You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2021/03/13 12:25:20 UTC
[GitHub] [apisix] benx203 opened a new pull request #3820: add nacos support
benx203 opened a new pull request #3820:
URL: https://github.com/apache/apisix/pull/3820
add nacos support
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] Firstsawyou commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
Firstsawyou commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603925211
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,323 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
Review comment:
I think this style is better:
```suggestion
local host = local_conf.discovery and local_conf.discovery.nacos
and local_conf.discovery.nacos.host
```
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,323 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
Review comment:
Bad style, this would be better:
```suggestion
log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
", read_timeout:", read_timeout, ".")
```
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,323 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
Review comment:
It is better to keep a blank line between if conditional statements.
```suggestion
if local_conf.discovery.nacos.prefix then
url = url .. local_conf.discovery.nacos.prefix
end
if str_byte(url, #url) ~= str_byte("/") then
url = url .. "/"
end
```
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602649771
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
How to check nacos in discovery plugin whether authed?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615710553
##########
File path: apisix/discovery/nacos.lua
##########
@@ -182,47 +179,47 @@ local function get_base_uri()
end
-local function get_page_service(infos, base_uri, token_param, page_num)
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local path = str_format(service_list_path, page_num, 100) .. token_param
- local data, err = get_url(base_uri, path)
- if err then
- return data, err, path
- end
-
- for _, service_name in ipairs(data.doms) do
- core.table.insert(infos, service_name)
- end
- return data, err, path
-end
-
-
-local function iter_and_add_service_info(infos, base_uri, token_param)
- local data, err, path = get_page_service(infos, base_uri, token_param, 1)
- if err then
- log.error("get_url:", path, " err:", err)
+local function iter_and_add_service(services, values)
+ if not values then
return
end
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local maxPage = math.ceil(data.count / 100)
- if maxPage == 0 then
- return
- end
+ for _, value in core.config_util.iterate_values(values) do
+ local conf = value.value
+ if not conf then
+ goto CONTINUE
+ end
- -- more than 1 page,continue fetch other pages
- if maxPage > 1 then
- for i = 2, maxPage do
- get_page_service(infos, base_uri, token_param, i)
+ local up
+ if conf.upstream then
+ up = conf.upstream
+ else
+ up = conf
end
+
+ if up.discovery_type == "nacos" then
+ core.table.insert(services, up.service_name)
+ end
+::CONTINUE::
end
end
-local function get_services(base_uri, token_param)
- local infos = core.table.new(0, 0)
- iter_and_add_service_info(infos, base_uri, token_param)
- return infos
+local function get_nacos_services()
+ local services = {}
+
+ -- here we use lazy load to work around circle dependency
+ local get_upstreams = require("apisix.upstream").upstreams
+ local get_routes = require("apisix.router").http_routes
+ local get_services = require("apisix.http.service").services
+
+ local values = get_upstreams()
+ iter_and_add_service(services, values)
+ values = get_routes()
+ iter_and_add_service(services, values)
Review comment:
I see,thanks.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] moonming commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
moonming commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-819617847
@benx203 thanks for your contribution.
You can create a new PR to fix the code style issue.
And it will be better if you can add `support Nacos` in the README.md to let more people know about this feature.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r599433211
##########
File path: docs/en/latest/discovery/nacos.md
##########
@@ -0,0 +1,95 @@
+---
+title: nacos
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+### Configuration for Nacos
+
+Add following configuration in `conf/config.yaml` :
+
+```yaml
+discovery:
+ nacos:
+ host:
+ - "http://${username}:${password}@${host1}:${port1}"
+ prefix: "/nacos/v1/"
+ auth_path: "auth/login"
+ service_list_path: "ns/service/list?pageNo=1&pageSize=20"
+ instance_list_path: "ns/instance/list?serviceName="
+ fetch_interval: 30 # default 30 sec
+ weight: 100 # default 100
+ timeout:
+ connect: 2000 # default 2000
Review comment:
Better to mention the unit is ms.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
+ instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},
Review comment:
Need a test to check the user-defined paths.
BTW, in what situation people need to redefine the paths?
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ my $http_config = $block->http_config // <<_EOC_;
+
+ server {
+ listen 18001;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 1")
+ }
+ }
+ }
+ server {
+ listen 18002;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 2")
+ }
+ }
+ }
+_EOC_
+
+ $block->set_value("http_config", $http_config);
+});
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: prepare nacos register nodes
+--- config
+location /nacos {
+ proxy_pass http://127.0.0.1:8848;
+}
+
+--- pipelined_requests eval
+[
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",
Review comment:
Why POST and then DELETE?
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
+ instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function str_split (inputstr, sep)
Review comment:
Should use existent API:
https://github.com/apache/apisix/blob/e9a59ac5e8618737f69eddbaf05097b7ffab46ff/apisix/plugins/proxy-cache.lua#L194
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
We need test the user/password feature.
##########
File path: docs/en/latest/discovery/nacos.md
##########
@@ -0,0 +1,95 @@
+---
+title: nacos
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+### Configuration for Nacos
+
+Add following configuration in `conf/config.yaml` :
+
+```yaml
+discovery:
+ nacos:
+ host:
+ - "http://${username}:${password}@${host1}:${port1}"
+ prefix: "/nacos/v1/"
+ auth_path: "auth/login"
+ service_list_path: "ns/service/list?pageNo=1&pageSize=20"
+ instance_list_path: "ns/instance/list?serviceName="
+ fetch_interval: 30 # default 30 sec
+ weight: 100 # default 100
+ timeout:
+ connect: 2000 # default 2000
+ send: 2000 # default 2000
+ read: 5000 # default 5000
+```
+
+And you can config it in short by default value:
+
+```yaml
+discovery:
+ nacos:
+ host:
+ - "http://192.168.33.1:8848"
+```
+
+### Upstream setting
+
+Here is an example of routing a request with a URL of "/nacos/**" to a service which named "http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS" and use nacos discovery client in the registry :
+
+```shell
+$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
+{
+ "uri": "/nacos/**",
Review comment:
Use `/nacos/*` is enough?
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
+ instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function str_split (inputstr, sep)
+ if sep == nil then
+ sep = "%s"
+ end
+ local t = {}
+ for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
+ table.insert(t, str)
+ end
+ return t
+end
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = str_split(user_and_password,":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local base_uri, username, password = service_info()
+ if not base_uri then
+ return
+ end
+
+ local token_param = ""
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return
+ end
+ token_param = "&accessToken=" .. data.accessToken
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local data, err = get_url(base_uri, service_list_path .. token_param)
+ if err then
+ log.error("get_url:" .. service_list_path .. " err:" .. err)
+ return
+ end
+
+ if tostring(data.count) == "0" then
+ applications = up_apps
+ return
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
Review comment:
We can add `healthyOnly` to the argument to reduce the response
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
Review comment:
Only return the first 20 services is not a good idea.
We need to iterate the upstreams and build a service list from those that have `nacos` discovery_type.
Like this:
https://github.com/apache/apisix/blob/e9a59ac5e8618737f69eddbaf05097b7ffab46ff/apisix/control/v1.lua#L144-L149
You might need some lazy load trick to break the dependent cycle.
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ my $http_config = $block->http_config // <<_EOC_;
+
+ server {
+ listen 18001;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 1")
+ }
+ }
+ }
+ server {
+ listen 18002;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 2")
+ }
+ }
+ }
+_EOC_
+
+ $block->set_value("http_config", $http_config);
+});
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: prepare nacos register nodes
+--- config
+location /nacos {
+ proxy_pass http://127.0.0.1:8848;
+}
+
+--- pipelined_requests eval
+[
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "POST /nacos/v1/ns/instance?port=18002&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+]
+--- response_body eval
+["ok", "ok", "ok", "ok"]
+
+
+
+=== TEST 2: get APISIX-NACOS info from NACOS
+--- yaml_config eval: $::yaml_config
+--- apisix_yaml
+routes:
+ -
+ uri: /hello
+ upstream:
+ service_name: APISIX-NACOS
+ discovery_type: nacos
+ type: roundrobin
+
+#END
+--- request
+GET /hello
+--- error_code: 200
Review comment:
We need to show if server 1 or server 2 is hit.
And we need a test to show the default weight
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615699700
##########
File path: apisix/discovery/nacos.lua
##########
@@ -275,41 +273,33 @@ end
function _M.nodes(service_name)
- local logged = false
Review comment:
OK,i rollback the code.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609320898
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,152 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
Review comment:
After add this,it throws error when run test file in my local pc:
pattern "[error]" should not match any line in error.log but matches line "2021/04/08 05:39:35 [error] 25739#25739: *3 [lua] init.lua:462: http_access_phase(): failed to set upstream: no valid upstream node: nil, client: 127.0.0.1, server: localhost, request: \"GET /hello HTTP/1.1\", host: \"localhost\"" (req 0)
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r605524014
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
Review comment:
We can initialize `applications = {}` so that we can save many codes like:
```
if not applications then
applications = up_apps
end
```
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615685716
##########
File path: apisix/discovery/nacos.lua
##########
@@ -275,41 +273,33 @@ end
function _M.nodes(service_name)
- local logged = false
Review comment:
The lazy init is important as the sync is slow.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r600110250
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ my $http_config = $block->http_config // <<_EOC_;
+
+ server {
+ listen 18001;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 1")
+ }
+ }
+ }
+ server {
+ listen 18002;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 2")
+ }
+ }
+ }
+_EOC_
+
+ $block->set_value("http_config", $http_config);
+});
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: prepare nacos register nodes
+--- config
+location /nacos {
+ proxy_pass http://127.0.0.1:8848;
+}
+
+--- pipelined_requests eval
+[
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",
Review comment:
But it is not the feature of APISIX. We don't need to test nacos itself.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r606041056
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ while( not applications )
+ do
+ log.info('wait init')
Review comment:
Better to use a `WARN` level log and only log for the first sleep.
`info` level is invisible by default.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609596820
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
Review comment:
@benx203
Why we can't support 2.0.0 directly? Is `2.0.0` incompatible with `1.4.1`?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615639810
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,306 @@
+--
+-- 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 require = require
+local local_conf = require('apisix.core.config_local').local_conf()
+local http = require('resty.http')
+local core = require('apisix.core')
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require('ngx.re')
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications = {}
+local auth_path = 'auth/login'
+local instance_list_path = 'ns/instance/list?healthyOnly=true&serviceName='
+
+local host_pattern = [[^http(s)?:\/\/[a-zA-Z0-9-_.:\@]+$]]
+local prefix_pattern = [[^[\/a-zA-Z0-9-_.]+$]]
+local schema = {
+ type = 'object',
+ properties = {
+ host = {
+ type = 'array',
+ minItems = 1,
+ items = {
+ type = 'string',
+ pattern = host_pattern,
+ minLength = 2,
+ maxLength = 100,
+ },
+ },
+ fetch_interval = {type = 'integer', minimum = 1, default = 30},
+ prefix = {type = 'string', pattern = prefix_pattern, maxLength = 100, default = '/nacos/v1/'},
+ weight = {type = 'integer', minimum = 1, default = 100},
+ timeout = {
+ type = 'object',
+ properties = {
+ connect = {type = 'integer', minimum = 1, default = 2000},
+ send = {type = 'integer', minimum = 1, default = 2000},
+ read = {type = 'integer', minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {'host'}
+}
+
+
+local _M = {}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info('request url:', url)
+ local headers = {}
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info('connect_timeout:', connect_timeout, ', send_timeout:', send_timeout,
+ ', read_timeout:', read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, 'status = ' .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, 'GET', nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, 'POST', nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if not username or not password then
+ return ''
+ end
+
+ local args = { username = username, password = password}
+ local data, err = post_url(base_uri, auth_path .. '?' .. ngx.encode_args(args), nil)
+ if err then
+ log.error('nacos login fail:', username, ' ', password, ' desc:', err)
+ return nil, err
+ end
+ return '&accessToken=' .. data.accessToken
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, '@', 1, true)
Review comment:
The `core.string.find` is already the plain string find... 😅
Not all the suggestion from the reviewer is correct.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -275,41 +273,33 @@ end
function _M.nodes(service_name)
- local logged = false
Review comment:
The original code is good. We just need to set a 5s limitation.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 edited a comment on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 edited a comment on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-816555334
@spacewander
OK.Take your time.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609449874
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
+ # nacos auth server - for test auth
+ docker run --rm -d --name nacos_auth --network nacos_net --hostname nacos1 --env NACOS_AUTH_ENABLE=true --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
+ url="127.0.0.1:8858/nacos/v1/ns/service/list?pageNo=1&pageSize=2"
+ until [[ "$(curl -s -o /dev/null -w ''%{http_code}'' $url)" == "200" ]]; do
+ echo 'wait nacos server...'
+ sleep 1;
+ done
+ # register nacos service
+ rm -rf tmp
+ mkdir tmp
+ cd tmp
+ wget https://raw.githubusercontent.com/benx203/nacos-test-service/main/spring-nacos-1.0-SNAPSHOT.jar
Review comment:
OK.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r606045390
##########
File path: apisix/discovery/nacos.lua
##########
@@ -278,9 +278,13 @@ end
function _M.nodes(service_name)
- while( not applications )
+ local loged = false
Review comment:
Should be `logged`
##########
File path: apisix/discovery/nacos.lua
##########
@@ -278,9 +278,13 @@ end
function _M.nodes(service_name)
- while( not applications )
+ local loged = false
+ while(not applications)
Review comment:
Style: better to write `while not applications do`.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609413722
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
+ # nacos auth server - for test auth
+ docker run --rm -d --name nacos_auth --network nacos_net --hostname nacos1 --env NACOS_AUTH_ENABLE=true --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
+ url="127.0.0.1:8858/nacos/v1/ns/service/list?pageNo=1&pageSize=2"
+ until [[ "$(curl -s -o /dev/null -w ''%{http_code}'' $url)" == "200" ]]; do
+ echo 'wait nacos server...'
+ sleep 1;
+ done
+ # register nacos service
+ rm -rf tmp
+ mkdir tmp
+ cd tmp
+ wget https://raw.githubusercontent.com/benx203/nacos-test-service/main/spring-nacos-1.0-SNAPSHOT.jar
Review comment:
@benx203
Would you also submit the Java code to https://github.com/benx203/nacos-test-service? Thanks!
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603799397
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
Review comment:
OK.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615650797
##########
File path: apisix/discovery/nacos.lua
##########
@@ -182,47 +179,47 @@ local function get_base_uri()
end
-local function get_page_service(infos, base_uri, token_param, page_num)
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local path = str_format(service_list_path, page_num, 100) .. token_param
- local data, err = get_url(base_uri, path)
- if err then
- return data, err, path
- end
-
- for _, service_name in ipairs(data.doms) do
- core.table.insert(infos, service_name)
- end
- return data, err, path
-end
-
-
-local function iter_and_add_service_info(infos, base_uri, token_param)
- local data, err, path = get_page_service(infos, base_uri, token_param, 1)
- if err then
- log.error("get_url:", path, " err:", err)
+local function iter_and_add_service(services, values)
+ if not values then
return
end
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local maxPage = math.ceil(data.count / 100)
- if maxPage == 0 then
- return
- end
+ for _, value in core.config_util.iterate_values(values) do
+ local conf = value.value
+ if not conf then
+ goto CONTINUE
+ end
- -- more than 1 page,continue fetch other pages
- if maxPage > 1 then
- for i = 2, maxPage do
- get_page_service(infos, base_uri, token_param, i)
+ local up
+ if conf.upstream then
+ up = conf.upstream
+ else
+ up = conf
end
+
+ if up.discovery_type == "nacos" then
+ core.table.insert(services, up.service_name)
+ end
+::CONTINUE::
end
end
-local function get_services(base_uri, token_param)
- local infos = core.table.new(0, 0)
- iter_and_add_service_info(infos, base_uri, token_param)
- return infos
+local function get_nacos_services()
+ local services = {}
+
+ -- here we use lazy load to work around circle dependency
+ local get_upstreams = require("apisix.upstream").upstreams
+ local get_routes = require("apisix.router").http_routes
+ local get_services = require("apisix.http.service").services
+
+ local values = get_upstreams()
+ iter_and_add_service(services, values)
+ values = get_routes()
+ iter_and_add_service(services, values)
Review comment:
By the way,Are there 'discovery_type' config in service and route?
@spacewander
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597350777
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
+ end
+
+ if not res.body or res.status ~= 200 then
+ log.error("failed to fetch registry, status = ", res.status)
+ return
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ log.error("invalid response body: ", json_str, " err: ", err)
+ return
+ end
+ return data
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local base_uri, basic_auth = service_info()
+ if not base_uri then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local data = get_url(base_uri,basic_auth,service_list_path)
+ if tostring(data.count) == "0" then
+ applications = up_apps
+ return
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ data = get_url(base_uri,basic_auth,instance_list_path .. service_name)
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ if not applications then
+ log.error("failed to fetch nodes for : ", service_name)
+ return
+ end
+
+ return applications[service_name]
+end
+
+
+function _M.init_worker()
+ if not local_conf.discovery.nacos or
+ not local_conf.discovery.nacos.host or #local_conf.discovery.nacos.host == 0 then
+ error("do not set nacos.host")
+ return
+ end
+
+ local ok, err = core.schema.check(schema, local_conf.discovery.nacos)
+ if not ok then
+ error("invalid nacos configuration: " .. err)
+ return
+ end
+ default_weight = local_conf.discovery.nacos.weight or 100
+ log.info("default_weight:", default_weight, ".")
+ local fetch_interval = local_conf.discovery.nacos.fetch_interval or 30
+ log.info("fetch_interval:", fetch_interval, ".")
+ service_list_path = local_conf.discovery.nacos.service_list_path or
Review comment:
I will fix it.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r599625682
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ my $http_config = $block->http_config // <<_EOC_;
+
+ server {
+ listen 18001;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 1")
+ }
+ }
+ }
+ server {
+ listen 18002;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 2")
+ }
+ }
+ }
+_EOC_
+
+ $block->set_value("http_config", $http_config);
+});
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: prepare nacos register nodes
+--- config
+location /nacos {
+ proxy_pass http://127.0.0.1:8848;
+}
+
+--- pipelined_requests eval
+[
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",
Review comment:
Delete directly will return 400.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r605413510
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
Review comment:
We can remove the page_size now and hardcore a very big number. So I don't need to change too many things when I edit this PR.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
Review comment:
Better to turn on ssl_verify.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function refresh_token_param(username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return
+ end
+ token_param = "&accessToken=" .. data.accessToken
+ else
+ token_param = ""
+ end
+end
+
+
+local function service_info()
+ local host = local_conf.discovery and local_conf.discovery.nacos
+ and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ base_uri = url
+ refresh_token_param(username, password)
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / page_size)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ service_info()
+ if not base_uri then
+ applications = up_apps
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
+ applications = up_apps
Review comment:
IMHO, when something bad happened, we should keep the `application` unchanged. Stale configuration is better than no configuration.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function refresh_token_param(username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return
+ end
+ token_param = "&accessToken=" .. data.accessToken
+ else
+ token_param = ""
+ end
+end
+
+
+local function service_info()
+ local host = local_conf.discovery and local_conf.discovery.nacos
+ and local_conf.discovery.nacos.host
+ if not host then
Review comment:
There is no need to check the host repeatedly. We can check it in the schema.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function refresh_token_param(username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return
+ end
+ token_param = "&accessToken=" .. data.accessToken
+ else
+ token_param = ""
+ end
+end
+
+
+local function service_info()
Review comment:
The name of the function is not good.
We can split it into two functions, `get_base_uri` and `refresh_token_param`.
And there is no need to use the global variable `base_uri`, we pass it as an argument in many functions.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,326 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local base_uri
+local token_param
+local page_size
+local token_ttl = 18000
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function refresh_token_param(username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return
+ end
+ token_param = "&accessToken=" .. data.accessToken
+ else
+ token_param = ""
+ end
+end
+
+
+local function service_info()
+ local host = local_conf.discovery and local_conf.discovery.nacos
+ and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ base_uri = url
+ refresh_token_param(username, password)
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / page_size)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ service_info()
+ if not base_uri then
+ applications = up_apps
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
+ applications = up_apps
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ while( not applications )
+ do
+ log.info('wait init')
+ ngx.sleep(0.1)
+ end
+ return applications[service_name]
+end
+
+
+function _M.init_worker()
+ if not local_conf.discovery.nacos or
+ not local_conf.discovery.nacos.host or #local_conf.discovery.nacos.host == 0 then
+ error("do not set nacos.host")
+ return
+ end
+
+ local ok, err = core.schema.check(schema, local_conf.discovery.nacos)
+ if not ok then
+ error("invalid nacos configuration: " .. err)
+ return
+ end
+ default_weight = local_conf.discovery.nacos.weight
+ log.info("default_weight:", default_weight, ".")
+ local fetch_interval = local_conf.discovery.nacos.fetch_interval
+ log.info("fetch_interval:", fetch_interval, ".")
+ page_size = local_conf.discovery.nacos.page_size
+ ngx_timer_at(0, fetch_full_registry)
+ ngx_timer_every(token_ttl, service_info)
Review comment:
Maybe we can remove this as we will reset the token each fetch_interval, which is smaller than token_ttl
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-816555334
> @benx203
> I will work on this PR and fulfill my promise in a few days. Please be patient.
OK.Take your time.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602672250
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
You can export the auth function: https://github.com/apache/apisix/pull/3820/files#diff-46fd008790f9ea29612a92ca5c94212ae43c81ab6b902ef3014d3d6b4bdfc5b3R202
and call it in the test file.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609321509
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,152 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8858"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+our $yaml_auth_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://nacos:nacos\@127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: get APISIX-NACOS info from NACOS - no auth
+--- yaml_config eval: $::yaml_config
+--- apisix_yaml
+routes:
+ -
+ uri: /hello
+ upstream:
+ service_name: APISIX-NACOS
+ discovery_type: nacos
+ type: roundrobin
+
+#END
+--- pipelined_requests eval
Review comment:
Should be useful,thanks!
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] membphis commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
membphis commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r607529325
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,319 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
Review comment:
bad code style
this is the right style: `log.error("get_url:", path, " err:", err)`
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,319 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
Review comment:
magic number, need some comments
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,319 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
Review comment:
ditto
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,319 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
Review comment:
we need to writhe this error message to error log
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,319 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
Review comment:
bad code style
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r604157217
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
Could you give me some demo code?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597369333
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
Thanks,Submit it with TortoiseGit success.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603719667
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
Review comment:
You need to escape it as `\@` in the template string. The `@` has a special meaning in Perl.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r606029536
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
Review comment:
If use applications = {},run test could fail cause maybe call _M.nodes method before finish init.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on pull request #3820: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-798416438
And you need to add docs under https://github.com/apache/apisix/tree/master/docs/en/latest/discovery
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609411973
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,322 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:", path, " err:", err)
+ return
+ end
+
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ -- more than 1 page,continue fetch other pages
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ log.error("get_token_param error:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:", instance_list_path, " err:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
Review comment:
I set up the environment and debug it myself.
Here is the `host`: {\"enabled\":true,\"instanceHeartBeatTimeOut\":15000,\"ipDeleteTimeout\":30000,\"instanceHeartBeatInterval\":5000,\"metadata\":{\"preserved.register.source\":\"SPRING_CLOUD\"},\"port\":18001,\"serviceName\":\"DEFAULT_GROUP@@APISIX-NACOS\",\"instanceId\":\"192.168.65.3#18001#DEFAULT#DEFAULT_GROUP@@APISIX-NACOS\",\"healthy\":true,\"ip\":\"192.168.65.3\",\"ephemeral\":true,\"clusterName\":\"DEFAULT\",\"weight\":1}
There is not `valid` field. The response doesn't match their API doc: https://nacos.io/en-us/docs/open-api.html
I am not sure if it is because the latest Nacos has changed the API. Maybe we need to use the tagged nacos image `2.0.0` instead of the latest one?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r596662744
##########
File path: docs/en/latest/discovery/nacos.md
##########
@@ -0,0 +1,93 @@
+---
+title: nacos
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+### Configuration for Nacos
+
+Add following configuration in `conf/config.yaml` :
+
+```yaml
+discovery:
+ nacos:
+ host:
+ - "http://192.168.33.1:8848"
Review comment:
Because Nacos not need login yet.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609413111
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
Review comment:
Would it be better to use `nacos/nacos-server:2.0.0`?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597350658
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
Review comment:
OK.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609451778
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
Review comment:
The nacos version should be 1.4.1,2.0.0 just released few days ago.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603319995
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
Review comment:
If use @,when run test file,will throw error:
Possible unintended interpolation of @127 in string at t/discovery/nacos.t line 70
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603173738
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
You can take a look at https://github.com/apache/apisix/blob/49e4fd307c65dc125e62987b3634a9e7358179bf/apisix/control/v1.lua#L115-L122
for how we iterate the upstream configurations and collect the health check info.
It is similar to collect the service_name.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609287508
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,152 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8858"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+our $yaml_auth_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://nacos:nacos\@127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: get APISIX-NACOS info from NACOS - no auth
+--- yaml_config eval: $::yaml_config
+--- apisix_yaml
+routes:
+ -
+ uri: /hello
+ upstream:
+ service_name: APISIX-NACOS
+ discovery_type: nacos
+ type: roundrobin
+
+#END
+--- pipelined_requests eval
Review comment:
Maybe we can use sleep before sending HTTP requests?
Like this: https://github.com/apache/apisix/blob/252af4143d527b5a644c0a4959b96504099237e2/t/discovery/consul_kv.t#L307
Don't forget to set a long "--- timeout".
It look like syncing configuration from Nacos is time-consuming job.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603156071
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
Review comment:
fixed.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r599625682
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ my $http_config = $block->http_config // <<_EOC_;
+
+ server {
+ listen 18001;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 1")
+ }
+ }
+ }
+ server {
+ listen 18002;
+
+ location /hello {
+ content_by_lua_block {
+ ngx.say("server 2")
+ }
+ }
+ }
+_EOC_
+
+ $block->set_value("http_config", $http_config);
+});
+
+our $yaml_config = <<_EOC_;
+apisix:
+ node_listen: 1984
+ config_center: yaml
+ enable_admin: false
+discovery:
+ nacos:
+ host:
+ - "http://127.0.0.1:8848"
+ prefix: "/nacos/v1/"
+ fetch_interval: 30
+ weight: 100
+ timeout:
+ connect: 2000
+ send: 2000
+ read: 5000
+
+_EOC_
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: prepare nacos register nodes
+--- config
+location /nacos {
+ proxy_pass http://127.0.0.1:8848;
+}
+
+--- pipelined_requests eval
+[
+ "POST /nacos/v1/ns/instance?port=18001&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=APISIX-NACOS&encoding=GBK&enabled=true",
+ "DELETE /nacos/v1/ns/service?serviceName=APISIX-NACOS",
Review comment:
If has no data,delete return code is 400,if has data,delete return code is 200.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609308381
##########
File path: t/discovery/nacos.t
##########
@@ -0,0 +1,152 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+log_level('info');
+no_root_location();
+no_shuffle();
+
Review comment:
We can add this block to check the error log:
```
add_block_preprocessor(sub {
my ($block) = @_;
if (!$block->no_error_log) {
$block->set_value("no_error_log", "[error]\n[alert]");
}
});
```
It would be helpful for debugging the 503.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r604533670
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
Don't worry, I can update it for you once you have solved the other issues.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609647031
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,322 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:", path, " err:", err)
+ return
+ end
+
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ -- more than 1 page,continue fetch other pages
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ log.error("get_token_param error:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:", instance_list_path, " err:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
Review comment:
If query all records,need to filter.
But now should not need any more.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r600111763
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
+ instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},
Review comment:
@benx203
I think we can remove it now and add it if needed.
We need to add a doc and test for this feature if you insist to keep it.
(I don't recommend to do that as this PR is big enough)
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r606044345
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ while( not applications )
+ do
+ log.info('wait init')
Review comment:
OK.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597362835
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
> refusing to allow an OAuth App
Try to update it locally via a regular editor and submit it with Git?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602668288
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
But if nacos start with auth mode,in nacos.t add services to nacos need send auth token.
How can i save auth token in nacos.t?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602663539
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
If the auth enable nacos can be used, the auth is successful.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r596664303
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
Review comment:
OK,I copy from eureka.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r610686799
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
Review comment:
I think better way is support both 2.0.0 and 1.4.1.
Maybe support 2.0.0 later?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603879135
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
I have mentioned it before: https://github.com/apache/apisix/pull/3820#discussion_r599481973
> You might need some lazy load trick to break the dependent cycle.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609596820
##########
File path: .github/workflows/centos7-ci.yml
##########
@@ -101,6 +101,37 @@ jobs:
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+ # start nacos server
+ nohup docker network rm nacos_net > /dev/null 2>&1 &
+ nohup docker network create nacos_net > /dev/null 2>&1 &
+ # nacos no auth server - for test no auth
+ docker run --rm -d --name nacos_no_auth --network nacos_net --hostname nacos2 --env NACOS_SERVERS="nacos1:8848 nacos2:8848" --env PREFER_HOST_MODE=hostname --env MODE=cluster --env EMBEDDED_STORAGE=embedded --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8858:8848 nacos/nacos-server:latest
Review comment:
@benx203
Why can't we support 2.0.0 directly? Is `2.0.0` incompatible with `1.4.1`?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r596598466
##########
File path: docs/en/latest/discovery/nacos.md
##########
@@ -0,0 +1,93 @@
+---
+title: nacos
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+### Configuration for Nacos
+
+Add following configuration in `conf/config.yaml` :
+
+```yaml
+discovery:
+ nacos:
+ host:
+ - "http://192.168.33.1:8848"
Review comment:
Why don't mention the user / password feature?
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
+ end
+
+ if not res.body or res.status ~= 200 then
+ log.error("failed to fetch registry, status = ", res.status)
+ return
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ log.error("invalid response body: ", json_str, " err: ", err)
+ return
+ end
+ return data
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local base_uri, basic_auth = service_info()
+ if not base_uri then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local data = get_url(base_uri,basic_auth,service_list_path)
+ if tostring(data.count) == "0" then
+ applications = up_apps
+ return
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ data = get_url(base_uri,basic_auth,instance_list_path .. service_name)
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ if not applications then
+ log.error("failed to fetch nodes for : ", service_name)
+ return
+ end
+
+ return applications[service_name]
+end
+
+
+function _M.init_worker()
+ if not local_conf.discovery.nacos or
+ not local_conf.discovery.nacos.host or #local_conf.discovery.nacos.host == 0 then
+ error("do not set nacos.host")
+ return
+ end
+
+ local ok, err = core.schema.check(schema, local_conf.discovery.nacos)
+ if not ok then
+ error("invalid nacos configuration: " .. err)
+ return
+ end
+ default_weight = local_conf.discovery.nacos.weight or 100
+ log.info("default_weight:", default_weight, ".")
+ local fetch_interval = local_conf.discovery.nacos.fetch_interval or 30
+ log.info("fetch_interval:", fetch_interval, ".")
+ service_list_path = local_conf.discovery.nacos.service_list_path or
Review comment:
Where should I configure `service_list_path`? There is neither schema nor doc for it.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
+ end
+
+ if not res.body or res.status ~= 200 then
+ log.error("failed to fetch registry, status = ", res.status)
+ return
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ log.error("invalid response body: ", json_str, " err: ", err)
+ return
+ end
+ return data
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local base_uri, basic_auth = service_info()
+ if not base_uri then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local data = get_url(base_uri,basic_auth,service_list_path)
+ if tostring(data.count) == "0" then
+ applications = up_apps
+ return
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ data = get_url(base_uri,basic_auth,instance_list_path .. service_name)
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ if not applications then
+ log.error("failed to fetch nodes for : ", service_name)
+ return
+ end
+
+ return applications[service_name]
+end
+
+
+function _M.init_worker()
+ if not local_conf.discovery.nacos or
+ not local_conf.discovery.nacos.host or #local_conf.discovery.nacos.host == 0 then
+ error("do not set nacos.host")
+ return
+ end
+
+ local ok, err = core.schema.check(schema, local_conf.discovery.nacos)
+ if not ok then
+ error("invalid nacos configuration: " .. err)
+ return
+ end
+ default_weight = local_conf.discovery.nacos.weight or 100
+ log.info("default_weight:", default_weight, ".")
+ local fetch_interval = local_conf.discovery.nacos.fetch_interval or 30
+ log.info("fetch_interval:", fetch_interval, ".")
+ service_list_path = local_conf.discovery.nacos.service_list_path or
+ 'ns/service/list?pageNo=1&pageSize=20'
+ instance_list_path = local_conf.discovery.nacos.instance_list_path or
Review comment:
ditto
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
Review comment:
Missing default for weight?
And the minimum weight should be 1.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
Review comment:
The default value will be injected via schema check. We don't need to assign it.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
Review comment:
Why choose 5?
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
Review comment:
Better to use `str_byte(uri, #uri) == str_byte("/")`
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
Please pass the error out so the caller can check it.
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
Review comment:
We don't need it for HTTP 1.1
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
+ end
+
+ if not res.body or res.status ~= 200 then
+ log.error("failed to fetch registry, status = ", res.status)
+ return
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ log.error("invalid response body: ", json_str, " err: ", err)
+ return
+ end
+ return data
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local base_uri, basic_auth = service_info()
+ if not base_uri then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local data = get_url(base_uri,basic_auth,service_list_path)
Review comment:
Need space after the comma.
And please check the returned value of `get_url`.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615648329
##########
File path: apisix/discovery/nacos.lua
##########
@@ -275,41 +273,33 @@ end
function _M.nodes(service_name)
- local logged = false
Review comment:
Just keep simple.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r606044345
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:" .. username .. " " .. password .. " desc:" .. err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:" .. path .. " err:" .. err)
+ return
+ end
+
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:" .. instance_list_path .. " err:" .. err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ while( not applications )
+ do
+ log.info('wait init')
Review comment:
OK.
BTW,when i run test file in local CentOS7,most time success,sometime will throw error:
[error] 23302#23302: *10 [lua] init.lua:462: http_access_phase(): failed to set upstream: no valid upstream node: nil, client: 127.0.0.1, server: localhost, request: "GET /hello HTTP/1.1", host: "localhost"
Is it a bug?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597352555
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
content:
```
rm -rf nacos-docker
git clone --depth 1 https://github.com/benx203/nacos-docker.git
cd nacos-docker
docker-compose -f example/standalone-test.yaml up
ps aux|grep nacos-gateway-provider-example-2.2.6-SNAPSHOT |grep -v grep|awk '{print $2}'|xargs kill -9
nohup java -jar example/nacos-gateway-provider-example-2.2.6-SNAPSHOT.jar --spring.application.name=APISIX-NACOS > /dev/null 2>&1 &
```
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
content:
```
rm -rf nacos-docker
git clone --depth 1 https://github.com/benx203/nacos-docker.git
cd nacos-docker
docker-compose -f example/standalone-test.yaml up
ps aux|grep nacos-gateway-provider-example-2.2.6-SNAPSHOT |grep -v grep|awk '{print $2}'|xargs kill -9
nohup java -jar example/nacos-gateway-provider-example-2.2.6-SNAPSHOT.jar --spring.application.name=APISIX-NACOS > /dev/null 2>&1 &
```
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
content:
```
rm -rf nacos-docker
git clone --depth 1 https://github.com/benx203/nacos-docker.git
cd nacos-docker
docker-compose -f example/standalone-test.yaml up
ps aux|grep nacos-gateway-provider-example-2.2.6-SNAPSHOT |grep -v grep|awk '{print $2}'|xargs kill -9
nohup java -jar example/nacos-gateway-provider-example-2.2.6-SNAPSHOT.jar --spring.application.name=APISIX-NACOS > /dev/null 2>&1 &
```
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603167933
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
Review comment:
Is there any need to change `@` to `#`? Maybe I miss something?
It is the standard to use `@` to separate the authority part from the rest:
https://en.wikipedia.org/wiki/URL#Syntax
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
Emm... I mean to iterate the upstream configurations and collect the service list from those that have `discovery_type` set to `nacos`. There is no need to ask nacos for the service list, we already know it via the upstream configuration.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-820352257
> @benx203 thanks for your contribution.
> You can create a new PR to fix the code style issue.
> And it will be better if you can add `support Nacos` in the README.md to let more people know about this feature.
OK,i will try,thank you all.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander merged pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander merged pull request #3820:
URL: https://github.com/apache/apisix/pull/3820
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-800841987
Please make sure it can pass the lint.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-816503248
@benx203
I will work on this PR and fulfill my promise in a few days. Please be patient.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602111154
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
If add NACOS_AUTH_ENABLE=true, file nacos.t need login too.
Could you give me a t file login demo?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r602173854
##########
File path: .travis/linux_tengine_runner.sh
##########
@@ -40,6 +40,9 @@ before_install() {
# start consul servers
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
+
+ # start nacos server
+ docker run --rm --name nacos_1 -d --env PREFER_HOST_MODE=hostname --env MODE=standalone --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m -p8848:8848 nacos/nacos-server:latest
Review comment:
You can use different conf in different tests, one for auth success and another for auth fail.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] membphis commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
membphis commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r613275203
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
Review comment:
add a pattern to limit the string to the host format
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
Review comment:
we'd better use the plain text model, better performance.
https://stackoverflow.com/questions/18973019/is-there-a-lua-string-find-without-pattern
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function iter_and_add_service(services, values)
+ if not values then
+ return
+ end
+
+ for _, value in core.config_util.iterate_values(values) do
+ local conf = value.value
+ if not conf then
+ goto CONTINUE
+ end
+
+ local up
+ if conf.upstream then
+ up = conf.upstream
+ else
+ up = conf
+ end
+
+ if up.discovery_type == "nacos" then
+ core.table.insert(services, up.service_name)
+ end
+::CONTINUE::
+ end
+end
+
+
+local function get_nacos_services()
+ local services = {}
+
+ -- here we use lazy load to work around circle dependency
+ local get_upstreams = require("apisix.upstream").upstreams
+ local get_routes = require("apisix.router").http_routes
+ local get_services = require("apisix.http.service").services
+
+ local values = get_upstreams()
+ iter_and_add_service(services, values)
+ values = get_routes()
+ iter_and_add_service(services, values)
+ values = get_services()
+ iter_and_add_service(services, values)
+ return services
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ log.error("get_token_param error:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_nacos_services()
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:", instance_list_path, " err:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ local nodes = up_apps[service_name]
+ if not nodes then
+ nodes = core.table.new(0, 0)
+ up_apps[service_name] = nodes
+ end
+ core.table.insert(nodes, {
+ host = host.ip,
+ port = host.port,
+ weight = host.weight or default_weight,
+ })
+ end
+ end
+ applications = up_apps
+end
+
+
+function _M.nodes(service_name)
+ local logged = false
+ while not applications do
Review comment:
I think we need to set a maximum waiting time , eg: 5 seconds
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
Review comment:
I think we should call [ngx.encode_args](https://github.com/openresty/lua-nginx-module#ngxencode_args) for `username` and `password`
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
Review comment:
this version is useless, we can drop it
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
Review comment:
ditto
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
Review comment:
better style:
```lua
if not username or not password then
return ""
end
...
```
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function iter_and_add_service(services, values)
+ if not values then
Review comment:
bad indentation
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
Review comment:
for the string object, I think we use `"`, it is easier for reading.
`headers["Accept"] = "application/json"`
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,316 @@
+--
+-- 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 require = require
+local local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
Review comment:
and please fix the similar points
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603719667
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
Review comment:
You need to escape it as `\@` in the template string.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#issuecomment-809838710
Please merge master to resolve conflicts.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r603841571
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,324 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local page_size
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ page_size = {type = "integer", minimum = 1, default = 100},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local username, password
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "#")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = false,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ local path = str_format(service_list_path, page_num, page_size) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
Review comment:
If import these in nacos.lua:
local upstream_mod = require("apisix.upstream")
local get_upstreams = upstream_mod.upstreams
When run test file,will throw error:
attempt to index local 'upstream_mod' (a number value)
It's not right import?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r597351976
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,237 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string_sub = string.sub
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string"},
+ weight = {type = "integer", minimum = 0},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function service_info()
+ local host = local_conf.discovery and
+ local_conf.discovery.nacos and local_conf.discovery.nacos.host
+ if not host then
+ log.error("do not set nacos.host")
+ return
+ end
+
+ local basic_auth
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ basic_auth = "Basic " .. ngx.encode_base64(user_and_password)
+ end
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+ if string_sub(url, #url) ~= "/" then
+ url = url .. "/"
+ end
+
+ return url, basic_auth
+end
+
+
+local function request(request_uri, basic_auth, method, path, query, body)
+ log.info("nacos uri:", request_uri, ".")
+ local url = request_uri .. path
+ local headers = core.table.new(0, 5)
+ headers['Connection'] = 'Keep-Alive'
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ -- log.warn(method, url, body)
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout and timeout.connect or 2000
+ local send_timeout = timeout and timeout.send or 2000
+ local read_timeout = timeout and timeout.read or 5000
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout, ".")
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ return httpc:request_uri(url, {
+ version = 1.1,
+ method = method,
+ headers = headers,
+ query = query,
+ body = body,
+ ssl_verify = false,
+ })
+end
+
+
+local function get_url(request_url,basic_auth,path)
+ local res, err = request(request_url, basic_auth, "GET", path)
+ if not res then
+ log.error("failed to fetch registry", err)
+ return
Review comment:
OK.
By the way,when i add nacos test script in centos7-ci.yml,can't submit,how can i fix it?
error tips:
[remote rejected] (refusing to allow an OAuth App to create or update workflow `.github/workflows/centos7-ci.yml` without `workflow` scope)
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r615681419
##########
File path: apisix/discovery/nacos.lua
##########
@@ -182,47 +179,47 @@ local function get_base_uri()
end
-local function get_page_service(infos, base_uri, token_param, page_num)
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local path = str_format(service_list_path, page_num, 100) .. token_param
- local data, err = get_url(base_uri, path)
- if err then
- return data, err, path
- end
-
- for _, service_name in ipairs(data.doms) do
- core.table.insert(infos, service_name)
- end
- return data, err, path
-end
-
-
-local function iter_and_add_service_info(infos, base_uri, token_param)
- local data, err, path = get_page_service(infos, base_uri, token_param, 1)
- if err then
- log.error("get_url:", path, " err:", err)
+local function iter_and_add_service(services, values)
+ if not values then
return
end
- -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
- local maxPage = math.ceil(data.count / 100)
- if maxPage == 0 then
- return
- end
+ for _, value in core.config_util.iterate_values(values) do
+ local conf = value.value
+ if not conf then
+ goto CONTINUE
+ end
- -- more than 1 page,continue fetch other pages
- if maxPage > 1 then
- for i = 2, maxPage do
- get_page_service(infos, base_uri, token_param, i)
+ local up
+ if conf.upstream then
+ up = conf.upstream
+ else
+ up = conf
end
+
+ if up.discovery_type == "nacos" then
+ core.table.insert(services, up.service_name)
+ end
+::CONTINUE::
end
end
-local function get_services(base_uri, token_param)
- local infos = core.table.new(0, 0)
- iter_and_add_service_info(infos, base_uri, token_param)
- return infos
+local function get_nacos_services()
+ local services = {}
+
+ -- here we use lazy load to work around circle dependency
+ local get_upstreams = require("apisix.upstream").upstreams
+ local get_routes = require("apisix.router").http_routes
+ local get_services = require("apisix.http.service").services
+
+ local values = get_upstreams()
+ iter_and_add_service(services, values)
+ values = get_routes()
+ iter_and_add_service(services, values)
Review comment:
Those can have embedded upstream field.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] spacewander commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
spacewander commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r609595479
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,322 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math = math
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_re = require("ngx.re")
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local str_format = string.format
+local log = core.log
+
+local default_weight
+local applications
+local auth_path = "auth/login"
+local service_list_path = "ns/service/list?pageNo=%s&pageSize=%s"
+local instance_list_path = "ns/instance/list?healthyOnly=true&serviceName="
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ weight = {type = "integer", minimum = 1, default = 100},
+ timeout = {
+ type = "object",
+ properties = {
+ connect = {type = "integer", minimum = 1, default = 2000},
+ send = {type = "integer", minimum = 1, default = 2000},
+ read = {type = "integer", minimum = 1, default = 5000},
+ },
+ default = {
+ connect = 2000,
+ send = 2000,
+ read = 5000,
+ }
+ },
+ },
+ required = {"host"}
+}
+
+
+local _M = {
+ version = 0.1,
+}
+
+
+local function request(request_uri, path, body, method, basic_auth)
+ local url = request_uri .. path
+ log.info("request url:", url)
+ local headers = core.table.new(0, 0)
+ headers['Accept'] = 'application/json'
+
+ if basic_auth then
+ headers['Authorization'] = basic_auth
+ end
+
+ if body and 'table' == type(body) then
+ local err
+ body, err = core.json.encode(body)
+ if not body then
+ return nil, 'invalid body : ' .. err
+ end
+ headers['Content-Type'] = 'application/json'
+ end
+
+ local httpc = http.new()
+ local timeout = local_conf.discovery.nacos.timeout
+ local connect_timeout = timeout.connect
+ local send_timeout = timeout.send
+ local read_timeout = timeout.read
+ log.info("connect_timeout:", connect_timeout, ", send_timeout:", send_timeout,
+ ", read_timeout:", read_timeout)
+ httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)
+ local res, err = httpc:request_uri(url, {
+ method = method,
+ headers = headers,
+ body = body,
+ ssl_verify = true,
+ })
+ if not res then
+ return nil, err
+ end
+
+ if not res.body or res.status ~= 200 then
+ return nil, "status = " .. res.status
+ end
+
+ local json_str = res.body
+ local data, err = core.json.decode(json_str)
+ if not data then
+ return nil, err
+ end
+ return data
+end
+
+
+local function get_url(request_uri, path)
+ return request(request_uri, path, nil, "GET", nil)
+end
+
+
+local function post_url(request_uri, path, body)
+ return request(request_uri, path, body, "POST", nil)
+end
+
+
+local function get_token_param(base_uri, username, password)
+ if username and password then
+ local data, err = post_url(base_uri, auth_path .. "?username=" .. username
+ .. "&password=" .. password, nil)
+ if err then
+ log.error("nacos login fail:", username, " ", password, " desc:", err)
+ return nil, err
+ end
+ return "&accessToken=" .. data.accessToken
+ end
+ return ""
+end
+
+
+local function get_base_uri()
+ local host = local_conf.discovery.nacos.host
+ -- TODO Add health check to get healthy nodes.
+ local url = host[math_random(#host)]
+ local auth_idx = str_find(url, "@")
+ local username, password
+ if auth_idx then
+ local protocol_idx = str_find(url, "://")
+ local protocol = string_sub(url, 1, protocol_idx + 2)
+ local user_and_password = string_sub(url, protocol_idx + 3, auth_idx - 1)
+ local arr = ngx_re.split(user_and_password, ":")
+ if #arr == 2 then
+ username = arr[1]
+ password = arr[2]
+ end
+ local other = string_sub(url, auth_idx + 1)
+ url = protocol .. other
+ end
+
+ if local_conf.discovery.nacos.prefix then
+ url = url .. local_conf.discovery.nacos.prefix
+ end
+
+ if str_byte(url, #url) ~= str_byte("/") then
+ url = url .. "/"
+ end
+
+ return url, username, password
+end
+
+
+local function get_page_service(infos, base_uri, token_param, page_num)
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local path = str_format(service_list_path, page_num, 100) .. token_param
+ local data, err = get_url(base_uri, path)
+ if err then
+ return data, err, path
+ end
+
+ for _, service_name in ipairs(data.doms) do
+ core.table.insert(infos, service_name)
+ end
+ return data, err, path
+end
+
+
+local function iter_and_add_service_info(infos, base_uri, token_param)
+ local data, err, path = get_page_service(infos, base_uri, token_param, 1)
+ if err then
+ log.error("get_url:", path, " err:", err)
+ return
+ end
+
+ -- TODO Hardcode:page size=100,will rewrite by spacewander after merge
+ local maxPage = math.ceil(data.count / 100)
+ if maxPage == 0 then
+ return
+ end
+
+ -- more than 1 page,continue fetch other pages
+ if maxPage > 1 then
+ for i = 2, maxPage do
+ get_page_service(infos, base_uri, token_param, i)
+ end
+ end
+end
+
+
+local function get_services(base_uri, token_param)
+ local infos = core.table.new(0, 0)
+ iter_and_add_service_info(infos, base_uri, token_param)
+ return infos
+end
+
+
+local function fetch_full_registry(premature)
+ if premature then
+ return
+ end
+
+ local up_apps = core.table.new(0, 0)
+ local base_uri, username, password = get_base_uri()
+ local token_param, err = get_token_param(base_uri, username, password)
+ if err then
+ log.error("get_token_param error:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ local infos = get_services(base_uri, token_param)
+ if #infos == 0 then
+ applications = up_apps
+ return
+ end
+
+ local data, err
+ for _, service_name in ipairs(infos) do
+ data, err = get_url(base_uri, instance_list_path .. service_name .. token_param)
+ if err then
+ log.error("get_url:", instance_list_path, " err:", err)
+ if not applications then
+ applications = up_apps
+ end
+ return
+ end
+
+ for _, host in ipairs(data.hosts) do
+ if tostring(host.valid) == 'true' and
+ tostring(host.healthy) == 'true' and
+ tostring(host.enabled) == 'true' then
Review comment:
One more question: why we need to filter the result according to those fields?
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] benx203 commented on a change in pull request #3820: feat: add nacos support
Posted by GitBox <gi...@apache.org>.
benx203 commented on a change in pull request #3820:
URL: https://github.com/apache/apisix/pull/3820#discussion_r599636476
##########
File path: apisix/discovery/nacos.lua
##########
@@ -0,0 +1,285 @@
+--
+-- 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 local_conf = require("apisix.core.config_local").local_conf()
+local http = require("resty.http")
+local core = require("apisix.core")
+local ipairs = ipairs
+local tostring = tostring
+local type = type
+local math_random = math.random
+local error = error
+local ngx = ngx
+local ngx_timer_at = ngx.timer.at
+local ngx_timer_every = ngx.timer.every
+local string = string
+local table = table
+local string_sub = string.sub
+local str_byte = string.byte
+local str_find = core.string.find
+local log = core.log
+
+local default_weight
+local applications
+local auth_path
+local service_list_path
+local instance_list_path
+
+local schema = {
+ type = "object",
+ properties = {
+ host = {
+ type = "array",
+ minItems = 1,
+ items = {
+ type = "string",
+ },
+ },
+ fetch_interval = {type = "integer", minimum = 1, default = 30},
+ prefix = {type = "string", default = "/nacos/v1/"},
+ auth_path = {type = "string", default = "auth/login"},
+ service_list_path = {type = "string", default = "ns/service/list?pageNo=1&pageSize=20"},
+ instance_list_path = {type = "string", default = "ns/instance/list?serviceName="},
Review comment:
When Nacos api change.
--
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.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org