feat(apisix): add Cloudron package
- Implements Apache APISIX packaging for Cloudron platform. - Includes Dockerfile, CloudronManifest.json, and start.sh. - Configured to use Cloudron's etcd addon. 🤖 Generated with Gemini CLI Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
#
|
||||
# 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;
|
||||
|
||||
my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
|
||||
my $version = eval { `$nginx_binary -V 2>&1` };
|
||||
|
||||
plan('no_plan');
|
||||
|
||||
repeat_each(1);
|
||||
log_level('warn');
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
workers(4);
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
my $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_admin: false
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
discovery:
|
||||
tars:
|
||||
db_conf:
|
||||
host: 127.0.0.1
|
||||
port: 3306
|
||||
database: db_tars
|
||||
user: root
|
||||
password: tars2022
|
||||
full_fetch_interval: 3
|
||||
incremental_fetch_interval: 1
|
||||
_EOC_
|
||||
|
||||
$block->set_value("yaml_config", $yaml_config);
|
||||
|
||||
my $apisix_yaml = $block->apisix_yaml // <<_EOC_;
|
||||
routes: []
|
||||
#END
|
||||
_EOC_
|
||||
|
||||
$block->set_value("apisix_yaml", $apisix_yaml);
|
||||
|
||||
my $extra_init_by_lua_start = <<_EOC_;
|
||||
-- reduce incremental_fetch_interval,full_fetch_interval
|
||||
local schema = require("apisix.discovery.tars.schema")
|
||||
schema.properties.incremental_fetch_interval.minimum=1
|
||||
schema.properties.incremental_fetch_interval.default=1
|
||||
schema.properties.full_fetch_interval.minimum = 3
|
||||
schema.properties.full_fetch_interval.default = 3
|
||||
_EOC_
|
||||
|
||||
$block->set_value("extra_init_by_lua_start", $extra_init_by_lua_start);
|
||||
$block->set_value("stream_extra_init_by_lua_start", $extra_init_by_lua_start);
|
||||
|
||||
my $config = $block->config // <<_EOC_;
|
||||
|
||||
location /sql {
|
||||
content_by_lua_block {
|
||||
local mysql = require("resty.mysql")
|
||||
local core = require("apisix.core")
|
||||
local ipairs = ipairs
|
||||
|
||||
ngx.req.read_body()
|
||||
local sql = ngx.req.get_body_data()
|
||||
core.log.info("get sql ", sql)
|
||||
|
||||
local db_conf= {
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
database="db_tars",
|
||||
user="root",
|
||||
password="tars2022",
|
||||
}
|
||||
|
||||
local db_cli, err = mysql:new()
|
||||
if not db_cli then
|
||||
core.log.error("failed to instantiate mysql: ", err)
|
||||
return
|
||||
end
|
||||
db_cli:set_timeout(3000)
|
||||
|
||||
local ok, err, errcode, sqlstate = db_cli:connect(db_conf)
|
||||
if not ok then
|
||||
core.log.error("failed to connect mysql: ", err, ", ", errcode, ", ", sqlstate)
|
||||
return
|
||||
end
|
||||
|
||||
local res, err, errcode, sqlstate = db_cli:query(sql)
|
||||
if not res then
|
||||
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
|
||||
return
|
||||
end
|
||||
ngx.say("DONE")
|
||||
}
|
||||
}
|
||||
_EOC_
|
||||
|
||||
$block->set_value("config", $config);
|
||||
|
||||
my $stream_config = $block->stream_config // <<_EOC_;
|
||||
server {
|
||||
listen 8125;
|
||||
content_by_lua_block {
|
||||
local core = require("apisix.core")
|
||||
local d = require("apisix.discovery.tars")
|
||||
|
||||
ngx.sleep(2)
|
||||
|
||||
local sock = ngx.req.socket()
|
||||
local request_body = sock:receive()
|
||||
|
||||
core.log.info("get body ", request_body)
|
||||
|
||||
local response_body = "{"
|
||||
local queries = core.json.decode(request_body)
|
||||
for _,query in ipairs(queries) do
|
||||
local nodes = d.nodes(query)
|
||||
if nodes==nil or #nodes==0 then
|
||||
response_body=response_body.." "..0
|
||||
else
|
||||
response_body=response_body.." "..#nodes
|
||||
end
|
||||
end
|
||||
ngx.say(response_body.." }")
|
||||
}
|
||||
}
|
||||
|
||||
_EOC_
|
||||
|
||||
$block->set_value("extra_stream_config", $stream_config);
|
||||
|
||||
});
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: create initial server and servant
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
truncate table t_server_conf",
|
||||
|
||||
"POST /sql
|
||||
truncate table t_adapter_conf",
|
||||
|
||||
"POST /sql
|
||||
insert into t_server_conf(application, server_name, node_name, registry_timestamp,
|
||||
template_name, setting_state, present_state, server_type)
|
||||
values ('A', 'AServer', '172.16.1.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('B', 'BServer', '172.16.2.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('C', 'CServer', '172.16.3.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp')",
|
||||
|
||||
"POST /sql
|
||||
insert into t_adapter_conf(application, server_name, node_name, adapter_name, endpoint, servant)
|
||||
values ('A', 'AServer', '172.16.1.1', 'A.AServer.FirstObjAdapter',
|
||||
'tcp -h 172.16.1.1 -p 10001 -e 0 -t 6000', 'A.AServer.FirstObj'),
|
||||
('B', 'BServer', '172.16.2.1', 'B.BServer.FirstObjAdapter',
|
||||
'tcp -p 10001 -h 172.16.2.1 -e 0 -t 6000', 'B.BServer.FirstObj'),
|
||||
('C', 'CServer', '172.16.3.1', 'C.CServer.FirstObjAdapter',
|
||||
'tcp -e 0 -h 172.16.3.1 -t 6000 -p 10001 ', 'C.CServer.FirstObj')",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 2: get count after create servant
|
||||
--- apisix_yaml
|
||||
stream_routes:
|
||||
-
|
||||
id: 1
|
||||
server_port: 1985
|
||||
upstream_id: 1
|
||||
|
||||
upstreams:
|
||||
- nodes:
|
||||
"127.0.0.1:8125": 1
|
||||
type: roundrobin
|
||||
id: 1
|
||||
|
||||
#END
|
||||
--- stream_request
|
||||
["A.AServer.FirstObj","B.BServer.FirstObj", "C.CServer.FirstObj"]
|
||||
--- stream_response eval
|
||||
qr{ 1 1 1 }
|
391
CloudronPackages/APISIX/apisix-source/t/tars/discovery/tars.t
Normal file
391
CloudronPackages/APISIX/apisix-source/t/tars/discovery/tars.t
Normal file
@@ -0,0 +1,391 @@
|
||||
#
|
||||
# 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('warn');
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
workers(4);
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
my $yaml_config = <<_EOC_;
|
||||
apisix:
|
||||
node_listen: 1984
|
||||
enable_admin: false
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
discovery:
|
||||
tars:
|
||||
db_conf:
|
||||
host: 127.0.0.1
|
||||
port: 3306
|
||||
database: db_tars
|
||||
user: root
|
||||
password: tars2022
|
||||
full_fetch_interval: 3
|
||||
incremental_fetch_interval: 1
|
||||
_EOC_
|
||||
|
||||
$block->set_value("yaml_config", $yaml_config);
|
||||
|
||||
my $apisix_yaml = $block->apisix_yaml // <<_EOC_;
|
||||
routes: []
|
||||
#END
|
||||
_EOC_
|
||||
|
||||
$block->set_value("apisix_yaml", $apisix_yaml);
|
||||
|
||||
my $extra_init_by_lua_start = <<_EOC_;
|
||||
-- reduce incremental_fetch_interval,full_fetch_interval
|
||||
local schema = require("apisix.discovery.tars.schema")
|
||||
schema.properties.incremental_fetch_interval.minimum=1
|
||||
schema.properties.incremental_fetch_interval.default=1
|
||||
schema.properties.full_fetch_interval.minimum = 3
|
||||
schema.properties.full_fetch_interval.default = 3
|
||||
_EOC_
|
||||
|
||||
$block->set_value("extra_init_by_lua_start", $extra_init_by_lua_start);
|
||||
|
||||
my $config = $block->config // <<_EOC_;
|
||||
location /count {
|
||||
content_by_lua_block {
|
||||
local core = require("apisix.core")
|
||||
local d = require("apisix.discovery.tars")
|
||||
|
||||
ngx.sleep(2)
|
||||
|
||||
ngx.req.read_body()
|
||||
local request_body = ngx.req.get_body_data()
|
||||
local queries = core.json.decode(request_body)
|
||||
local response_body = "{"
|
||||
for _,query in ipairs(queries) do
|
||||
local nodes = d.nodes(query)
|
||||
if nodes==nil or #nodes==0 then
|
||||
response_body=response_body.." "..0
|
||||
else
|
||||
response_body=response_body.." "..#nodes
|
||||
end
|
||||
end
|
||||
ngx.say(response_body.." }")
|
||||
}
|
||||
}
|
||||
|
||||
location /nodes {
|
||||
content_by_lua_block {
|
||||
local core = require("apisix.core")
|
||||
local d = require("apisix.discovery.tars")
|
||||
|
||||
ngx.sleep(2)
|
||||
|
||||
ngx.req.read_body()
|
||||
local servant = ngx.req.get_body_data()
|
||||
local response=""
|
||||
local nodes = d.nodes(servant)
|
||||
response="{"
|
||||
for _,node in ipairs(nodes or {}) do
|
||||
response=response..node.host..":"..node.port..","
|
||||
end
|
||||
response=response.."}"
|
||||
ngx.say(response)
|
||||
}
|
||||
}
|
||||
|
||||
location /sql {
|
||||
content_by_lua_block {
|
||||
local mysql = require("resty.mysql")
|
||||
local core = require("apisix.core")
|
||||
local ipairs = ipairs
|
||||
|
||||
ngx.req.read_body()
|
||||
local sql = ngx.req.get_body_data()
|
||||
core.log.info("get sql ", sql)
|
||||
|
||||
local db_conf= {
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
database="db_tars",
|
||||
user="root",
|
||||
password="tars2022",
|
||||
}
|
||||
|
||||
local db_cli, err = mysql:new()
|
||||
if not db_cli then
|
||||
core.log.error("failed to instantiate mysql: ", err)
|
||||
return
|
||||
end
|
||||
db_cli:set_timeout(3000)
|
||||
|
||||
local ok, err, errcode, sqlstate = db_cli:connect(db_conf)
|
||||
if not ok then
|
||||
core.log.error("failed to connect mysql: ", err, ", ", errcode, ", ", sqlstate)
|
||||
return
|
||||
end
|
||||
|
||||
local res, err, errcode, sqlstate = db_cli:query(sql)
|
||||
if not res then
|
||||
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
|
||||
return
|
||||
end
|
||||
ngx.say("DONE")
|
||||
}
|
||||
}
|
||||
_EOC_
|
||||
|
||||
$block->set_value("config", $config);
|
||||
|
||||
});
|
||||
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: create initial server and servant
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
truncate table t_server_conf",
|
||||
|
||||
"POST /sql
|
||||
truncate table t_adapter_conf",
|
||||
|
||||
"POST /sql
|
||||
insert into t_server_conf(application, server_name, node_name, registry_timestamp,
|
||||
template_name, setting_state, present_state, server_type)
|
||||
values ('A', 'AServer', '172.16.1.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('B', 'BServer', '172.16.2.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('C', 'CServer', '172.16.3.1', now(), 'taf-cpp', 'active', 'active', 'tars_cpp')",
|
||||
|
||||
"POST /sql
|
||||
insert into t_adapter_conf(application, server_name, node_name, adapter_name, endpoint, servant)
|
||||
values ('A', 'AServer', '172.16.1.1', 'A.AServer.FirstObjAdapter',
|
||||
'tcp -h 172.16.1.1 -p 10001 -e 0 -t 6000', 'A.AServer.FirstObj'),
|
||||
('B', 'BServer', '172.16.2.1', 'B.BServer.FirstObjAdapter',
|
||||
'tcp -p 10001 -h 172.16.2.1 -e 0 -t 6000', 'B.BServer.FirstObj'),
|
||||
('C', 'CServer', '172.16.3.1', 'C.CServer.FirstObjAdapter',
|
||||
'tcp -e 0 -h 172.16.3.1 -t 6000 -p 10001 ', 'C.CServer.FirstObj')",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\",\"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
"DONE\n",
|
||||
"{ 1 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 2: add servers on different nodes
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
insert into t_server_conf(application, server_name, node_name, registry_timestamp,
|
||||
template_name, setting_state, present_state, server_type)
|
||||
values ('A', 'AServer', '172.16.1.2', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('B', 'BServer', '172.16.2.2', now(), 'taf-cpp', 'active', 'active', 'tars_cpp'),
|
||||
('C', 'CServer', '172.16.3.2', now(), 'taf-cpp', 'active', 'active', 'tars_cpp')",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\",\"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"{ 1 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 3: add servant
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
insert into t_adapter_conf(application, server_name, node_name, adapter_name, endpoint, servant)
|
||||
values ('A', 'AServer', '172.16.1.2', 'A.AServer.FirstObjAdapter',
|
||||
'tcp -h 172.16.1.2 -p 10001 -e 0 -t 6000', 'A.AServer.FirstObj'),
|
||||
('A', 'AServer', '172.16.1.2', 'A.AServer.SecondObjAdapter',
|
||||
'tcp -p 10002 -h 172.16.1.2 -e 0 -t 6000', 'A.AServer.SecondObj')",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"{ 2 1 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 4: update servant, update setting_state
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
update t_server_conf set setting_state='inactive'
|
||||
where application = 'A' and server_name = 'AServer' and node_name = '172.16.1.2'",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"{ 1 0 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 5: update server setting_state
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
update t_server_conf set setting_state='active', present_state='inactive'
|
||||
where application = 'A' and server_name = 'AServer' and node_name = '172.16.1.2'",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"{ 1 0 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 6: update server present_state
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
update t_server_conf set setting_state='active', present_state='active'
|
||||
where application = 'A' and server_name = 'AServer' and node_name = '172.16.1.2'",
|
||||
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
"{ 2 1 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 7: update servant endpoint
|
||||
--- timeout: 3
|
||||
--- request eval
|
||||
[
|
||||
"GET /nodes
|
||||
A.AServer.SecondObj",
|
||||
|
||||
"POST /sql
|
||||
update t_adapter_conf set endpoint='tcp -h 172.16.1.2 -p 10003 -e 0 -t 3000'
|
||||
where application = 'A' and server_name = 'AServer'
|
||||
and node_name = '172.16.1.2' and servant='A.AServer.SecondObj'",
|
||||
|
||||
"GET /nodes
|
||||
A.AServer.SecondObj",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"{172.16.1.2:10002,}\n",
|
||||
"DONE\n",
|
||||
"{172.16.1.2:10003,}\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 8: delete servant
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
delete from t_adapter_conf where application = 'A' and server_name = 'AServer'
|
||||
and node_name = '172.16.1.2' and servant = 'A.AServer.SecondObj'",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 9: count after delete servant
|
||||
--- timeout: 4
|
||||
--- wait: 3
|
||||
--- request eval
|
||||
[
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"{ 2 0 1 1 }\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 10: delete server
|
||||
--- request eval
|
||||
[
|
||||
"POST /sql
|
||||
delete from t_server_conf
|
||||
where application = 'A' and server_name = 'AServer' and node_name = '172.16.1.1'",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"DONE\n",
|
||||
]
|
||||
|
||||
|
||||
|
||||
=== TEST 11: count after delete
|
||||
--- timeout: 4
|
||||
--- wait: 3
|
||||
--- request eval
|
||||
[
|
||||
"GET /count
|
||||
[\"A.AServer.FirstObj\", \"A.AServer.SecondObj\", \"B.BServer.FirstObj\", \"C.CServer.FirstObj\"]",
|
||||
|
||||
]
|
||||
--- response_body eval
|
||||
[
|
||||
"{ 1 0 1 1 }\n",
|
||||
]
|
Reference in New Issue
Block a user