From 2a1fa6f7ef6b3a111fdf7dee23237cd5df481daa Mon Sep 17 00:00:00 2001 From: Demogorgon314 Date: Wed, 26 May 2021 19:08:35 +0800 Subject: [PATCH 1/3] feat: nacos discovery support namespace --- apisix/discovery/nacos.lua | 25 +++-- apisix/schema_def.lua | 4 + ci/install-ext-services-via-docker.sh | 22 ++++- docs/en/latest/discovery/nacos.md | 43 +++++++++ t/discovery/nacos.t | 131 ++++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 8 deletions(-) diff --git a/apisix/discovery/nacos.lua b/apisix/discovery/nacos.lua index cbb0bb6c3024..88f68ca5e076 100644 --- a/apisix/discovery/nacos.lua +++ b/apisix/discovery/nacos.lua @@ -157,6 +157,14 @@ local function get_token_param(base_uri, username, password) return '&accessToken=' .. data.accessToken end +local function get_namespace_param(namespace_id) + local param = '' + if namespace_id then + local args = {namespaceId = namespace_id} + param = '&' .. ngx.encode_args(args) + end + return param +end local function get_base_uri() local host = local_conf.discovery.nacos.host @@ -208,7 +216,10 @@ local function iter_and_add_service(services, values) end if up.discovery_type == 'nacos' then - core.table.insert(services, up.service_name) + core.table.insert(services, { + service_name = up.service_name, + nacos_namespace_id = up.nacos_namespace_id + }) end ::CONTINUE:: end @@ -222,7 +233,6 @@ local function get_nacos_services() 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() @@ -254,10 +264,11 @@ local function fetch_full_registry(premature) 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) + for _, service_info in ipairs(infos) do + local namespace_param = get_namespace_param(service_info.nacos_namespace_id); + data, err = get_url(base_uri, instance_list_path .. service_info.service_name + .. token_param .. namespace_param) if err then log.error('get_url:', instance_list_path, ' err:', err) if not applications then @@ -267,10 +278,10 @@ local function fetch_full_registry(premature) end for _, host in ipairs(data.hosts) do - local nodes = up_apps[service_name] + local nodes = up_apps[service_info.service_name] if not nodes then nodes = {} - up_apps[service_name] = nodes + up_apps[service_info.service_name] = nodes end core.table.insert(nodes, { host = host.ip, diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua index a391e994d3e7..9b2702af2002 100644 --- a/apisix/schema_def.lua +++ b/apisix/schema_def.lua @@ -389,6 +389,10 @@ local upstream_schema = { description = "discovery type", type = "string", }, + nacos_namespace_id = { + description = "nacos namespace id", + type = "string", + }, pass_host = { description = "mod of host passing", type = "string", diff --git a/ci/install-ext-services-via-docker.sh b/ci/install-ext-services-via-docker.sh index 87d417af6810..8f2ff28c65e9 100755 --- a/ci/install-ext-services-via-docker.sh +++ b/ci/install-ext-services-via-docker.sh @@ -55,7 +55,14 @@ wget https://raw.githubusercontent.com/api7/nacos-test-service/main/spring-nacos curl https://raw.githubusercontent.com/api7/nacos-test-service/main/Dockerfile | docker build -t nacos-test-service:1.0-SNAPSHOT -f - . docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=1 -p 18001:18001 --name nacos-service1 nacos-test-service:1.0-SNAPSHOT docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env SUFFIX_NUM=2 -p 18002:18001 --name nacos-service2 nacos-test-service:1.0-SNAPSHOT -url="127.0.0.1:18002/hello" +# register nacos service with namespaceId=test_ns +docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env SUFFIX_NUM=1 -p 18003:18001 --name nacos-service3 nacos-test-service:1.0-SNAPSHOT +# register nacos service with group=test_group +docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env GROUP=test_group --env SUFFIX_NUM=1 -p 18004:18001 --name nacos-service4 nacos-test-service:1.0-SNAPSHOT +# register nacos service with namespaceId=test_ns and group=test_group +docker run -d --rm --network nacos_net --env SERVICE_NAME=APISIX-NACOS --env NACOS_ADDR=nacos2:8848 --env NAMESPACE=test_ns --env GROUP=test_group --env SUFFIX_NUM=1 -p 18005:18001 --name nacos-service5 nacos-test-service:1.0-SNAPSHOT + +url="127.0.0.1:18005/hello" until [[ "$(curl -s -o /dev/null -w ''%{http_code}'' $url)" == "200" ]]; do echo 'wait nacos service...' sleep 1; @@ -64,4 +71,17 @@ until [[ $(curl -s "127.0.0.1:8858/nacos/v1/ns/service/list?pageNo=1&pageSize=2 echo 'wait nacos reg...' sleep 1; done +until [[ $(curl -s "127.0.0.1:8858/nacos/v1/ns/service/list?groupName=test_group&pageNo=1&pageSize=2" | grep "APISIX-NACOS") ]]; do + echo 'wait nacos reg...' + sleep 1; +done +until [[ $(curl -s "127.0.0.1:8858/nacos/v1/ns/service/list?groupName=DEFAULT_GROUP&namespaceId=test_ns&pageNo=1&pageSize=2" | grep "APISIX-NACOS") ]]; do + echo 'wait nacos reg...' + sleep 1; +done +until [[ $(curl -s "127.0.0.1:8858/nacos/v1/ns/service/list?groupName=test_group&namespaceId=test_ns&pageNo=1&pageSize=2" | grep "APISIX-NACOS") ]]; do + echo 'wait nacos reg...' + sleep 1; +done + cd .. diff --git a/docs/en/latest/discovery/nacos.md b/docs/en/latest/discovery/nacos.md index 5d5ea2b4028c..86a1296fc0eb 100644 --- a/docs/en/latest/discovery/nacos.md +++ b/docs/en/latest/discovery/nacos.md @@ -99,3 +99,46 @@ The format response as below: "action": "set" } ``` + +Example of routing a request with a URL of "/nacosWithNamespaceId/*" to a service which name, namespaceId "http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&namespaceId=test_ns" and use nacos discovery client in the registry : + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' +{ + "uri": "/nacosWithNamespaceId/*", + "upstream": { + "service_name": "APISIX-NACOS", + "type": "roundrobin", + "discovery_type": "nacos", + "nacos_namespace_id": "test_ns" + } +}' +``` + +The format response as below: + +```json +{ + "node": { + "key": "\/apisix\/routes\/2", + "value": { + "id": "1", + "create_time": 1615796097, + "status": 1, + "update_time": 1615799165, + "upstream": { + "hash_on": "vars", + "pass_host": "pass", + "scheme": "http", + "service_name": "APISIX-NACOS", + "type": "roundrobin", + "discovery_type": "nacos", + "nacos_namespace_id": "test_ns" + }, + "priority": 0, + "uri": "\/nacosWithNamespaceId\/*" + } + }, + "action": "set" +} +``` diff --git a/t/discovery/nacos.t b/t/discovery/nacos.t index 60f60cb7cac9..1c6aafee94a9 100644 --- a/t/discovery/nacos.t +++ b/t/discovery/nacos.t @@ -251,3 +251,134 @@ discovery: ] --- no_error_log [error] + + + +=== TEST 8: get APISIX-NACOS info from NACOS - no auth with namespace +--- yaml_config eval: $::yaml_config +--- apisix_yaml +routes: + - + uri: /hello + upstream: + service_name: APISIX-NACOS + discovery_type: nacos + type: roundrobin + nacos_namespace_id: test_ns +#END +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello", +] +--- response_body_like eval +[ + qr/server [1-2]/, + qr/server [1-2]/, +] +--- no_error_log +[error] + + + +=== TEST 9: get APISIX-NACOS info from NACOS - configured in services with namespace +--- yaml_config eval: $::yaml_config +--- apisix_yaml +routes: + - + uri: /hello + service_id: 1 +services: + - + id: 1 + upstream: + service_name: APISIX-NACOS + discovery_type: nacos + type: roundrobin + nacos_namespace_id: test_ns +#END +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello", +] +--- response_body_like eval +[ + qr/server [1-2]/, + qr/server [1-2]/, +] +--- no_error_log +[error] + + + +=== TEST 10: get APISIX-NACOS info from NACOS - configured in upstreams + etcd with namespace +--- extra_yaml_config +discovery: + nacos: + host: + - "http://127.0.0.1:8858" + fetch_interval: 1 +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/upstreams/1', + ngx.HTTP_PUT, + [[{ + "service_name": "APISIX-NACOS", + "discovery_type": "nacos", + "type": "roundrobin", + "nacos_namespace_id": "test_ns" + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/hello", + "upstream_id": 1 + }]] + ) + + if code >= 300 then + ngx.status = code + end + + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 11: hit with namespace +--- extra_yaml_config +discovery: + nacos: + host: + - "http://127.0.0.1:8858" + fetch_interval: 1 +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello", +] +--- response_body_like eval +[ + qr/server [1-2]/, + qr/server [1-2]/, +] +--- no_error_log +[error] From e65097430e8cc19cc18d8a12bbc290dea7314364 Mon Sep 17 00:00:00 2001 From: Demogorgon314 Date: Thu, 27 May 2021 13:45:32 +0800 Subject: [PATCH 2/3] perf: use discovery_args.namespace_id to replace nacos_namespace_id --- apisix/discovery/nacos.lua | 9 ++++++-- apisix/schema_def.lua | 11 +++++++--- docs/en/latest/discovery/nacos.md | 8 +++++-- t/discovery/nacos.t | 35 +++++++++++++++++++++++++------ 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/apisix/discovery/nacos.lua b/apisix/discovery/nacos.lua index 88f68ca5e076..4ac43781c90e 100644 --- a/apisix/discovery/nacos.lua +++ b/apisix/discovery/nacos.lua @@ -215,10 +215,15 @@ local function iter_and_add_service(services, values) up = conf end + local namespace_id + if up.discovery_args then + namespace_id = up.discovery_args.namespace_id + end + if up.discovery_type == 'nacos' then core.table.insert(services, { service_name = up.service_name, - nacos_namespace_id = up.nacos_namespace_id + namespace_id = namespace_id }) end ::CONTINUE:: @@ -266,7 +271,7 @@ local function fetch_full_registry(premature) end local data, err for _, service_info in ipairs(infos) do - local namespace_param = get_namespace_param(service_info.nacos_namespace_id); + local namespace_param = get_namespace_param(service_info.namespace_id); data, err = get_url(base_uri, instance_list_path .. service_info.service_name .. token_param .. namespace_param) if err then diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua index 9b2702af2002..0fb75739586a 100644 --- a/apisix/schema_def.lua +++ b/apisix/schema_def.lua @@ -389,9 +389,14 @@ local upstream_schema = { description = "discovery type", type = "string", }, - nacos_namespace_id = { - description = "nacos namespace id", - type = "string", + discovery_args = { + type = "object", + properties = { + namespace_id = { + description = "namespace id", + type = "string", + }, + } }, pass_host = { description = "mod of host passing", diff --git a/docs/en/latest/discovery/nacos.md b/docs/en/latest/discovery/nacos.md index 86a1296fc0eb..26b9d6c8e120 100644 --- a/docs/en/latest/discovery/nacos.md +++ b/docs/en/latest/discovery/nacos.md @@ -110,7 +110,9 @@ $ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f "service_name": "APISIX-NACOS", "type": "roundrobin", "discovery_type": "nacos", - "nacos_namespace_id": "test_ns" + "discovery_args": { + "namespace_id": "test_ns" + } } }' ``` @@ -133,7 +135,9 @@ The format response as below: "service_name": "APISIX-NACOS", "type": "roundrobin", "discovery_type": "nacos", - "nacos_namespace_id": "test_ns" + "discovery_args": { + "namespace_id": "test_ns" + } }, "priority": 0, "uri": "\/nacosWithNamespaceId\/*" diff --git a/t/discovery/nacos.t b/t/discovery/nacos.t index 1c6aafee94a9..4162517674c6 100644 --- a/t/discovery/nacos.t +++ b/t/discovery/nacos.t @@ -264,7 +264,8 @@ routes: service_name: APISIX-NACOS discovery_type: nacos type: roundrobin - nacos_namespace_id: test_ns + discovery_args: + namespace_id: test_ns #END --- pipelined_requests eval [ @@ -281,7 +282,26 @@ routes: -=== TEST 9: get APISIX-NACOS info from NACOS - configured in services with namespace +=== TEST 9: error namespace_id - no auth +--- yaml_config eval: $::yaml_config +--- apisix_yaml +routes: + - + uri: /hello + upstream: + service_name: APISIX-NACOS-DEMO + discovery_type: nacos + type: roundrobin + discovery_args: + namespace_id: err_ns +#END +--- request +GET /hello +--- error_code: 503 + + + +=== TEST 10: get APISIX-NACOS info from NACOS - configured in services with namespace --- yaml_config eval: $::yaml_config --- apisix_yaml routes: @@ -295,7 +315,8 @@ services: service_name: APISIX-NACOS discovery_type: nacos type: roundrobin - nacos_namespace_id: test_ns + discovery_args: + namespace_id: test_ns #END --- pipelined_requests eval [ @@ -312,7 +333,7 @@ services: -=== TEST 10: get APISIX-NACOS info from NACOS - configured in upstreams + etcd with namespace +=== TEST 11: get APISIX-NACOS info from NACOS - configured in upstreams + etcd with namespace --- extra_yaml_config discovery: nacos: @@ -329,7 +350,9 @@ discovery: "service_name": "APISIX-NACOS", "discovery_type": "nacos", "type": "roundrobin", - "nacos_namespace_id": "test_ns" + "discovery_args": { + "namespace_id": "test_ns" + } }]] ) @@ -363,7 +386,7 @@ passed -=== TEST 11: hit with namespace +=== TEST 12: hit with namespace --- extra_yaml_config discovery: nacos: From e03ac5d6a0d32ad7d11d84a2f58a13911af5ad7a Mon Sep 17 00:00:00 2001 From: Demogorgon314 Date: Thu, 27 May 2021 18:34:01 +0800 Subject: [PATCH 3/3] docs: fix code style --- docs/en/latest/discovery/nacos.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/latest/discovery/nacos.md b/docs/en/latest/discovery/nacos.md index 26b9d6c8e120..68b4c0ae2086 100644 --- a/docs/en/latest/discovery/nacos.md +++ b/docs/en/latest/discovery/nacos.md @@ -59,7 +59,7 @@ discovery: ### 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 : +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 ' @@ -73,7 +73,7 @@ $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f }' ``` -The format response as below: +The formatted response as below: ```json { @@ -100,7 +100,7 @@ The format response as below: } ``` -Example of routing a request with a URL of "/nacosWithNamespaceId/*" to a service which name, namespaceId "http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&namespaceId=test_ns" and use nacos discovery client in the registry : +Example of routing a request with a URL of "/nacosWithNamespaceId/*" to a service which name, namespaceId "http://192.168.33.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS&namespaceId=test_ns" and use nacos discovery client in the registry: ```shell $ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' @@ -117,7 +117,7 @@ $ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f }' ``` -The format response as below: +The formatted response as below: ```json {