This fixes https://emqx.atlassian.net/browse/EMQX-8648. The issue
described in `EMQX-8648` is that when deleting a non-existing bridge the
server gives a success response. See below:
```
curl --head -u admin:public2 -X 'DELETE' 'http://localhost:18083/api/v5/bridges/webhook:i_do_not_exist'
HTTP/1.1 204 No Content
date: Tue, 03 Jan 2023 16:59:01 GMT
server: Cowboy
```
After the fix, deleting a non existing bridge will give the following
response:
```
HTTP/1.1 404 Not Found
content-length: 49
content-type: application/json
date: Thu, 05 Jan 2023 12:40:35 GMT
server: Cowboy
```
Closes: EMQX-8648
Related issue: https://github.com/emqx/emqx/issues/9683
When the HTTP request for authz fails (e.g.: resource is down or
server is down), then the HTTP authorizer returns `ignore`, which was
not handled correctly by the authorization callback.
This makes the buffer/resource workers always use `replayq` for
queuing, along with collecting multiple requests in a single call.
This is done to avoid long message queues for the buffer workers and
rely on `replayq`'s capabilities of offloading to disk and detecting
overflow.
Also, this deprecates the `enable_batch` and `enable_queue` resource
creation options, as: i) queuing is now always enables; ii) batch_size
> 1 <=> batch_enabled. The corresponding metric
`dropped.queue_not_enabled` is dropped, along with `batching`. The
batching is too ephemeral, especially considering a default batch time
of 20 ms, and is not shown in the dashboard, so it was removed.
To avoid confusion for the users as to what persistence guarantees we
offer when buffering bridges/resources, we will always enable offload
mode for `replayq`. With this, when the buffer size is above the max
segment size, it'll flush the queue to disk, but on recovery after a
restart it'll clean the existing segments rather than resuming from
them.
https://emqx.atlassian.net/browse/EMQX-8502
When a bridge is disabled, its metrics are reset. With this change,
we make rule actions behave like that: disabling a rule will reset its
metrics.
https://emqx.atlassian.net/browse/EMQX-8548
Currently, we face several issues trying to keep resource metrics
reasonable. For example, when a resource is re-created and has its
metrics reset, but then its durable queue resumes its previous work
and leads to strange (often negative) metrics.
Instead using `counters` that are shared by more than one worker to
manage gauges, we introduce an ETS table whose key is not only scoped
by the Resource ID as before, but also by the worker ID. This way,
when a worker starts/terminates, they should set their own gauges to
their values (often 0 or `replayq:count` when resuming off a queue).
With this scoping and initialization procedure, we'll hopefully avoid
hitting those strange metrics scenarios and have better control over
the gauges.
https://emqx.atlassian.net/browse/EMQX-8445
Currently the bridge client’s client ID is prefixed with the resource
ID.
Sometimes it’s useful for users to have control of this prefix,
e.g. prefix based ACL rules in the target broker.
An infinite loop was triggered in the mysql connector when a query
used a prepared statement key that was not among the defined prepared
statements on start. We now check that the key is defined among the
prepared statements before recursing. It seems that this bug was never
triggered in any production code flow and simply found while writing
tests.
An error return spell fix is also included as well as a FIXME comment
regarding running mysql:prepare and not distinguishing between
transient failures and syntax errors. Syntax errors should not be
retried.
Testcase `t_log_file` was flapping when run happened to pass through
boundary of a second. Archive files' `ctime`s could differ between
consecutive archive downloads.
reason: 'ce' (Community Edition) is only for internal use,
when it comes to user/customer facing descriptions,
we should use Opensource edition and Enterprise edition.
Similary, for user/customer facing shell prompt,
use `v` for Opensource edition and `e` for Enterprise
Given the implicit convention that an egress bridge containing the
`local_topic` config will forward messages without the need for a rule
action, this was added to avoid needing a rule action.
When `system_monitor`'s application is loaded, it sets a default
hostname:
```erlang
1> application:get_env(system_monitor, db_hostname).
undefined
2> application:load(system_monitor).
ok
3> application:get_env(system_monitor, db_hostname).
{ok,"localhost"}
```
And that makes tests crash when somehow it gets loaded.
By having a semantic `enable` field, we could avoid starting this
application by checking if the hostname is filled or not.
```
=ERROR REPORT==== 1-Dec-2022::13:57:20.855070 ===
** Generic server <0.7646.3> terminating
** Last message in was {command,epgsql_cmd_connect,
#{codecs => [],database => "postgres",
host => [],
password =>
#Fun<epgsql_cmd_connect.0.29916615>,
port => 5432,timeout => 5000,
username => "system_monitor"}}
** When Server state == {state,undefined,undefined,<<>>,undefined,on_message,
undefined,
{[],[]},
undefined,undefined,undefined,undefined,[],
information_redacted,[],undefined,undefined,
undefined,undefined,undefined,#{}}
** Reason for termination ==
** {badarg,
[{gen_tcp,connect_0,4,[{file,"gen_tcp.erl"},{line,207}]},
{epgsql_cmd_connect,open_socket,2,
[{file,
"/emqx/_build/default/lib/epgsql/src/commands/epgsql_cmd_connect.erl"},
{line,94}]},
{epgsql_cmd_connect,execute,2,
[{file,
"/emqx/_build/default/lib/epgsql/src/commands/epgsql_cmd_connect.erl"},
{line,54}]},
{epgsql_sock,command_exec,4,
[{file,"/emqx/_build/default/lib/epgsql/src/epgsql_sock.erl"},
{line,338}]},
{gen_server,try_handle_call,4,[{file,"gen_server.erl"},{line,721}]},
{gen_server,handle_msg,6,[{file,"gen_server.erl"},{line,750}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}
** Client system_monitor_pg stacktrace
** [{gen,do_call,4,[{file,"gen.erl"},{line,214}]},
{gen_server,call,3,[{file,"gen_server.erl"},{line,243}]},
{epgsql,call_connect,2,
[{file,"/emqx/_build/default/lib/epgsql/src/epgsql.erl"},
{line,203}]},
{system_monitor_pg,connect,0,
[{file,"/emqx/_build/default/lib/system_monitor/src/system_monitor_pg.erl"},
{line,151}]},
{system_monitor_pg,initialize,0,
[{file,"/emqx/_build/default/lib/system_monitor/src/system_monitor_pg.erl"},
{line,142}]},
{system_monitor_pg,handle_info,2,
[{file,"/emqx/_build/default/lib/system_monitor/src/system_monitor_pg.erl"},
{line,92}]},
{gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,695}]},
{gen_server,handle_msg,6,[{file,"gen_server.erl"},{line,771}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]
=CRASH REPORT==== 1-Dec-2022::13:57:20.855697 ===
crasher:
initial call: epgsql_sock:init/1
pid: <0.7646.3>
registered_name: []
exception exit: badarg
in function gen_tcp:connect_0/4 (gen_tcp.erl, line 207)
in call from epgsql_cmd_connect:open_socket/2 (/emqx/_build/default/lib/epgsql/src/commands/epgsql_cmd_connect.erl, line 94)
in call from epgsql_cmd_connect:execute/2 (/emqx/_build/default/lib/epgsql/src/commands/epgsql_cmd_connect.erl, line 54)
in call from epgsql_sock:command_exec/4 (/emqx/_build/default/lib/epgsql/src/epgsql_sock.erl, line 338)
in call from gen_server:try_handle_call/4 (gen_server.erl, line 721)
in call from gen_server:handle_msg/6 (gen_server.erl, line 750)
ancestors: [system_monitor_pg,system_monitor2_sup,system_monitor_sup,
<0.4297.3>]
message_queue_len: 0
messages: []
links: [<0.4303.3>]
dictionary: []
trap_exit: false
status: running
heap_size: 1598
stack_size: 29
reductions: 734
neighbours:
```
Add test coverage for HTTP 204 returns from lwm2m client API
posts. This includes a small refactoring of the request functionality
in emqx_mgmt_api_test_util.