Merge remote-tracking branch 'origin/dev/v4.3.0' into umbrella-fix-build
This commit is contained in:
commit
7bdd093ef5
|
@ -35,4 +35,4 @@ Mnesia.*/
|
||||||
_checkouts
|
_checkouts
|
||||||
rebar.config.rendered
|
rebar.config.rendered
|
||||||
/rebar3
|
/rebar3
|
||||||
rebar.lock
|
rebar.lock
|
|
@ -0,0 +1 @@
|
||||||
|
erlang 22.3.4.13
|
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
REBAR_VERSION = 3.14.3-emqx-1
|
REBAR_VERSION = 3.14.3-emqx-2
|
||||||
REBAR = ./rebar3
|
REBAR = ./rebar3
|
||||||
|
|
||||||
PROFILE ?= emqx
|
PROFILE ?= emqx
|
||||||
|
|
|
@ -119,7 +119,7 @@ translate_env() ->
|
||||||
#{host := Host0,
|
#{host := Host0,
|
||||||
port := Port,
|
port := Port,
|
||||||
path := Path} = uri_string:parse(list_to_binary(URL)),
|
path := Path} = uri_string:parse(list_to_binary(URL)),
|
||||||
{ok, Host} = inet:parse_address(binary_to_list(Host0)),
|
Host = get_addr(binary_to_list(Host0)),
|
||||||
[{Name, {Host, Port, binary_to_list(Path)}} | Acc]
|
[{Name, {Host, Port, binary_to_list(Path)}} | Acc]
|
||||||
end
|
end
|
||||||
end, [], [acl_req, auth_req, super_req]),
|
end, [], [acl_req, auth_req, super_req]),
|
||||||
|
@ -145,3 +145,16 @@ same_host_and_port([{_, {Host, Port, _}}, URL = {_, {Host, Port, _}} | Rest]) ->
|
||||||
same_host_and_port([URL | Rest]);
|
same_host_and_port([URL | Rest]);
|
||||||
same_host_and_port(_) ->
|
same_host_and_port(_) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
|
get_addr(Hostname) ->
|
||||||
|
case inet:parse_address(Hostname) of
|
||||||
|
{ok, {_,_,_,_} = Addr} -> Addr;
|
||||||
|
{ok, {_,_,_,_,_,_,_,_} = Addr} -> Addr;
|
||||||
|
{error, einval} ->
|
||||||
|
case inet:getaddr(Hostname, inet) of
|
||||||
|
{error, _} ->
|
||||||
|
{ok, Addr} = inet:getaddr(Hostname, inet6),
|
||||||
|
Addr;
|
||||||
|
{ok, Addr} -> Addr
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.1
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_ldap
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
depends_on:
|
||||||
|
- ldap_server
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
ldap_server:
|
||||||
|
build: ./emqx-ldap
|
||||||
|
image: emqx-ldap:1.0
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 389:389
|
||||||
|
- 636:636
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx_bridge:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,26 @@
|
||||||
|
FROM buildpack-deps:stretch
|
||||||
|
|
||||||
|
ENV VERSION=2.4.50
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y groff groff-base
|
||||||
|
RUN wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-${VERSION}.tgz \
|
||||||
|
&& gunzip -c openldap-${VERSION}.tgz | tar xvfB - \
|
||||||
|
&& cd openldap-${VERSION} \
|
||||||
|
&& ./configure && make depend && make && make install \
|
||||||
|
&& cd .. && rm -rf openldap-${VERSION}
|
||||||
|
|
||||||
|
COPY ./slapd.conf /usr/local/etc/openldap/slapd.conf
|
||||||
|
COPY ./emqx.io.ldif /usr/local/etc/openldap/schema/emqx.io.ldif
|
||||||
|
COPY ./emqx.schema /usr/local/etc/openldap/schema/emqx.schema
|
||||||
|
COPY ./*.pem /usr/local/etc/openldap/
|
||||||
|
|
||||||
|
RUN mkdir -p /usr/local/etc/openldap/data \
|
||||||
|
&& slapadd -l /usr/local/etc/openldap/schema/emqx.io.ldif -f /usr/local/etc/openldap/slapd.conf
|
||||||
|
|
||||||
|
WORKDIR /usr/local/etc/openldap
|
||||||
|
|
||||||
|
EXPOSE 389 636
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/libexec/slapd", "-h", "ldap:/// ldaps:///", "-d", "3", "-f", "/usr/local/etc/openldap/slapd.conf"]
|
||||||
|
|
||||||
|
CMD []
|
|
@ -0,0 +1,16 @@
|
||||||
|
include /usr/local/etc/openldap/schema/core.schema
|
||||||
|
include /usr/local/etc/openldap/schema/cosine.schema
|
||||||
|
include /usr/local/etc/openldap/schema/inetorgperson.schema
|
||||||
|
include /usr/local/etc/openldap/schema/ppolicy.schema
|
||||||
|
include /usr/local/etc/openldap/schema/emqx.schema
|
||||||
|
|
||||||
|
TLSCACertificateFile /usr/local/etc/openldap/cacert.pem
|
||||||
|
TLSCertificateFile /usr/local/etc/openldap/cert.pem
|
||||||
|
TLSCertificateKeyFile /usr/local/etc/openldap/key.pem
|
||||||
|
|
||||||
|
database bdb
|
||||||
|
suffix "dc=emqx,dc=io"
|
||||||
|
rootdn "cn=root,dc=emqx,dc=io"
|
||||||
|
rootpw {SSHA}eoF7NhNrejVYYyGHqnt+MdKNBh4r1w3W
|
||||||
|
|
||||||
|
directory /usr/local/etc/openldap/data
|
|
@ -63,10 +63,8 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)),
|
emqx_metrics:inc(?AUTH_METRICS(ignore)),
|
||||||
ok;
|
ok;
|
||||||
List ->
|
List ->
|
||||||
case [ Hash || <<Salt:4/binary, Hash/binary>> <- lists:sort(fun emqx_auth_mnesia_cli:comparing/2, List),
|
case match_password(NPassword, HashType, List) of
|
||||||
Hash =:= hash(NPassword, Salt, HashType)
|
false ->
|
||||||
] of
|
|
||||||
[] ->
|
|
||||||
?LOG(error, "[Mnesia] Auth from mnesia failed: ~p", [ClientInfo]),
|
?LOG(error, "[Mnesia] Auth from mnesia failed: ~p", [ClientInfo]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
||||||
|
@ -78,7 +76,34 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
|
|
||||||
description() -> "Authentication with Mnesia".
|
description() -> "Authentication with Mnesia".
|
||||||
|
|
||||||
|
match_password(Password, HashType, HashList) ->
|
||||||
|
lists:any(
|
||||||
|
fun(Secret) ->
|
||||||
|
case is_salt_hash(Secret, HashType) of
|
||||||
|
true ->
|
||||||
|
<<Salt:4/binary, Hash/binary>> = Secret,
|
||||||
|
Hash =:= hash(Password, Salt, HashType);
|
||||||
|
_ ->
|
||||||
|
Secret =:= hash(Password, HashType)
|
||||||
|
end
|
||||||
|
end, HashList).
|
||||||
|
|
||||||
|
hash(undefined, HashType) ->
|
||||||
|
hash(<<>>, HashType);
|
||||||
|
hash(Password, HashType) ->
|
||||||
|
emqx_passwd:hash(HashType, Password).
|
||||||
|
|
||||||
hash(undefined, SaltBin, HashType) ->
|
hash(undefined, SaltBin, HashType) ->
|
||||||
hash(<<>>, SaltBin, HashType);
|
hash(<<>>, SaltBin, HashType);
|
||||||
hash(Password, SaltBin, HashType) ->
|
hash(Password, SaltBin, HashType) ->
|
||||||
emqx_passwd:hash(HashType, <<SaltBin/binary, Password/binary>>).
|
emqx_passwd:hash(HashType, <<SaltBin/binary, Password/binary>>).
|
||||||
|
|
||||||
|
is_salt_hash(_, plain) ->
|
||||||
|
true;
|
||||||
|
is_salt_hash(Secret, HashType) ->
|
||||||
|
not (byte_size(Secret) == len(HashType)).
|
||||||
|
|
||||||
|
len(md5) -> 32;
|
||||||
|
len(sha) -> 40;
|
||||||
|
len(sha256) -> 64;
|
||||||
|
len(sha512) -> 128.
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.3
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_pgsql
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
depends_on:
|
||||||
|
- pgsql_server
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
pgsql_server:
|
||||||
|
build:
|
||||||
|
context: ./pgsql
|
||||||
|
args:
|
||||||
|
BUILD_FROM: postgres:${PGSQL_TAG}
|
||||||
|
image: emqx-pgsql
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: public
|
||||||
|
POSTGRES_USER: root
|
||||||
|
POSTGRES_DB: mqtt
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx_bridge:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,8 @@
|
||||||
|
ARG BUILD_FROM=postgres:11
|
||||||
|
FROM ${BUILD_FROM}
|
||||||
|
COPY pg.conf /etc/postgresql/postgresql.conf
|
||||||
|
COPY server-cert.pem /etc/postgresql/server-cert.pem
|
||||||
|
COPY server-key.pem /etc/postgresql/server-key.pem
|
||||||
|
RUN chown -R postgres:postgres /etc/postgresql \
|
||||||
|
&& chmod 600 /etc/postgresql/*.pem
|
||||||
|
CMD ["-c", "config_file=/etc/postgresql/postgresql.conf"]
|
|
@ -1,9 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
version: '2.4'
|
||||||
|
# network configuration is limited in version 3
|
||||||
|
# https://github.com/docker/compose/issues/4958
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.3
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_redis
|
||||||
|
networks:
|
||||||
|
- app_net
|
||||||
|
depends_on:
|
||||||
|
- redis_cluster
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
redis_cluster:
|
||||||
|
image: redis:6.0.9
|
||||||
|
container_name: redis-cluster
|
||||||
|
volumes:
|
||||||
|
- ../test/emqx_auth_redis_SUITE_data/certs:/tls
|
||||||
|
- ./redis/:/data/conf
|
||||||
|
command: bash -c "/bin/bash /data/conf/redis.sh -t && while true; do echo 1; sleep 1; done"
|
||||||
|
networks:
|
||||||
|
app_net:
|
||||||
|
# Assign a public address. Erlang container cannot find cluster nodes by network-scoped alias (redis_cluster).
|
||||||
|
ipv4_address: 172.16.239.10
|
||||||
|
ipv6_address: 2001:3200:3200::20
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app_net:
|
||||||
|
driver: bridge
|
||||||
|
enable_ipv6: true
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 172.16.239.0/24
|
||||||
|
gateway: 172.16.239.1
|
||||||
|
- subnet: 2001:3200:3200::/64
|
||||||
|
gateway: 2001:3200:3200::1
|
|
@ -0,0 +1,38 @@
|
||||||
|
version: '2.4'
|
||||||
|
# network configuration is limited in version 3
|
||||||
|
# https://github.com/docker/compose/issues/4958
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.3
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_redis
|
||||||
|
networks:
|
||||||
|
- app_net
|
||||||
|
depends_on:
|
||||||
|
- redis_cluster
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
redis_cluster:
|
||||||
|
image: redis:${REDIS_TAG}
|
||||||
|
container_name: redis-cluster
|
||||||
|
volumes:
|
||||||
|
- ./redis/:/data/conf
|
||||||
|
command: bash -c "/bin/bash /data/conf/redis.sh && while true; do echo 1; sleep 1; done"
|
||||||
|
networks:
|
||||||
|
app_net:
|
||||||
|
# Assign a public address. Erlang container cannot find cluster nodes by network-scoped alias (redis_cluster).
|
||||||
|
ipv4_address: 172.16.239.10
|
||||||
|
ipv6_address: 2001:3200:3200::20
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app_net:
|
||||||
|
driver: bridge
|
||||||
|
enable_ipv6: true
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 172.16.239.0/24
|
||||||
|
gateway: 172.16.239.1
|
||||||
|
- subnet: 2001:3200:3200::/64
|
||||||
|
gateway: 2001:3200:3200::1
|
|
@ -0,0 +1,31 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.3
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_redis
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
depends_on:
|
||||||
|
- redis_server
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
redis_server:
|
||||||
|
image: redis:6.0.9
|
||||||
|
volumes:
|
||||||
|
- ../test/emqx_auth_redis_SUITE_data/certs:/tls
|
||||||
|
command:
|
||||||
|
- redis-server
|
||||||
|
- "--bind 0.0.0.0 ::"
|
||||||
|
- --tls-port 6380
|
||||||
|
- --tls-cert-file /tls/redis.crt
|
||||||
|
- --tls-key-file /tls/redis.key
|
||||||
|
- --tls-ca-cert-file /tls/ca.crt
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx_bridge:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,25 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
erlang:
|
||||||
|
image: erlang:22.3
|
||||||
|
volumes:
|
||||||
|
- ../:/emqx_auth_redis
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
depends_on:
|
||||||
|
- redis_server
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
redis_server:
|
||||||
|
image: redis:${REDIS_TAG}
|
||||||
|
command:
|
||||||
|
- redis-server
|
||||||
|
- "--bind 0.0.0.0 ::"
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- emqx_bridge
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx_bridge:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,3 @@
|
||||||
|
cluster-enabled yes
|
||||||
|
cluster-node-timeout 10000
|
||||||
|
bind 0.0.0.0 ::
|
|
@ -0,0 +1,71 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
tls=false;
|
||||||
|
while getopts t OPT
|
||||||
|
do
|
||||||
|
case $OPT in
|
||||||
|
t) tls=true
|
||||||
|
;;
|
||||||
|
\?) exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f \
|
||||||
|
/data/conf/r7000i.log \
|
||||||
|
/data/conf/r7001i.log \
|
||||||
|
/data/conf/r7002i.log \
|
||||||
|
/data/conf/nodes.7000.conf \
|
||||||
|
/data/conf/nodes.7001.conf \
|
||||||
|
/data/conf/nodes.7002.conf ;
|
||||||
|
|
||||||
|
if $tls ; then
|
||||||
|
redis-server /data/conf/redis.conf --port 7000 --cluster-config-file /data/conf/nodes.7000.conf --daemonize yes \
|
||||||
|
--tls-port 8000 \
|
||||||
|
--tls-cert-file /tls/redis.crt \
|
||||||
|
--tls-key-file /tls/redis.key \
|
||||||
|
--tls-ca-cert-file /tls/ca.crt
|
||||||
|
redis-server /data/conf/redis.conf --port 7001 --cluster-config-file /data/conf/nodes.7001.conf --daemonize yes \
|
||||||
|
--tls-port 8001 \
|
||||||
|
--tls-cert-file /tls/redis.crt \
|
||||||
|
--tls-key-file /tls/redis.key \
|
||||||
|
--tls-ca-cert-file /tls/ca.crt
|
||||||
|
redis-server /data/conf/redis.conf --port 7002 --cluster-config-file /data/conf/nodes.7002.conf --daemonize yes \
|
||||||
|
--tls-port 8002 \
|
||||||
|
--tls-cert-file /tls/redis.crt \
|
||||||
|
--tls-key-file /tls/redis.key \
|
||||||
|
--tls-ca-cert-file /tls/ca.crt
|
||||||
|
else
|
||||||
|
redis-server /data/conf/redis.conf --port 7000 --cluster-config-file /data/conf/nodes.7000.conf --daemonize yes ;
|
||||||
|
redis-server /data/conf/redis.conf --port 7001 --cluster-config-file /data/conf/nodes.7001.conf --daemonize yes ;
|
||||||
|
redis-server /data/conf/redis.conf --port 7002 --cluster-config-file /data/conf/nodes.7002.conf --daemonize yes ;
|
||||||
|
fi
|
||||||
|
|
||||||
|
REDIS_LOAD_FLG=true;
|
||||||
|
|
||||||
|
while $REDIS_LOAD_FLG;
|
||||||
|
do
|
||||||
|
sleep 1;
|
||||||
|
redis-cli -p 7000 info 1> /data/conf/r7000i.log 2> /dev/null;
|
||||||
|
if [ -s /data/conf/r7000i.log ]; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
redis-cli -p 7001 info 1> /data/conf/r7001i.log 2> /dev/null;
|
||||||
|
if [ -s /data/conf/r7001i.log ]; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
redis-cli -p 7002 info 1> /data/conf/r7002i.log 2> /dev/null;
|
||||||
|
if [ -s /data/conf/r7002i.log ]; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
yes "yes" | redis-cli --cluster create 172.16.239.10:7000 172.16.239.10:7001 172.16.239.10:7002;
|
||||||
|
REDIS_LOAD_FLG=false;
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0;
|
|
@ -24,3 +24,5 @@ erlang.mk
|
||||||
rebar.lock
|
rebar.lock
|
||||||
/.idea/
|
/.idea/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/.ci/redis/nodes.*.conf
|
||||||
|
/.ci/redis/*.log
|
|
@ -1,10 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -69,21 +69,18 @@ set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_redis_rows() ->
|
init_redis_rows() ->
|
||||||
{ok, Connection} = ?POOL(?APP),
|
|
||||||
%% Users
|
%% Users
|
||||||
[eredis:q(Connection, ["HMSET", Key|FiledValue]) || {Key, FiledValue} <- ?INIT_AUTH],
|
[q(["HMSET", Key|FiledValue]) || {Key, FiledValue} <- ?INIT_AUTH],
|
||||||
|
|
||||||
%% ACLs
|
%% ACLs
|
||||||
emqx_modules:load_module(emqx_mod_acl_internal, false),
|
emqx_modules:load_module(emqx_mod_acl_internal, false),
|
||||||
Result = [eredis:q(Connection, ["HSET", Key, Filed, Value]) || {Key, Filed, Value} <- ?INIT_ACL],
|
Result = [q(["HSET", Key, Filed, Value]) || {Key, Filed, Value} <- ?INIT_ACL],
|
||||||
ct:pal("redis init result: ~p~n", [Result]).
|
ct:pal("redis init result: ~p~n", [Result]).
|
||||||
|
|
||||||
deinit_redis_rows() ->
|
deinit_redis_rows() ->
|
||||||
{ok, Connection} = ?POOL(?APP),
|
|
||||||
AuthKeys = [Key || {Key, _Filed, _Value} <- ?INIT_AUTH],
|
AuthKeys = [Key || {Key, _Filed, _Value} <- ?INIT_AUTH],
|
||||||
AclKeys = [Key || {Key, _Value} <- ?INIT_ACL],
|
AclKeys = [Key || {Key, _Value} <- ?INIT_ACL],
|
||||||
eredis:q(Connection, ["DEL" | AuthKeys]),
|
q(["DEL" | AuthKeys]),
|
||||||
eredis:q(Connection, ["DEL" | AclKeys]).
|
q(["DEL" | AclKeys]).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Cases
|
%% Cases
|
||||||
|
@ -121,9 +118,8 @@ t_check_auth(_) ->
|
||||||
{error, _} = emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}).
|
{error, _} = emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}).
|
||||||
|
|
||||||
t_check_auth_hget(_) ->
|
t_check_auth_hget(_) ->
|
||||||
{ok, Connection} = ?POOL(?APP),
|
q(["HSET", "mqtt_user:hset", "password", "hset"]),
|
||||||
eredis:q(Connection, ["HSET", "mqtt_user:hset", "password", "hset"]),
|
q(["HSET", "mqtt_user:hset", "is_superuser", "1"]),
|
||||||
eredis:q(Connection, ["HSET", "mqtt_user:hset", "is_superuser", "1"]),
|
|
||||||
reload([{password_hash, plain}, {auth_cmd, "HGET mqtt_user:%u password"}]),
|
reload([{password_hash, plain}, {auth_cmd, "HGET mqtt_user:%u password"}]),
|
||||||
Hset = #{clientid => <<"hset">>, username => <<"hset">>, zone => external},
|
Hset = #{clientid => <<"hset">>, username => <<"hset">>, zone => external},
|
||||||
{ok, #{is_superuser := true}} = emqx_access_control:authenticate(Hset#{password => <<"hset">>}).
|
{ok, #{is_superuser := true}} = emqx_access_control:authenticate(Hset#{password => <<"hset">>}).
|
||||||
|
@ -164,6 +160,16 @@ t_acl_super(_) ->
|
||||||
end,
|
end,
|
||||||
emqtt:disconnect(C).
|
emqtt:disconnect(C).
|
||||||
|
|
||||||
|
t_check_cluster_connection(_) ->
|
||||||
|
?assertMatch({error, _Reason}, reload([{server, [{type,cluster},
|
||||||
|
{pool_size,8},
|
||||||
|
{auto_reconnect,1},
|
||||||
|
{database,0},
|
||||||
|
{password,[]},
|
||||||
|
{sentinel,[]},
|
||||||
|
{servers,[{"wrong",6379},{"wrong",6380},{"wrong",6381}]}]}])).
|
||||||
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal funcs
|
%% Internal funcs
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -172,3 +178,13 @@ reload(Config) when is_list(Config) ->
|
||||||
application:stop(?APP),
|
application:stop(?APP),
|
||||||
[application:set_env(?APP, K, V) || {K, V} <- Config],
|
[application:set_env(?APP, K, V) || {K, V} <- Config],
|
||||||
application:start(?APP).
|
application:start(?APP).
|
||||||
|
|
||||||
|
q(Cmd) ->
|
||||||
|
{ok, Server} = application:get_env(?APP, server),
|
||||||
|
case proplists:get_value(type, Server) of
|
||||||
|
single ->
|
||||||
|
{ok, Connection} = ?POOL(?APP),
|
||||||
|
eredis:q(Connection, Cmd);
|
||||||
|
cluster ->
|
||||||
|
eredis_cluster:q(emqx_auth_redis, Cmd)
|
||||||
|
end.
|
|
@ -1,10 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<"*.">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
webpackJsonp([20],{"4odX":function(t,e){},LbE0:function(t,e,s){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a={name:"help-view",components:{},data:function(){return{lang:window.localStorage.getItem("language")||"en"}},computed:{learnEnterprise:function(){return"zh"===this.lang?"https://www.emqx.io/cn/products/enterprise":"https://www.emqx.io/products/enterprise"},freeTrial:function(){return"zh"===this.lang?"https://www.emqx.io/cn/downloads#enterprise":"https://www.emqx.io/downloads#enterprise"},docsLink:function(){return"zh"===this.lang?"https://docs.emqx.io/broker/v4/cn":"https://docs.emqx.io/broker/v4/en"},faqLink:function(){return"zh"===this.lang?"https://docs.emqx.io/broker/latest/cn/faq/faq.html":"https://docs.emqx.io/tutorial/v4/en/faq/faq.html"}},methods:{}},n={render:function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{staticClass:"help-view"},[s("div",{staticClass:"page-title"},[t._v(t._s(t.$t("leftbar.help")))]),t._v(" "),s("div",{staticClass:"help-item"},[s("h3",[t._v(t._s(t.$t("help.quickStart")))]),t._v(" "),s("p",[t._v(t._s(t.$t("help.emqxDesc")))]),t._v(" "),s("a",{attrs:{target:"_blank",href:"https://github.com/emqx/emqx"}},[t._v("Github")])]),t._v(" "),s("el-divider"),t._v(" "),s("div",{staticClass:"help-item"},[s("h3",[t._v(t._s(t.$t("help.emqxEnterprise")))]),t._v(" "),s("p",{domProps:{innerHTML:t._s(t.$t("help.enterpriseDesc"))}}),t._v(" "),s("a",{attrs:{target:"_blank",href:t.learnEnterprise}},[t._v("\n "+t._s(t.$t("oper.learnMore"))+"\n ")]),t._v(" "),s("a",{attrs:{target:"_blank",href:t.freeTrial}},[t._v("\n "+t._s(t.$t("help.freeTrial"))+"\n ")])]),t._v(" "),s("el-divider"),t._v(" "),s("div",{staticClass:"help-item"},[s("h3",[t._v(t._s(t.$t("help.useDocs")))]),t._v(" "),s("p",[t._v(t._s(t.$t("help.docsDesc")))]),t._v(" "),s("a",{attrs:{target:"_blank",href:t.docsLink}},[t._v("\n "+t._s(t.$t("help.forwardView"))+"\n ")])]),t._v(" "),s("el-divider"),t._v(" "),s("div",{staticClass:"help-item"},[s("h3",[t._v("FAQ")]),t._v(" "),s("p",[t._v(t._s(t.$t("help.faqDesc")))]),t._v(" "),s("a",{attrs:{target:"_blank",href:t.faqLink}},[t._v("\n "+t._s(t.$t("help.forwardFaq"))+"\n ")])]),t._v(" "),s("el-divider"),t._v(" "),s("div",{staticClass:"help-item"},[s("h3",[t._v(t._s(t.$t("help.followUs")))]),t._v(" "),t._m(0),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4),t._v(" "),t._m(5)])],1)},staticRenderFns:[function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://github.com/emqx/emqx"}},[e("i",{staticClass:"iconfont icon-git"})])},function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://twitter.com/emqtt"}},[e("i",{staticClass:"iconfont icon-tuite"})])},function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://emqx.slack.com/"}},[e("i",{staticClass:"iconfont icon-slack"})])},function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://stackoverflow.com/questions/tagged/emq"}},[e("i",{staticClass:"iconfont icon-stack-overflow"})])},function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://groups.google.com/forum/#!forum/emqtt"}},[e("i",{staticClass:"iconfont icon-icons-google_groups"})])},function(){var t=this.$createElement,e=this._self._c||t;return e("a",{staticClass:"follow-link",attrs:{target:"_blank",href:"https://www.youtube.com/channel/UCDU9GWFk8NTGiTvPx_2XskA"}},[e("i",{staticClass:"iconfont icon-youtube"})])}]};var i=s("VU/8")(a,n,!1,function(t){s("4odX")},null,null);e.default=i.exports}});
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
!function(e){var a=window.webpackJsonp;window.webpackJsonp=function(c,t,f){for(var o,d,b,i=0,u=[];i<c.length;i++)d=c[i],n[d]&&u.push(n[d][0]),n[d]=0;for(o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);for(a&&a(c,t,f);u.length;)u.shift()();if(f)for(i=0;i<f.length;i++)b=r(r.s=f[i]);return b};var c={},n={27:0};function r(a){if(c[a])return c[a].exports;var n=c[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.e=function(e){var a=n[e];if(0===a)return new Promise(function(e){e()});if(a)return a[2];var c=new Promise(function(c,r){a=n[e]=[c,r]});a[2]=c;var t=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.timeout=12e4,r.nc&&f.setAttribute("nonce",r.nc),f.src=r.p+"static/js/"+e+"."+{0:"7a09d1383e1319441399",1:"fcd6fde8b053e80bc68f",2:"71ffb214c95162432f13",3:"25b49772270df4b9915d",4:"93d4473fcf7768693652",5:"8935139a413f40d70253",6:"ef8e6aa7a51fa7564f71",7:"92a348a80764134ff2a9",8:"e86f6131cc8a9138368d",9:"473ceac05f7dfe3f3e92",10:"188c5e479f887d471dde",11:"3861aeb3036b8f41a6e8",12:"43feccc8f1584bdba5c2",13:"026a13a2a59abd354bd5",14:"0342a1a3d29f1adca947",15:"7d11711536eb5b2ca561",16:"6bfd6f3eb9216e73149c",17:"1d56280c16e6e2b81cff",18:"a0c394cb4b55bee2fa82",19:"060521bb4ba4f7a81ac0",20:"308aa0fdf6653ef3299f",21:"306758a2a6ef73532290",22:"d968dc6f54a690adde18",23:"7837b8f015b7d486b74f",24:"ccbcfda924431cb282e2",25:"8b2dccd8a7e1f91a5040",26:"9cd922cc7e5d035cbcc7"}[e]+".js";var o=setTimeout(d,12e4);function d(){f.onerror=f.onload=null,clearTimeout(o);var a=n[e];0!==a&&(a&&a[1](new Error("Loading chunk "+e+" failed.")),n[e]=void 0)}return f.onerror=f.onload=d,t.appendChild(f),c},r.m=e,r.c=c,r.d=function(e,a,c){r.o(e,a)||Object.defineProperty(e,a,{configurable:!1,enumerable:!0,get:c})},r.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(a,"a",a),a},r.o=function(e,a){return Object.prototype.hasOwnProperty.call(e,a)},r.p="/",r.oe=function(e){throw console.error(e),e}}([]);
|
|
|
@ -1,24 +0,0 @@
|
||||||
%%-*- mode: erlang -*-
|
|
||||||
%% .app.src.script
|
|
||||||
|
|
||||||
RemoveLeadingV =
|
|
||||||
fun(Tag) ->
|
|
||||||
case re:run(Tag, "^[v]?[0-9]\.[0-9]\.([0-9]|(rc|beta|alpha)\.[0-9])", [{capture, none}]) of
|
|
||||||
nomatch ->
|
|
||||||
re:replace(Tag, "/", "-", [{return ,list}]);
|
|
||||||
_ ->
|
|
||||||
%% if it is a version number prefixed by 'v' or 'e', then remove it
|
|
||||||
re:replace(Tag, "[v]", "", [{return ,list}])
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
case os:getenv("EMQX_DEPS_DEFAULT_VSN") of
|
|
||||||
false -> CONFIG; % env var not defined
|
|
||||||
[] -> CONFIG; % env var set to empty string
|
|
||||||
Tag ->
|
|
||||||
[begin
|
|
||||||
AppConf0 = lists:keystore(vsn, 1, AppConf, {vsn, RemoveLeadingV(Tag)}),
|
|
||||||
{application, App, AppConf0}
|
|
||||||
end || Conf = {application, App, AppConf} <- CONFIG]
|
|
||||||
end.
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -1,24 +0,0 @@
|
||||||
%%-*- mode: erlang -*-
|
|
||||||
%% .app.src.script
|
|
||||||
|
|
||||||
RemoveLeadingV =
|
|
||||||
fun(Tag) ->
|
|
||||||
case re:run(Tag, "^[v]?[0-9]\.[0-9]\.([0-9]|(rc|beta|alpha)\.[0-9])", [{capture, none}]) of
|
|
||||||
nomatch ->
|
|
||||||
re:replace(Tag, "/", "-", [{return ,list}]);
|
|
||||||
_ ->
|
|
||||||
%% if it is a version number prefixed by 'v' or 'e', then remove it
|
|
||||||
re:replace(Tag, "[v]", "", [{return ,list}])
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
case os:getenv("EMQX_DEPS_DEFAULT_VSN") of
|
|
||||||
false -> CONFIG; % env var not defined
|
|
||||||
[] -> CONFIG; % env var set to empty string
|
|
||||||
Tag ->
|
|
||||||
[begin
|
|
||||||
AppConf0 = lists:keystore(vsn, 1, AppConf, {vsn, RemoveLeadingV(Tag)}),
|
|
||||||
{application, App, AppConf0}
|
|
||||||
end || Conf = {application, App, AppConf} <- CONFIG]
|
|
||||||
end.
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -25,3 +25,4 @@
|
||||||
{cover_enabled, true}.
|
{cover_enabled, true}.
|
||||||
{cover_opts, [verbose]}.
|
{cover_opts, [verbose]}.
|
||||||
{cover_export_enabled, true}.
|
{cover_export_enabled, true}.
|
||||||
|
{extra_src_dirs, [{"lwm2m_xml", [{recursive,true}]}]}.
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -78,10 +78,6 @@
|
||||||
, bitxor/2
|
, bitxor/2
|
||||||
, bitsl/2
|
, bitsl/2
|
||||||
, bitsr/2
|
, bitsr/2
|
||||||
, bitsize/1
|
|
||||||
, subbits/2
|
|
||||||
, subbits/3
|
|
||||||
, subbits/6
|
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% Data Type Convertion
|
%% Data Type Convertion
|
||||||
|
@ -237,7 +233,7 @@ payload() ->
|
||||||
|
|
||||||
payload(Path) ->
|
payload(Path) ->
|
||||||
fun(#{payload := Payload}) when erlang:is_map(Payload) ->
|
fun(#{payload := Payload}) when erlang:is_map(Payload) ->
|
||||||
map_get(Path, Payload);
|
emqx_rule_maps:nested_get(map_path(Path), Payload);
|
||||||
(_) -> undefined
|
(_) -> undefined
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -405,74 +401,6 @@ bitsl(X, I) when is_integer(X), is_integer(I) ->
|
||||||
bitsr(X, I) when is_integer(X), is_integer(I) ->
|
bitsr(X, I) when is_integer(X), is_integer(I) ->
|
||||||
X bsr I.
|
X bsr I.
|
||||||
|
|
||||||
bitsize(Bits) when is_bitstring(Bits) ->
|
|
||||||
bit_size(Bits).
|
|
||||||
|
|
||||||
subbits(Bits, Len) when is_integer(Len), is_bitstring(Bits) ->
|
|
||||||
subbits(Bits, 1, Len).
|
|
||||||
|
|
||||||
subbits(Bits, Start, Len) when is_integer(Start), is_integer(Len), is_bitstring(Bits) ->
|
|
||||||
get_subbits(Bits, Start, Len, <<"integer">>, <<"unsigned">>, <<"big">>).
|
|
||||||
|
|
||||||
subbits(Bits, Start, Len, Type, Signedness, Endianness) when is_integer(Start), is_integer(Len), is_bitstring(Bits) ->
|
|
||||||
get_subbits(Bits, Start, Len, Type, Signedness, Endianness).
|
|
||||||
|
|
||||||
get_subbits(Bits, Start, Len, Type, Signedness, Endianness) ->
|
|
||||||
Begin = Start - 1,
|
|
||||||
case Bits of
|
|
||||||
<<_:Begin, Rem/bits>> when Rem =/= <<>> ->
|
|
||||||
Sz = bit_size(Rem),
|
|
||||||
do_get_subbits(Rem, Sz, Len, Type, Signedness, Endianness);
|
|
||||||
_ -> undefined
|
|
||||||
end.
|
|
||||||
|
|
||||||
-define(match_bits(Bits0, Pattern, ElesePattern),
|
|
||||||
case Bits0 of
|
|
||||||
Pattern ->
|
|
||||||
SubBits;
|
|
||||||
ElesePattern ->
|
|
||||||
SubBits
|
|
||||||
end).
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"integer">>, <<"unsigned">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/integer-unsigned-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/integer-unsigned-big-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"float">>, <<"unsigned">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/float-unsigned-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/float-unsigned-big-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"bits">>, <<"unsigned">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/bits-unsigned-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/bits-unsigned-big-unit:1>>);
|
|
||||||
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"integer">>, <<"signed">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/integer-signed-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/integer-signed-big-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"float">>, <<"signed">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/float-signed-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/float-signed-big-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"bits">>, <<"signed">>, <<"big">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/bits-signed-big-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/bits-signed-big-unit:1>>);
|
|
||||||
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"integer">>, <<"unsigned">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/integer-unsigned-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/integer-unsigned-little-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"float">>, <<"unsigned">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/float-unsigned-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/float-unsigned-little-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"bits">>, <<"unsigned">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/bits-unsigned-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/bits-unsigned-little-unit:1>>);
|
|
||||||
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"integer">>, <<"signed">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/integer-signed-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/integer-signed-little-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"float">>, <<"signed">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/float-signed-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/float-signed-little-unit:1>>);
|
|
||||||
do_get_subbits(Bits, Sz, Len, <<"bits">>, <<"signed">>, <<"little">>) ->
|
|
||||||
?match_bits(Bits, <<SubBits:Len/bits-signed-little-unit:1, _/bits>>,
|
|
||||||
<<SubBits:Sz/bits-signed-little-unit:1>>).
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Data Type Convertion Funcs
|
%% Data Type Convertion Funcs
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
@ -682,10 +610,52 @@ map_get(Key, Map) ->
|
||||||
map_get(Key, Map, undefined).
|
map_get(Key, Map, undefined).
|
||||||
|
|
||||||
map_get(Key, Map, Default) ->
|
map_get(Key, Map, Default) ->
|
||||||
emqx_rule_maps:nested_get(map_path(Key), Map, Default).
|
case maps:find(Key, Map) of
|
||||||
|
{ok, Val} -> Val;
|
||||||
|
error when is_atom(Key) ->
|
||||||
|
%% the map may have an equivalent binary-form key
|
||||||
|
BinKey = emqx_rule_utils:bin(Key),
|
||||||
|
case maps:find(BinKey, Map) of
|
||||||
|
{ok, Val} -> Val;
|
||||||
|
error -> Default
|
||||||
|
end;
|
||||||
|
error when is_binary(Key) ->
|
||||||
|
try %% the map may have an equivalent atom-form key
|
||||||
|
AtomKey = list_to_existing_atom(binary_to_list(Key)),
|
||||||
|
case maps:find(AtomKey, Map) of
|
||||||
|
{ok, Val} -> Val;
|
||||||
|
error -> Default
|
||||||
|
end
|
||||||
|
catch error:badarg ->
|
||||||
|
Default
|
||||||
|
end;
|
||||||
|
error ->
|
||||||
|
Default
|
||||||
|
end.
|
||||||
|
|
||||||
map_put(Key, Val, Map) ->
|
map_put(Key, Val, Map) ->
|
||||||
emqx_rule_maps:nested_put(map_path(Key), Val, Map).
|
case maps:find(Key, Map) of
|
||||||
|
{ok, _} -> maps:put(Key, Val, Map);
|
||||||
|
error when is_atom(Key) ->
|
||||||
|
%% the map may have an equivalent binary-form key
|
||||||
|
BinKey = emqx_rule_utils:bin(Key),
|
||||||
|
case maps:find(BinKey, Map) of
|
||||||
|
{ok, _} -> maps:put(BinKey, Val, Map);
|
||||||
|
error -> maps:put(Key, Val, Map)
|
||||||
|
end;
|
||||||
|
error when is_binary(Key) ->
|
||||||
|
try %% the map may have an equivalent atom-form key
|
||||||
|
AtomKey = list_to_existing_atom(binary_to_list(Key)),
|
||||||
|
case maps:find(AtomKey, Map) of
|
||||||
|
{ok, _} -> maps:put(AtomKey, Val, Map);
|
||||||
|
error -> maps:put(Key, Val, Map)
|
||||||
|
end
|
||||||
|
catch error:badarg ->
|
||||||
|
maps:put(Key, Val, Map)
|
||||||
|
end;
|
||||||
|
error ->
|
||||||
|
maps:put(Key, Val, Map)
|
||||||
|
end.
|
||||||
|
|
||||||
mget(Key, Map) ->
|
mget(Key, Map) ->
|
||||||
mget(Key, Map, undefined).
|
mget(Key, Map, undefined).
|
||||||
|
|
|
@ -489,75 +489,22 @@ t_contains(_) ->
|
||||||
|
|
||||||
t_map_get(_) ->
|
t_map_get(_) ->
|
||||||
?assertEqual(1, apply_func(map_get, [<<"a">>, #{a => 1}])),
|
?assertEqual(1, apply_func(map_get, [<<"a">>, #{a => 1}])),
|
||||||
?assertEqual(undefined, apply_func(map_get, [<<"a">>, #{}])),
|
?assertEqual(undefined, apply_func(map_get, [<<"a">>, #{}])).
|
||||||
?assertEqual(1, apply_func(map_get, [<<"a.b">>, #{a => #{b => 1}}])),
|
|
||||||
?assertEqual(undefined, apply_func(map_get, [<<"a.c">>, #{a => #{b => 1}}])).
|
|
||||||
|
|
||||||
t_map_put(_) ->
|
t_map_put(_) ->
|
||||||
?assertEqual(#{<<"a">> => 1}, apply_func(map_put, [<<"a">>, 1, #{}])),
|
?assertEqual(#{<<"a">> => 1}, apply_func(map_put, [<<"a">>, 1, #{}])),
|
||||||
?assertEqual(#{a => 2}, apply_func(map_put, [<<"a">>, 2, #{a => 1}])),
|
?assertEqual(#{a => 2}, apply_func(map_put, [<<"a">>, 2, #{a => 1}])).
|
||||||
?assertEqual(#{<<"a">> => #{<<"b">> => 1}}, apply_func(map_put, [<<"a.b">>, 1, #{}])),
|
|
||||||
?assertEqual(#{a => #{b => 1, <<"c">> => 1}}, apply_func(map_put, [<<"a.c">>, 1, #{a => #{b => 1}}])).
|
|
||||||
|
|
||||||
t_mget(_) ->
|
t_mget(_) ->
|
||||||
?assertEqual(1, apply_func(map_get, [<<"a">>, #{a => 1}])),
|
?assertEqual(1, apply_func(map_get, [<<"a">>, #{a => 1}])),
|
||||||
?assertEqual(1, apply_func(map_get, [<<"a">>, #{<<"a">> => 1}])),
|
?assertEqual(1, apply_func(map_get, [<<"a">>, #{<<"a">> => 1}])),
|
||||||
?assertEqual(undefined, apply_func(map_get, [<<"a">>, #{}])).
|
?assertEqual(undefined, apply_func(map_get, [<<"a">>, #{}])).
|
||||||
|
|
||||||
t_mput(_) ->
|
t_mput(_) ->
|
||||||
?assertEqual(#{<<"a">> => 1}, apply_func(map_put, [<<"a">>, 1, #{}])),
|
?assertEqual(#{<<"a">> => 1}, apply_func(map_put, [<<"a">>, 1, #{}])),
|
||||||
?assertEqual(#{<<"a">> => 2}, apply_func(map_put, [<<"a">>, 2, #{<<"a">> => 1}])),
|
?assertEqual(#{<<"a">> => 2}, apply_func(map_put, [<<"a">>, 2, #{<<"a">> => 1}])),
|
||||||
?assertEqual(#{a => 2}, apply_func(map_put, [<<"a">>, 2, #{a => 1}])).
|
?assertEqual(#{a => 2}, apply_func(map_put, [<<"a">>, 2, #{a => 1}])).
|
||||||
|
|
||||||
t_bitsize(_) ->
|
|
||||||
?assertEqual(8, apply_func(bitsize, [<<"a">>])),
|
|
||||||
?assertEqual(4, apply_func(bitsize, [<<15:4>>])).
|
|
||||||
|
|
||||||
t_subbits(_) ->
|
|
||||||
?assertEqual(1, apply_func(subbits, [<<255:8>>, 1])),
|
|
||||||
?assertEqual(3, apply_func(subbits, [<<255:8>>, 2])),
|
|
||||||
?assertEqual(7, apply_func(subbits, [<<255:8>>, 3])),
|
|
||||||
?assertEqual(15, apply_func(subbits, [<<255:8>>, 4])),
|
|
||||||
?assertEqual(31, apply_func(subbits, [<<255:8>>, 5])),
|
|
||||||
?assertEqual(63, apply_func(subbits, [<<255:8>>, 6])),
|
|
||||||
?assertEqual(127, apply_func(subbits, [<<255:8>>, 7])),
|
|
||||||
?assertEqual(255, apply_func(subbits, [<<255:8>>, 8])).
|
|
||||||
|
|
||||||
t_subbits2(_) ->
|
|
||||||
?assertEqual(1, apply_func(subbits, [<<255:8>>, 1, 1])),
|
|
||||||
?assertEqual(3, apply_func(subbits, [<<255:8>>, 1, 2])),
|
|
||||||
?assertEqual(7, apply_func(subbits, [<<255:8>>, 1, 3])),
|
|
||||||
?assertEqual(15, apply_func(subbits, [<<255:8>>, 1, 4])),
|
|
||||||
?assertEqual(31, apply_func(subbits, [<<255:8>>, 1, 5])),
|
|
||||||
?assertEqual(63, apply_func(subbits, [<<255:8>>, 1, 6])),
|
|
||||||
?assertEqual(127, apply_func(subbits, [<<255:8>>, 1, 7])),
|
|
||||||
?assertEqual(255, apply_func(subbits, [<<255:8>>, 1, 8])).
|
|
||||||
|
|
||||||
t_subbits2_1(_) ->
|
|
||||||
?assertEqual(1, apply_func(subbits, [<<255:8>>, 2, 1])),
|
|
||||||
?assertEqual(3, apply_func(subbits, [<<255:8>>, 2, 2])),
|
|
||||||
?assertEqual(7, apply_func(subbits, [<<255:8>>, 2, 3])),
|
|
||||||
?assertEqual(15, apply_func(subbits, [<<255:8>>, 2, 4])),
|
|
||||||
?assertEqual(31, apply_func(subbits, [<<255:8>>, 2, 5])),
|
|
||||||
?assertEqual(63, apply_func(subbits, [<<255:8>>, 2, 6])),
|
|
||||||
?assertEqual(127, apply_func(subbits, [<<255:8>>, 2, 7])),
|
|
||||||
?assertEqual(127, apply_func(subbits, [<<255:8>>, 2, 8])).
|
|
||||||
|
|
||||||
t_subbits2_integer(_) ->
|
|
||||||
?assertEqual(456, apply_func(subbits, [<<456:32/integer>>, 1, 32, <<"integer">>, <<"signed">>, <<"big">>])),
|
|
||||||
?assertEqual(-456, apply_func(subbits, [<<-456:32/integer>>, 1, 32, <<"integer">>, <<"signed">>, <<"big">>])).
|
|
||||||
|
|
||||||
t_subbits2_float(_) ->
|
|
||||||
R = apply_func(subbits, [<<5.3:64/float>>, 1, 64, <<"float">>, <<"unsigned">>, <<"big">>]),
|
|
||||||
RL = (5.3 - R),
|
|
||||||
ct:pal(";;;;~p", [R]),
|
|
||||||
?assert( (RL >= 0 andalso RL < 0.0001) orelse (RL =< 0 andalso RL > -0.0001)),
|
|
||||||
|
|
||||||
R2 = apply_func(subbits, [<<-5.3:64/float>>, 1, 64, <<"float">>, <<"signed">>, <<"big">>]),
|
|
||||||
|
|
||||||
RL2 = (5.3 + R2),
|
|
||||||
ct:pal(";;;;~p", [R2]),
|
|
||||||
?assert( (RL2 >= 0 andalso RL2 < 0.0001) orelse (RL2 =< 0 andalso RL2 > -0.0001)).
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Test cases for Hash funcs
|
%% Test cases for Hash funcs
|
||||||
|
|
|
@ -137,4 +137,4 @@ receive_msg() ->
|
||||||
ct:print("==========+~p~n", [Msg]),
|
ct:print("==========+~p~n", [Msg]),
|
||||||
receive_msg()
|
receive_msg()
|
||||||
after 200 -> ok
|
after 200 -> ok
|
||||||
end.
|
end.
|
|
@ -1,9 +0,0 @@
|
||||||
%% -*-: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -1139,6 +1139,13 @@ listener.tcp.external.send_timeout_close = on
|
||||||
## Value: on | off
|
## Value: on | off
|
||||||
## listener.tcp.external.tune_buffer = off
|
## listener.tcp.external.tune_buffer = off
|
||||||
|
|
||||||
|
## The socket is set to a busy state when the amount of data queued internally
|
||||||
|
## by the ERTS socket implementation reaches this limit.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
## Defaults to 1MB
|
||||||
|
## listener.tcp.external.high_watermark = 1MB
|
||||||
|
|
||||||
## The TCP_NODELAY flag for MQTT connections. Small amounts of data are
|
## The TCP_NODELAY flag for MQTT connections. Small amounts of data are
|
||||||
## sent immediately if the option is enabled.
|
## sent immediately if the option is enabled.
|
||||||
##
|
##
|
||||||
|
@ -1317,6 +1324,11 @@ listener.ssl.external.access.1 = allow all
|
||||||
## Value: Duration
|
## Value: Duration
|
||||||
listener.ssl.external.handshake_timeout = 15s
|
listener.ssl.external.handshake_timeout = 15s
|
||||||
|
|
||||||
|
## Maximum number of non-self-issued intermediate certificates that can follow the peer certificate in a valid certification path.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
#listener.ssl.external.depth = 10
|
||||||
|
|
||||||
## Path to the file containing the user's private PEM-encoded key.
|
## Path to the file containing the user's private PEM-encoded key.
|
||||||
##
|
##
|
||||||
## See: http://erlang.org/doc/man/ssl.html
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
|
|
|
@ -32,7 +32,6 @@ endif
|
||||||
.PHONY: $(PROFILES:%=relup-%)
|
.PHONY: $(PROFILES:%=relup-%)
|
||||||
$(PROFILES:%=relup-%): $(REBAR)
|
$(PROFILES:%=relup-%): $(REBAR)
|
||||||
ifneq ($(OS),Windows_NT)
|
ifneq ($(OS),Windows_NT)
|
||||||
@ln -snf _build/$(@:relup-%=%)/lib
|
|
||||||
@if [ ! -z $$(ls | grep -E "$(@:relup-%=%)-$(SYSTEM)-(.*)-$$(uname -m).zip" | head -1 ) ]; then \
|
@if [ ! -z $$(ls | grep -E "$(@:relup-%=%)-$(SYSTEM)-(.*)-$$(uname -m).zip" | head -1 ) ]; then \
|
||||||
mkdir -p tmp/relup_packages/$(@:relup-%=%); \
|
mkdir -p tmp/relup_packages/$(@:relup-%=%); \
|
||||||
cp $(@:relup-%=%)-$(SYSTEM)-*-$$(uname -m).zip tmp/relup_packages/$(@:relup-%=%); \
|
cp $(@:relup-%=%)-$(SYSTEM)-*-$$(uname -m).zip tmp/relup_packages/$(@:relup-%=%); \
|
||||||
|
@ -42,9 +41,6 @@ endif
|
||||||
|
|
||||||
.PHONY: $(PROFILES:%=%-tar) $(PKG_PROFILES:%=%-tar)
|
.PHONY: $(PROFILES:%=%-tar) $(PKG_PROFILES:%=%-tar)
|
||||||
$(PROFILES:%=%-tar) $(PKG_PROFILES:%=%-tar): $(REBAR)
|
$(PROFILES:%=%-tar) $(PKG_PROFILES:%=%-tar): $(REBAR)
|
||||||
ifneq ($(OS),Windows_NT)
|
|
||||||
@ln -snf _build/$(subst -tar,,$(@))/lib
|
|
||||||
endif
|
|
||||||
ifneq ($(shell echo $(@) |grep edge),)
|
ifneq ($(shell echo $(@) |grep edge),)
|
||||||
export EMQX_DESC="EMQ X Edge"
|
export EMQX_DESC="EMQ X Edge"
|
||||||
else
|
else
|
||||||
|
|
|
@ -1244,6 +1244,11 @@ end}.
|
||||||
hidden
|
hidden
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "listener.tcp.$name.high_watermark", "emqx.listeners", [
|
||||||
|
{datatype, bytesize},
|
||||||
|
{default, "1MB"}
|
||||||
|
]}.
|
||||||
|
|
||||||
{mapping, "listener.tcp.$name.tune_buffer", "emqx.listeners", [
|
{mapping, "listener.tcp.$name.tune_buffer", "emqx.listeners", [
|
||||||
{datatype, flag},
|
{datatype, flag},
|
||||||
hidden
|
hidden
|
||||||
|
@ -1336,6 +1341,11 @@ end}.
|
||||||
hidden
|
hidden
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "listener.ssl.$name.high_watermark", "emqx.listeners", [
|
||||||
|
{datatype, bytesize},
|
||||||
|
{default, "1MB"}
|
||||||
|
]}.
|
||||||
|
|
||||||
{mapping, "listener.ssl.$name.tune_buffer", "emqx.listeners", [
|
{mapping, "listener.ssl.$name.tune_buffer", "emqx.listeners", [
|
||||||
{datatype, flag},
|
{datatype, flag},
|
||||||
hidden
|
hidden
|
||||||
|
@ -1368,6 +1378,11 @@ end}.
|
||||||
{datatype, {duration, ms}}
|
{datatype, {duration, ms}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "listener.ssl.$name.depth", "emqx.listeners", [
|
||||||
|
{default, 10},
|
||||||
|
{datatype, integer}
|
||||||
|
]}.
|
||||||
|
|
||||||
{mapping, "listener.ssl.$name.dhfile", "emqx.listeners", [
|
{mapping, "listener.ssl.$name.dhfile", "emqx.listeners", [
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
@ -1839,6 +1854,7 @@ end}.
|
||||||
{recbuf, cuttlefish:conf_get(Prefix ++ ".recbuf", Conf, undefined)},
|
{recbuf, cuttlefish:conf_get(Prefix ++ ".recbuf", Conf, undefined)},
|
||||||
{sndbuf, cuttlefish:conf_get(Prefix ++ ".sndbuf", Conf, undefined)},
|
{sndbuf, cuttlefish:conf_get(Prefix ++ ".sndbuf", Conf, undefined)},
|
||||||
{buffer, cuttlefish:conf_get(Prefix ++ ".buffer", Conf, undefined)},
|
{buffer, cuttlefish:conf_get(Prefix ++ ".buffer", Conf, undefined)},
|
||||||
|
{high_watermark, cuttlefish:conf_get(Prefix ++ ".high_watermark", Conf, undefined)},
|
||||||
{nodelay, cuttlefish:conf_get(Prefix ++ ".nodelay", Conf, true)},
|
{nodelay, cuttlefish:conf_get(Prefix ++ ".nodelay", Conf, true)},
|
||||||
{reuseaddr, cuttlefish:conf_get(Prefix ++ ".reuseaddr", Conf, undefined)}])
|
{reuseaddr, cuttlefish:conf_get(Prefix ++ ".reuseaddr", Conf, undefined)}])
|
||||||
end,
|
end,
|
||||||
|
@ -1878,6 +1894,7 @@ end}.
|
||||||
{ciphers, Ciphers},
|
{ciphers, Ciphers},
|
||||||
{user_lookup_fun, UserLookupFun},
|
{user_lookup_fun, UserLookupFun},
|
||||||
{handshake_timeout, cuttlefish:conf_get(Prefix ++ ".handshake_timeout", Conf, undefined)},
|
{handshake_timeout, cuttlefish:conf_get(Prefix ++ ".handshake_timeout", Conf, undefined)},
|
||||||
|
{depth, cuttlefish:conf_get(Prefix ++ ".depth", Conf, undefined)},
|
||||||
{dhfile, cuttlefish:conf_get(Prefix ++ ".dhfile", Conf, undefined)},
|
{dhfile, cuttlefish:conf_get(Prefix ++ ".dhfile", Conf, undefined)},
|
||||||
{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
|
{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
|
||||||
{certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
|
{certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
warn_obsolete_guard,compressed]}.
|
warn_obsolete_guard,compressed]}.
|
||||||
|
|
||||||
{overrides,[{add,[{erl_opts,[compressed,deterministic,
|
{overrides,[{add,[{erl_opts,[compressed,deterministic,
|
||||||
{parse_transform,mod_vsn}]}]}]}.
|
{parse_transform,mod_vsn}]}]}
|
||||||
|
,{add,[{extra_src_dirs, [{"etc", [{recursive,true}]}]}]}
|
||||||
|
]}.
|
||||||
|
{extra_src_dirs, [{"etc", [{recursive,true}]}]}.
|
||||||
|
|
||||||
{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
|
{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
|
||||||
deprecated_function_calls,warnings_as_errors, deprecated_functions]}.
|
deprecated_function_calls,warnings_as_errors, deprecated_functions]}.
|
||||||
|
|
|
@ -1,48 +1,9 @@
|
||||||
%% -*-: erlang -*-
|
%% -*-: erlang -*-
|
||||||
{DefaultLen, DefaultSize} =
|
{VSN,
|
||||||
case WordSize = erlang:system_info(wordsize) of
|
[
|
||||||
8 -> % arch_64
|
{<<".*">>, []}
|
||||||
{10000, cuttlefish_bytesize:parse("64MB")};
|
],
|
||||||
4 -> % arch_32
|
[
|
||||||
{1000, cuttlefish_bytesize:parse("32MB")}
|
{<<".*">>, []}
|
||||||
end,
|
]
|
||||||
{"4.2.3",
|
|
||||||
[
|
|
||||||
{"4.2.2", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []}
|
|
||||||
]},
|
|
||||||
{"4.2.1", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_channel, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_mod_topic_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_json, brutal_purge, soft_purge, []}
|
|
||||||
]},
|
|
||||||
{"4.2.0", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_channel, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_mod_topic_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_json, brutal_purge, soft_purge, []},
|
|
||||||
{apply, {application, set_env,
|
|
||||||
[emqx, force_shutdown_policy,
|
|
||||||
#{message_queue_len => DefaultLen,
|
|
||||||
max_heap_size => DefaultSize div WordSize}]}}
|
|
||||||
]}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{"4.2.2", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []}
|
|
||||||
]},
|
|
||||||
{"4.2.1", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_channel, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_mod_topic_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_json, brutal_purge, soft_purge, []}
|
|
||||||
]},
|
|
||||||
{"4.2.0", [
|
|
||||||
{load_module, emqx_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_channel, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_mod_topic_metrics, brutal_purge, soft_purge, []},
|
|
||||||
{load_module, emqx_json, brutal_purge, soft_purge, []}
|
|
||||||
]}
|
|
||||||
]
|
|
||||||
}.
|
}.
|
||||||
|
|
|
@ -359,6 +359,8 @@ normalize_message(partition, #{occurred := Node}) ->
|
||||||
list_to_binary(io_lib:format("Partition occurs at node ~s", [Node]));
|
list_to_binary(io_lib:format("Partition occurs at node ~s", [Node]));
|
||||||
normalize_message(<<"resource", _/binary>>, #{type := Type, id := ID}) ->
|
normalize_message(<<"resource", _/binary>>, #{type := Type, id := ID}) ->
|
||||||
list_to_binary(io_lib:format("Resource ~s(~s) is down", [Type, ID]));
|
list_to_binary(io_lib:format("Resource ~s(~s) is down", [Type, ID]));
|
||||||
|
normalize_message(<<"mqtt_conn/congested/", ClientId/binary>>, _) ->
|
||||||
|
list_to_binary(io_lib:format("MQTT connection for clientid '~s' is congested", [ClientId]));
|
||||||
normalize_message(_Name, _UnknownDetails) ->
|
normalize_message(_Name, _UnknownDetails) ->
|
||||||
<<"Unknown alarm">>.
|
<<"Unknown alarm">>.
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,20 @@ info(zone, #channel{clientinfo = #{zone := Zone}}) ->
|
||||||
Zone;
|
Zone;
|
||||||
info(clientid, #channel{clientinfo = #{clientid := ClientId}}) ->
|
info(clientid, #channel{clientinfo = #{clientid := ClientId}}) ->
|
||||||
ClientId;
|
ClientId;
|
||||||
|
info(username, #channel{clientinfo = #{username := Username}}) ->
|
||||||
|
Username;
|
||||||
|
info(socktype, #channel{conninfo = #{socktype := SockType}}) ->
|
||||||
|
SockType;
|
||||||
|
info(peername, #channel{conninfo = #{peername := Peername}}) ->
|
||||||
|
Peername;
|
||||||
|
info(sockname, #channel{conninfo = #{sockname := Sockname}}) ->
|
||||||
|
Sockname;
|
||||||
|
info(proto_name, #channel{conninfo = #{proto_name := ProtoName}}) ->
|
||||||
|
ProtoName;
|
||||||
|
info(proto_ver, #channel{conninfo = #{proto_ver := ProtoVer}}) ->
|
||||||
|
ProtoVer;
|
||||||
|
info(connected_at, #channel{conninfo = #{connected_at := ConnectedAt}}) ->
|
||||||
|
ConnectedAt;
|
||||||
info(clientinfo, #channel{clientinfo = ClientInfo}) ->
|
info(clientinfo, #channel{clientinfo = ClientInfo}) ->
|
||||||
ClientInfo;
|
ClientInfo;
|
||||||
info(session, #channel{session = Session}) ->
|
info(session, #channel{session = Session}) ->
|
||||||
|
|
|
@ -80,8 +80,8 @@
|
||||||
limit_timer :: maybe(reference()),
|
limit_timer :: maybe(reference()),
|
||||||
%% Parse State
|
%% Parse State
|
||||||
parse_state :: emqx_frame:parse_state(),
|
parse_state :: emqx_frame:parse_state(),
|
||||||
%% Serialize function
|
%% Serialize options
|
||||||
serialize :: emqx_frame:serialize_fun(),
|
serialize :: emqx_frame:serialize_opts(),
|
||||||
%% Channel State
|
%% Channel State
|
||||||
channel :: emqx_channel:channel(),
|
channel :: emqx_channel:channel(),
|
||||||
%% GC State
|
%% GC State
|
||||||
|
@ -103,11 +103,24 @@
|
||||||
|
|
||||||
-define(ENABLED(X), (X =/= undefined)).
|
-define(ENABLED(X), (X =/= undefined)).
|
||||||
|
|
||||||
|
-define(ALARM_TCP_CONGEST(Channel),
|
||||||
|
list_to_binary(io_lib:format("mqtt_conn/congested/~s/~s",
|
||||||
|
[emqx_channel:info(clientid, Channel),
|
||||||
|
emqx_channel:info(username, Channel)]))).
|
||||||
|
|
||||||
|
-define(ALARM_CONN_INFO_KEYS, [
|
||||||
|
socktype, sockname, peername,
|
||||||
|
clientid, username, proto_name, proto_ver, connected_at
|
||||||
|
]).
|
||||||
|
-define(ALARM_SOCK_STATS_KEYS, [send_pend, recv_cnt, recv_oct, send_cnt, send_oct]).
|
||||||
|
-define(ALARM_SOCK_OPTS_KEYS, [high_watermark, high_msgq_watermark, sndbuf, recbuf, buffer]).
|
||||||
|
|
||||||
-dialyzer({no_match, [info/2]}).
|
-dialyzer({no_match, [info/2]}).
|
||||||
-dialyzer({nowarn_function, [ init/4
|
-dialyzer({nowarn_function, [ init/4
|
||||||
, init_state/3
|
, init_state/3
|
||||||
, run_loop/2
|
, run_loop/2
|
||||||
, system_terminate/4
|
, system_terminate/4
|
||||||
|
, system_code_change/4
|
||||||
]}).
|
]}).
|
||||||
|
|
||||||
-spec(start_link(esockd:transport(), esockd:socket(), proplists:proplist())
|
-spec(start_link(esockd:transport(), esockd:socket(), proplists:proplist())
|
||||||
|
@ -203,7 +216,7 @@ init_state(Transport, Socket, Options) ->
|
||||||
Limiter = emqx_limiter:init(Zone, PubLimit, BytesIn, RateLimit),
|
Limiter = emqx_limiter:init(Zone, PubLimit, BytesIn, RateLimit),
|
||||||
FrameOpts = emqx_zone:mqtt_frame_options(Zone),
|
FrameOpts = emqx_zone:mqtt_frame_options(Zone),
|
||||||
ParseState = emqx_frame:initial_parse_state(FrameOpts),
|
ParseState = emqx_frame:initial_parse_state(FrameOpts),
|
||||||
Serialize = emqx_frame:serialize_fun(),
|
Serialize = emqx_frame:serialize_opts(),
|
||||||
Channel = emqx_channel:init(ConnInfo, Options),
|
Channel = emqx_channel:init(ConnInfo, Options),
|
||||||
GcState = emqx_zone:init_gc_state(Zone),
|
GcState = emqx_zone:init_gc_state(Zone),
|
||||||
StatsTimer = emqx_zone:stats_timer(Zone),
|
StatsTimer = emqx_zone:stats_timer(Zone),
|
||||||
|
@ -338,7 +351,7 @@ handle_msg({Inet, _Sock, Data}, State) when Inet == tcp; Inet == ssl ->
|
||||||
handle_msg({incoming, Packet = ?CONNECT_PACKET(ConnPkt)},
|
handle_msg({incoming, Packet = ?CONNECT_PACKET(ConnPkt)},
|
||||||
State = #state{idle_timer = IdleTimer}) ->
|
State = #state{idle_timer = IdleTimer}) ->
|
||||||
ok = emqx_misc:cancel_timer(IdleTimer),
|
ok = emqx_misc:cancel_timer(IdleTimer),
|
||||||
Serialize = emqx_frame:serialize_fun(ConnPkt),
|
Serialize = emqx_frame:serialize_opts(ConnPkt),
|
||||||
NState = State#state{serialize = Serialize,
|
NState = State#state{serialize = Serialize,
|
||||||
idle_timer = undefined
|
idle_timer = undefined
|
||||||
},
|
},
|
||||||
|
@ -430,6 +443,7 @@ handle_msg(Msg, State) ->
|
||||||
-spec terminate(any(), state()) -> no_return().
|
-spec terminate(any(), state()) -> no_return().
|
||||||
terminate(Reason, State = #state{channel = Channel}) ->
|
terminate(Reason, State = #state{channel = Channel}) ->
|
||||||
?LOG(debug, "Terminated due to ~p", [Reason]),
|
?LOG(debug, "Terminated due to ~p", [Reason]),
|
||||||
|
emqx_alarm:deactivate(?ALARM_TCP_CONGEST(Channel)),
|
||||||
emqx_channel:terminate(Reason, Channel),
|
emqx_channel:terminate(Reason, Channel),
|
||||||
_ = close_socket(State),
|
_ = close_socket(State),
|
||||||
exit(Reason).
|
exit(Reason).
|
||||||
|
@ -580,7 +594,7 @@ handle_outgoing(Packet, State) ->
|
||||||
|
|
||||||
serialize_and_inc_stats_fun(#state{serialize = Serialize}) ->
|
serialize_and_inc_stats_fun(#state{serialize = Serialize}) ->
|
||||||
fun(Packet) ->
|
fun(Packet) ->
|
||||||
case Serialize(Packet) of
|
case emqx_frame:serialize_pkt(Packet, Serialize) of
|
||||||
<<>> -> ?LOG(warning, "~s is discarded due to the frame is too large!",
|
<<>> -> ?LOG(warning, "~s is discarded due to the frame is too large!",
|
||||||
[emqx_packet:format(Packet)]),
|
[emqx_packet:format(Packet)]),
|
||||||
ok = emqx_metrics:inc('delivery.dropped.too_large'),
|
ok = emqx_metrics:inc('delivery.dropped.too_large'),
|
||||||
|
@ -596,11 +610,12 @@ serialize_and_inc_stats_fun(#state{serialize = Serialize}) ->
|
||||||
%% Send data
|
%% Send data
|
||||||
|
|
||||||
-spec(send(iodata(), state()) -> ok).
|
-spec(send(iodata(), state()) -> ok).
|
||||||
send(IoData, #state{transport = Transport, socket = Socket}) ->
|
send(IoData, #state{transport = Transport, socket = Socket, channel = Channel}) ->
|
||||||
Oct = iolist_size(IoData),
|
Oct = iolist_size(IoData),
|
||||||
ok = emqx_metrics:inc('bytes.sent', Oct),
|
ok = emqx_metrics:inc('bytes.sent', Oct),
|
||||||
inc_counter(outgoing_bytes, Oct),
|
inc_counter(outgoing_bytes, Oct),
|
||||||
case Transport:async_send(Socket, IoData) of
|
maybe_warn_congestion(Socket, Transport, Channel),
|
||||||
|
case Transport:async_send(Socket, IoData, [nosuspend]) of
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
Error = {error, _Reason} ->
|
Error = {error, _Reason} ->
|
||||||
%% Send an inet_reply to postpone handling the error
|
%% Send an inet_reply to postpone handling the error
|
||||||
|
@ -608,6 +623,48 @@ send(IoData, #state{transport = Transport, socket = Socket}) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
maybe_warn_congestion(Socket, Transport, Channel) ->
|
||||||
|
IsCongestAlarmSet = is_congestion_alarm_set(),
|
||||||
|
case is_congested(Socket, Transport) of
|
||||||
|
true when not IsCongestAlarmSet ->
|
||||||
|
ok = set_congestion_alarm(),
|
||||||
|
emqx_alarm:activate(?ALARM_TCP_CONGEST(Channel),
|
||||||
|
tcp_congestion_alarm_details(Socket, Transport, Channel));
|
||||||
|
false when IsCongestAlarmSet ->
|
||||||
|
ok = clear_congestion_alarm(),
|
||||||
|
emqx_alarm:deactivate(?ALARM_TCP_CONGEST(Channel));
|
||||||
|
_ -> ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_congested(Socket, Transport) ->
|
||||||
|
case Transport:getstat(Socket, [send_pend]) of
|
||||||
|
{ok, [{send_pend, N}]} when N > 0 -> true;
|
||||||
|
_ -> false
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_congestion_alarm_set() ->
|
||||||
|
case erlang:get(conn_congested) of
|
||||||
|
true -> true;
|
||||||
|
_ -> false
|
||||||
|
end.
|
||||||
|
set_congestion_alarm() ->
|
||||||
|
erlang:put(conn_congested, true), ok.
|
||||||
|
clear_congestion_alarm() ->
|
||||||
|
erlang:put(conn_congested, false), ok.
|
||||||
|
|
||||||
|
tcp_congestion_alarm_details(Socket, Transport, Channel) ->
|
||||||
|
{ok, Stat} = Transport:getstat(Socket, ?ALARM_SOCK_STATS_KEYS),
|
||||||
|
{ok, Opts} = Transport:getopts(Socket, ?ALARM_SOCK_OPTS_KEYS),
|
||||||
|
SockInfo = maps:from_list(Stat ++ Opts),
|
||||||
|
ConnInfo = maps:from_list([conn_info(Key, Channel) || Key <- ?ALARM_CONN_INFO_KEYS]),
|
||||||
|
maps:merge(ConnInfo, SockInfo).
|
||||||
|
|
||||||
|
conn_info(Key, Channel) when Key =:= sockname; Key =:= peername ->
|
||||||
|
{IPStr, Port} = emqx_channel:info(Key, Channel),
|
||||||
|
{Key, iolist_to_binary([inet:ntoa(IPStr),":",integer_to_list(Port)])};
|
||||||
|
conn_info(Key, Channel) ->
|
||||||
|
{Key, emqx_channel:info(Key, Channel)}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Handle Info
|
%% Handle Info
|
||||||
|
|
||||||
|
@ -623,7 +680,7 @@ handle_info(activate_socket, State = #state{sockstate = OldSst}) ->
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_info({sock_error, Reason}, State) ->
|
handle_info({sock_error, Reason}, State) ->
|
||||||
?LOG(debug, "Socket error: ~p", [Reason]),
|
Reason =/= closed andalso ?LOG(error, "Socket error: ~p", [Reason]),
|
||||||
handle_info({sock_closed, Reason}, close_socket(State));
|
handle_info({sock_closed, Reason}, close_socket(State));
|
||||||
|
|
||||||
handle_info(Info, State) ->
|
handle_info(Info, State) ->
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
, parse/2
|
, parse/2
|
||||||
, serialize_fun/0
|
, serialize_fun/0
|
||||||
, serialize_fun/1
|
, serialize_fun/1
|
||||||
|
, serialize_opts/0
|
||||||
|
, serialize_opts/1
|
||||||
|
, serialize_pkt/2
|
||||||
, serialize/1
|
, serialize/1
|
||||||
, serialize/2
|
, serialize/2
|
||||||
]).
|
]).
|
||||||
|
@ -34,7 +37,7 @@
|
||||||
-export_type([ options/0
|
-export_type([ options/0
|
||||||
, parse_state/0
|
, parse_state/0
|
||||||
, parse_result/0
|
, parse_result/0
|
||||||
, serialize_fun/0
|
, serialize_opts/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-type(options() :: #{strict_mode => boolean(),
|
-type(options() :: #{strict_mode => boolean(),
|
||||||
|
@ -42,14 +45,19 @@
|
||||||
version => emqx_types:version()
|
version => emqx_types:version()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-type(parse_state() :: {none, options()} | cont_fun()).
|
-type(parse_state() :: {none, options()} | {cont_state(), options()}).
|
||||||
|
|
||||||
-type(parse_result() :: {more, cont_fun()}
|
-type(parse_result() :: {more, parse_state()}
|
||||||
| {ok, emqx_types:packet(), binary(), parse_state()}).
|
| {ok, emqx_types:packet(), binary(), parse_state()}).
|
||||||
|
|
||||||
-type(cont_fun() :: fun((binary()) -> parse_result())).
|
-type(cont_state() :: {Stage :: len | body,
|
||||||
|
State :: #{hdr := #mqtt_packet_header{},
|
||||||
|
len := {pos_integer(), non_neg_integer()} | non_neg_integer(),
|
||||||
|
rest => binary()
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
|
||||||
-type(serialize_fun() :: fun((emqx_types:packet()) -> iodata())).
|
-type(serialize_opts() :: options()).
|
||||||
|
|
||||||
-define(none(Options), {none, Options}).
|
-define(none(Options), {none, Options}).
|
||||||
|
|
||||||
|
@ -87,7 +95,7 @@ parse(Bin) ->
|
||||||
|
|
||||||
-spec(parse(binary(), parse_state()) -> parse_result()).
|
-spec(parse(binary(), parse_state()) -> parse_result()).
|
||||||
parse(<<>>, {none, Options}) ->
|
parse(<<>>, {none, Options}) ->
|
||||||
{more, fun(Bin) -> parse(Bin, {none, Options}) end};
|
{more, {none, Options}};
|
||||||
parse(<<Type:4, Dup:1, QoS:2, Retain:1, Rest/binary>>,
|
parse(<<Type:4, Dup:1, QoS:2, Retain:1, Rest/binary>>,
|
||||||
{none, Options = #{strict_mode := StrictMode}}) ->
|
{none, Options = #{strict_mode := StrictMode}}) ->
|
||||||
%% Validate header if strict mode.
|
%% Validate header if strict mode.
|
||||||
|
@ -102,11 +110,19 @@ parse(<<Type:4, Dup:1, QoS:2, Retain:1, Rest/binary>>,
|
||||||
FixedQoS -> Header#mqtt_packet_header{qos = FixedQoS}
|
FixedQoS -> Header#mqtt_packet_header{qos = FixedQoS}
|
||||||
end,
|
end,
|
||||||
parse_remaining_len(Rest, Header1, Options);
|
parse_remaining_len(Rest, Header1, Options);
|
||||||
parse(Bin, Cont) when is_binary(Bin), is_function(Cont) ->
|
|
||||||
Cont(Bin).
|
parse(Bin, {{len, #{hdr := Header,
|
||||||
|
len := {Multiplier, Length}}
|
||||||
|
}, Options}) when is_binary(Bin) ->
|
||||||
|
parse_remaining_len(Bin, Header, Multiplier, Length, Options);
|
||||||
|
parse(Bin, {{body, #{hdr := Header,
|
||||||
|
len := Length,
|
||||||
|
rest := Rest}
|
||||||
|
}, Options}) when is_binary(Bin) ->
|
||||||
|
parse_frame(<<Rest/binary, Bin/binary>>, Header, Length, Options).
|
||||||
|
|
||||||
parse_remaining_len(<<>>, Header, Options) ->
|
parse_remaining_len(<<>>, Header, Options) ->
|
||||||
{more, fun(Bin) -> parse_remaining_len(Bin, Header, Options) end};
|
{more, {{len, #{hdr => Header, len => {1, 0}}}, Options}};
|
||||||
parse_remaining_len(Rest, Header, Options) ->
|
parse_remaining_len(Rest, Header, Options) ->
|
||||||
parse_remaining_len(Rest, Header, 1, 0, Options).
|
parse_remaining_len(Rest, Header, 1, 0, Options).
|
||||||
|
|
||||||
|
@ -114,7 +130,7 @@ parse_remaining_len(_Bin, _Header, _Multiplier, Length, #{max_size := MaxSize})
|
||||||
when Length > MaxSize ->
|
when Length > MaxSize ->
|
||||||
error(frame_too_large);
|
error(frame_too_large);
|
||||||
parse_remaining_len(<<>>, Header, Multiplier, Length, Options) ->
|
parse_remaining_len(<<>>, Header, Multiplier, Length, Options) ->
|
||||||
{more, fun(Bin) -> parse_remaining_len(Bin, Header, Multiplier, Length, Options) end};
|
{more, {{len, #{hdr => Header, len => {Multiplier, Length}}}, Options}};
|
||||||
%% Match DISCONNECT without payload
|
%% Match DISCONNECT without payload
|
||||||
parse_remaining_len(<<0:8, Rest/binary>>, Header = #mqtt_packet_header{type = ?DISCONNECT}, 1, 0, Options) ->
|
parse_remaining_len(<<0:8, Rest/binary>>, Header = #mqtt_packet_header{type = ?DISCONNECT}, 1, 0, Options) ->
|
||||||
Packet = packet(Header, #mqtt_packet_disconnect{reason_code = ?RC_SUCCESS}),
|
Packet = packet(Header, #mqtt_packet_disconnect{reason_code = ?RC_SUCCESS}),
|
||||||
|
@ -150,9 +166,7 @@ parse_frame(Bin, Header, Length, Options) ->
|
||||||
{ok, packet(Header, Variable), Rest, ?none(Options)}
|
{ok, packet(Header, Variable), Rest, ?none(Options)}
|
||||||
end;
|
end;
|
||||||
TooShortBin ->
|
TooShortBin ->
|
||||||
{more, fun(BinMore) ->
|
{more, {{body, #{hdr => Header, len => Length, rest => TooShortBin}}, Options}}
|
||||||
parse_frame(<<TooShortBin/binary, BinMore/binary>>, Header, Length, Options)
|
|
||||||
end}
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-compile({inline, [packet/1, packet/2, packet/3]}).
|
-compile({inline, [packet/1, packet/2, packet/3]}).
|
||||||
|
@ -443,6 +457,20 @@ serialize_fun(#{version := Ver, max_size := MaxSize}) ->
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
serialize_opts() ->
|
||||||
|
?DEFAULT_OPTIONS.
|
||||||
|
|
||||||
|
serialize_opts(#mqtt_packet_connect{proto_ver = ProtoVer, properties = ConnProps}) ->
|
||||||
|
MaxSize = get_property('Maximum-Packet-Size', ConnProps, ?MAX_PACKET_SIZE),
|
||||||
|
#{version => ProtoVer, max_size => MaxSize}.
|
||||||
|
|
||||||
|
serialize_pkt(Packet, #{version := Ver, max_size := MaxSize}) ->
|
||||||
|
IoData = serialize(Packet, Ver),
|
||||||
|
case is_too_large(IoData, MaxSize) of
|
||||||
|
true -> <<>>;
|
||||||
|
false -> IoData
|
||||||
|
end.
|
||||||
|
|
||||||
-spec(serialize(emqx_types:packet()) -> iodata()).
|
-spec(serialize(emqx_types:packet()) -> iodata()).
|
||||||
serialize(Packet) -> serialize(Packet, ?MQTT_PROTO_V4).
|
serialize(Packet) -> serialize(Packet, ?MQTT_PROTO_V4).
|
||||||
|
|
||||||
|
@ -746,4 +774,3 @@ fixqos(?PUBREL, 0) -> 1;
|
||||||
fixqos(?SUBSCRIBE, 0) -> 1;
|
fixqos(?SUBSCRIBE, 0) -> 1;
|
||||||
fixqos(?UNSUBSCRIBE, 0) -> 1;
|
fixqos(?UNSUBSCRIBE, 0) -> 1;
|
||||||
fixqos(_Type, QoS) -> QoS.
|
fixqos(_Type, QoS) -> QoS.
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
-type(checker() :: #{ name := name()
|
-type(checker() :: #{ name := name()
|
||||||
, capacity := non_neg_integer()
|
, capacity := non_neg_integer()
|
||||||
, interval := non_neg_integer()
|
, interval := non_neg_integer()
|
||||||
, consumer := function() | esockd_rate_limit:bucket()
|
, consumer := esockd_rate_limit:bucket() | emqx_zone:zone()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-type(name() :: conn_bytes_in
|
-type(name() :: conn_bytes_in
|
||||||
|
@ -53,6 +53,8 @@
|
||||||
|
|
||||||
-type(limiter() :: #limiter{}).
|
-type(limiter() :: #limiter{}).
|
||||||
|
|
||||||
|
-dialyzer({nowarn_function, [consume/3]}).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% APIs
|
%% APIs
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -84,7 +86,7 @@ do_init_checker(Zone, {Name, {Capacity, Interval}}) ->
|
||||||
_ ->
|
_ ->
|
||||||
esockd_limiter:create({Zone, Name}, Capacity, Interval)
|
esockd_limiter:create({Zone, Name}, Capacity, Interval)
|
||||||
end,
|
end,
|
||||||
Ck#{consumer => fun(I) -> esockd_limiter:consume({Zone, Name}, I) end};
|
Ck#{consumer => Zone};
|
||||||
_ ->
|
_ ->
|
||||||
Ck#{consumer => esockd_rate_limit:new(Capacity / Interval, Capacity)}
|
Ck#{consumer => esockd_rate_limit:new(Capacity / Interval, Capacity)}
|
||||||
end.
|
end.
|
||||||
|
@ -126,7 +128,7 @@ consume(Pubs, Bytes, #{name := Name, consumer := Cons}) ->
|
||||||
_ ->
|
_ ->
|
||||||
case is_overall_limiter(Name) of
|
case is_overall_limiter(Name) of
|
||||||
true ->
|
true ->
|
||||||
{_, Intv} = Cons(Tokens),
|
{_, Intv} = esockd_limiter:consume({Cons, Name}, Tokens),
|
||||||
{Intv, Cons};
|
{Intv, Cons};
|
||||||
_ ->
|
_ ->
|
||||||
esockd_rate_limit:check(Tokens, Cons)
|
esockd_rate_limit:check(Tokens, Cons)
|
||||||
|
|
|
@ -70,8 +70,8 @@
|
||||||
limit_timer :: maybe(reference()),
|
limit_timer :: maybe(reference()),
|
||||||
%% Parse State
|
%% Parse State
|
||||||
parse_state :: emqx_frame:parse_state(),
|
parse_state :: emqx_frame:parse_state(),
|
||||||
%% Serialize Fun
|
%% Serialize options
|
||||||
serialize :: emqx_frame:serialize_fun(),
|
serialize :: emqx_frame:serialize_opts(),
|
||||||
%% Channel
|
%% Channel
|
||||||
channel :: emqx_channel:channel(),
|
channel :: emqx_channel:channel(),
|
||||||
%% GC State
|
%% GC State
|
||||||
|
@ -231,7 +231,7 @@ websocket_init([Req, Opts]) ->
|
||||||
MQTTPiggyback = proplists:get_value(mqtt_piggyback, Opts, multiple),
|
MQTTPiggyback = proplists:get_value(mqtt_piggyback, Opts, multiple),
|
||||||
FrameOpts = emqx_zone:mqtt_frame_options(Zone),
|
FrameOpts = emqx_zone:mqtt_frame_options(Zone),
|
||||||
ParseState = emqx_frame:initial_parse_state(FrameOpts),
|
ParseState = emqx_frame:initial_parse_state(FrameOpts),
|
||||||
Serialize = emqx_frame:serialize_fun(),
|
Serialize = emqx_frame:serialize_opts(),
|
||||||
Channel = emqx_channel:init(ConnInfo, Opts),
|
Channel = emqx_channel:init(ConnInfo, Opts),
|
||||||
GcState = emqx_zone:init_gc_state(Zone),
|
GcState = emqx_zone:init_gc_state(Zone),
|
||||||
StatsTimer = emqx_zone:stats_timer(Zone),
|
StatsTimer = emqx_zone:stats_timer(Zone),
|
||||||
|
@ -292,7 +292,7 @@ websocket_info({cast, Msg}, State) ->
|
||||||
handle_info(Msg, State);
|
handle_info(Msg, State);
|
||||||
|
|
||||||
websocket_info({incoming, Packet = ?CONNECT_PACKET(ConnPkt)}, State) ->
|
websocket_info({incoming, Packet = ?CONNECT_PACKET(ConnPkt)}, State) ->
|
||||||
Serialize = emqx_frame:serialize_fun(ConnPkt),
|
Serialize = emqx_frame:serialize_opts(ConnPkt),
|
||||||
NState = State#state{serialize = Serialize},
|
NState = State#state{serialize = Serialize},
|
||||||
handle_incoming(Packet, cancel_idle_timer(NState));
|
handle_incoming(Packet, cancel_idle_timer(NState));
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ handle_outgoing(Packets, State = #state{active_n = ActiveN, mqtt_piggyback = MQT
|
||||||
|
|
||||||
serialize_and_inc_stats_fun(#state{serialize = Serialize}) ->
|
serialize_and_inc_stats_fun(#state{serialize = Serialize}) ->
|
||||||
fun(Packet) ->
|
fun(Packet) ->
|
||||||
case Serialize(Packet) of
|
case emqx_frame:serialize_pkt(Packet, Serialize) of
|
||||||
<<>> -> ?LOG(warning, "~s is discarded due to the frame is too large.",
|
<<>> -> ?LOG(warning, "~s is discarded due to the frame is too large.",
|
||||||
[emqx_packet:format(Packet)]),
|
[emqx_packet:format(Packet)]),
|
||||||
ok = emqx_metrics:inc('delivery.dropped.too_large'),
|
ok = emqx_metrics:inc('delivery.dropped.too_large'),
|
||||||
|
|
|
@ -85,10 +85,11 @@ done
|
||||||
cleanup_app(){
|
cleanup_app(){
|
||||||
local app="$1"
|
local app="$1"
|
||||||
pushd "apps/$app"
|
pushd "apps/$app"
|
||||||
rm -f Makefile rebar.config.script
|
rm -f Makefile rebar.config.script LICENSE src/*.app.src.script src/*.appup.src
|
||||||
rm -rf ".github" ".ci"
|
rm -rf ".github"
|
||||||
rm -rf src/*.app.src.script
|
# restore rebar.config and app.src
|
||||||
rm -rf src/*.appup.src
|
git checkout rebar.config
|
||||||
|
git checkout src/*.app.src
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
-import(lists, [nth/2]).
|
-import(lists, [nth/2]).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(CM, emqx_cm).
|
-define(CM, emqx_cm).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
@ -52,6 +52,9 @@ init_per_suite(Config) ->
|
||||||
|
|
||||||
ok = meck:expect(emqx_channel, ensure_disconnected, fun(_, Channel) -> Channel end),
|
ok = meck:expect(emqx_channel, ensure_disconnected, fun(_, Channel) -> Channel end),
|
||||||
|
|
||||||
|
ok = meck:expect(emqx_alarm, activate, fun(_, _) -> ok end),
|
||||||
|
ok = meck:expect(emqx_alarm, deactivate, fun(_) -> ok end),
|
||||||
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
|
@ -62,6 +65,7 @@ end_per_suite(_Config) ->
|
||||||
ok = meck:unload(emqx_pd),
|
ok = meck:unload(emqx_pd),
|
||||||
ok = meck:unload(emqx_metrics),
|
ok = meck:unload(emqx_metrics),
|
||||||
ok = meck:unload(emqx_hooks),
|
ok = meck:unload(emqx_hooks),
|
||||||
|
ok = meck:unload(emqx_alarm),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
|
@ -77,6 +81,7 @@ init_per_testcase(_TestCase, Config) ->
|
||||||
{ok, [{K, 0} || K <- Options]}
|
{ok, [{K, 0} || K <- Options]}
|
||||||
end),
|
end),
|
||||||
ok = meck:expect(emqx_transport, async_send, fun(_Sock, _Data) -> ok end),
|
ok = meck:expect(emqx_transport, async_send, fun(_Sock, _Data) -> ok end),
|
||||||
|
ok = meck:expect(emqx_transport, async_send, fun(_Sock, _Data, _Opts) -> ok end),
|
||||||
ok = meck:expect(emqx_transport, fast_close, fun(_Sock) -> ok end),
|
ok = meck:expect(emqx_transport, fast_close, fun(_Sock) -> ok end),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("emqx_ct_helpers/include/emqx_ct.hrl").
|
-include_lib("emqx_ct_helpers/include/emqx_ct.hrl").
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Setups
|
%% Setups
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(RULES, [{rewrite, pub, <<"x/#">>,<<"^x/y/(.+)$">>,<<"z/y/$1">>},
|
-define(RULES, [{rewrite, pub, <<"x/#">>,<<"^x/y/(.+)$">>,<<"z/y/$1">>},
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
, replvar/2
|
, replvar/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("emqx_ct_helpers/include/emqx_ct.hrl").
|
-include_lib("emqx_ct_helpers/include/emqx_ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-export([start_link/4, stop/1]).
|
-export([start_link/4, stop/1]).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
|
|
||||||
-type qos() :: emqx_mqtt_types:qos_name() | emqx_mqtt_types:qos().
|
-type qos() :: emqx_mqtt_types:qos_name() | emqx_mqtt_types:qos().
|
||||||
-type topic() :: emqx_topic:topic().
|
-type topic() :: emqx_topic:topic().
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
-export([start_link/3, stop/1, send/6]).
|
-export([start_link/3, stop/1, send/6]).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
|
|
||||||
start_link(ResponseTopic, QoS, Options0) ->
|
start_link(ResponseTopic, QoS, Options0) ->
|
||||||
Parent = self(),
|
Parent = self(),
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(R, emqx_router).
|
-define(R, emqx_router).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(SYSMON, emqx_sys_mon).
|
-define(SYSMON, emqx_sys_mon).
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(TRIE, emqx_trie).
|
-define(TRIE, emqx_trie).
|
||||||
|
|
|
@ -80,7 +80,7 @@ t_get_port_info(_Config) ->
|
||||||
{ok, Sock} = gen_tcp:connect("localhost", 5678, [binary, {packet, 0}]),
|
{ok, Sock} = gen_tcp:connect("localhost", 5678, [binary, {packet, 0}]),
|
||||||
emqx_vm:get_port_info(),
|
emqx_vm:get_port_info(),
|
||||||
ok = gen_tcp:close(Sock),
|
ok = gen_tcp:close(Sock),
|
||||||
[Port | _] = erlang:ports().
|
[_Port | _] = erlang:ports().
|
||||||
|
|
||||||
t_transform_port(_Config) ->
|
t_transform_port(_Config) ->
|
||||||
[Port | _] = erlang:ports(),
|
[Port | _] = erlang:ports(),
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
-module(emqx_ws_connection_SUITE).
|
-module(emqx_ws_connection_SUITE).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include("emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-import(lists, [nth/2]).
|
-import(lists, [nth/2]).
|
||||||
|
@ -348,16 +348,19 @@ t_connect_will_delay_interval(_) ->
|
||||||
{will_topic, Topic},
|
{will_topic, Topic},
|
||||||
{will_payload, Payload},
|
{will_payload, Payload},
|
||||||
{will_props, #{'Will-Delay-Interval' => 3}},
|
{will_props, #{'Will-Delay-Interval' => 3}},
|
||||||
{properties, #{'Session-Expiry-Interval' => 7200}},
|
{properties, #{'Session-Expiry-Interval' => 7200}}
|
||||||
{keepalive, 2}
|
|
||||||
]),
|
]),
|
||||||
{ok, _} = emqtt:connect(Client2),
|
{ok, _} = emqtt:connect(Client2),
|
||||||
|
%% terminate the client without sending the DISCONNECT
|
||||||
timer:sleep(5000),
|
emqtt:stop(Client2),
|
||||||
|
%% should not get the will msg in 2.5s
|
||||||
|
timer:sleep(1500),
|
||||||
?assertEqual(0, length(receive_messages(1))),
|
?assertEqual(0, length(receive_messages(1))),
|
||||||
timer:sleep(7000),
|
%% should get the will msg in 4.5s
|
||||||
|
timer:sleep(1000),
|
||||||
?assertEqual(1, length(receive_messages(1))),
|
?assertEqual(1, length(receive_messages(1))),
|
||||||
|
|
||||||
|
%% try again, but let the session expire quickly
|
||||||
{ok, Client3} = emqtt:start_link([
|
{ok, Client3} = emqtt:start_link([
|
||||||
{clientid, <<"t_connect_will_delay_interval">>},
|
{clientid, <<"t_connect_will_delay_interval">>},
|
||||||
{proto_ver, v5},
|
{proto_ver, v5},
|
||||||
|
@ -367,14 +370,16 @@ t_connect_will_delay_interval(_) ->
|
||||||
{will_topic, Topic},
|
{will_topic, Topic},
|
||||||
{will_payload, Payload},
|
{will_payload, Payload},
|
||||||
{will_props, #{'Will-Delay-Interval' => 7200}},
|
{will_props, #{'Will-Delay-Interval' => 7200}},
|
||||||
{properties, #{'Session-Expiry-Interval' => 3}},
|
{properties, #{'Session-Expiry-Interval' => 3}}
|
||||||
{keepalive, 2}
|
|
||||||
]),
|
]),
|
||||||
{ok, _} = emqtt:connect(Client3),
|
{ok, _} = emqtt:connect(Client3),
|
||||||
|
%% terminate the client without sending the DISCONNECT
|
||||||
timer:sleep(5000),
|
emqtt:stop(Client3),
|
||||||
|
%% should not get the will msg in 2.5s
|
||||||
|
timer:sleep(1500),
|
||||||
?assertEqual(0, length(receive_messages(1))),
|
?assertEqual(0, length(receive_messages(1))),
|
||||||
timer:sleep(7000),
|
%% should get the will msg in 4.5s
|
||||||
|
timer:sleep(1000),
|
||||||
?assertEqual(1, length(receive_messages(1))),
|
?assertEqual(1, length(receive_messages(1))),
|
||||||
|
|
||||||
ok = emqtt:disconnect(Client1),
|
ok = emqtt:disconnect(Client1),
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
-module(prop_emqx_frame).
|
-module(prop_emqx_frame).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("proper/include/proper.hrl").
|
-include_lib("proper/include/proper.hrl").
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
-module(prop_emqx_reason_codes).
|
-module(prop_emqx_reason_codes).
|
||||||
|
|
||||||
-include("emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("proper/include/proper.hrl").
|
-include_lib("proper/include/proper.hrl").
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue