Merge remote-tracking branch 'origin/master' into merge-master-to-dev/v5.0

This commit is contained in:
Zaiming Shi 2021-04-30 15:09:31 +02:00
commit d904a1048b
491 changed files with 4724 additions and 2924 deletions

View File

@ -1,4 +1,4 @@
ARG BUILD_FROM=emqx/build-env:erl23.2.7-ubuntu20.04
ARG BUILD_FROM=emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
FROM ${BUILD_FROM}
ARG EMQX_NAME=emqx

View File

@ -3,3 +3,6 @@ REDIS_TAG=6
MONGO_TAG=4
PGSQL_TAG=13
LDAP_TAG=2.4.50
TARGET=emqx/emqx
EMQX_TAG=build-alpine-amd64

View File

@ -0,0 +1,6 @@
EMQX_NAME=emqx
EMQX_CLUSTER__DISCOVERY=static
EMQX_CLUSTER__STATIC__SEEDS="emqx@node1.emqx.io, emqx@node2.emqx.io"
EMQX_LISTENER__TCP__EXTERNAL__PROXY_PROTOCOL=on
EMQX_LISTENER__WS__EXTERNAL__PROXY_PROTOCOL=on
EMQX_LOG__LEVEL=debug

View File

@ -1,17 +1,38 @@
version: '3'
version: '3.9'
services:
haproxy:
container_name: haproxy
image: haproxy:2.3
depends_on:
- emqx1
- emqx2
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
- ../../etc/certs:/usr/local/etc/haproxy/certs
ports:
- "18083:18083"
# - "1883:1883"
# - "8883:8883"
# - "8083:8083"
# - "8084:8084"
networks:
- emqx_bridge
working_dir: /usr/local/etc/haproxy
command:
- bash
- -c
- |
cat /usr/local/etc/haproxy/certs/cert.pem /usr/local/etc/haproxy/certs/key.pem > /usr/local/etc/haproxy/certs/emqx.pem
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
emqx1:
container_name: node1.emqx.io
image: ${TARGET}:build-alpine-amd64
image: $TARGET:$EMQX_TAG
env_file:
- conf.cluster.env
environment:
- "EMQX_NAME=emqx"
- "EMQX_HOST=node1.emqx.io"
- "EMQX_CLUSTER__DISCOVERY=static"
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
- "EMQX_ZONE__EXTERNAL__RETRY_INTERVAL=2s"
- "EMQX_MQTT__MAX_TOPIC_ALIAS=10"
- "EMQX_LOG__LEVEL=debug"
- "EMQX_HOST=node1.emqx.io"
command:
- /bin/sh
- -c
@ -25,21 +46,17 @@ services:
timeout: 25s
retries: 5
networks:
emqx-bridge:
emqx_bridge:
aliases:
- node1.emqx.io
emqx2:
container_name: node2.emqx.io
image: ${TARGET}:build-alpine-amd64
image: $TARGET:$EMQX_TAG
env_file:
- conf.cluster.env
environment:
- "EMQX_NAME=emqx"
- "EMQX_HOST=node2.emqx.io"
- "EMQX_CLUSTER__DISCOVERY=static"
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
- "EMQX_ZONE__EXTERNAL__RETRY_INTERVAL=2s"
- "EMQX_MQTT__MAX_TOPIC_ALIAS=10"
- "EMQX_LOG__LEVEL=debug"
- "EMQX_HOST=node2.emqx.io"
command:
- /bin/sh
- -c
@ -53,22 +70,16 @@ services:
timeout: 25s
retries: 5
networks:
emqx-bridge:
emqx_bridge:
aliases:
- node2.emqx.io
client:
container_name: paho_client
image: python:3.7.2-alpine3.9
depends_on:
- emqx1
- emqx2
tty: true
networks:
emqx-bridge:
volumes:
- ./scripts:/scripts
networks:
emqx-bridge:
emqx_bridge:
driver: bridge
name: emqx_bridge
ipam:
driver: default
config:
- subnet: 172.100.239.0/24
gateway: 172.100.239.1

View File

@ -0,0 +1,15 @@
version: '3.9'
services:
python:
container_name: python
image: python:3.7.2-alpine3.9
depends_on:
- emqx1
- emqx2
tty: true
networks:
emqx_bridge:
volumes:
- ./python:/scripts

View File

@ -3,7 +3,7 @@ version: '3.9'
services:
erlang:
container_name: erlang
image: emqx/build-env:erl23.2.7-ubuntu20.04
image: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
env_file:
- conf.env
environment:

View File

@ -0,0 +1,109 @@
##----------------------------------------------------------------
## global 2021/04/05
##----------------------------------------------------------------
global
log stdout format raw daemon debug
# Replace 1024000 with deployment connections
maxconn 1000
nbproc 1
nbthread 2
cpu-map auto:1/1-2 0-1
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP
# Enable the HAProxy Runtime API
stats socket :9999 level admin expose-fd listeners
##----------------------------------------------------------------
## defaults
##----------------------------------------------------------------
defaults
log global
mode tcp
option tcplog
# Replace 1024000 with deployment connections
maxconn 1000
timeout connect 30000
timeout client 600s
timeout server 600s
##----------------------------------------------------------------
## API
##----------------------------------------------------------------
frontend emqx_mgmt
mode tcp
option tcplog
bind *:8081
default_backend emqx_mgmt_back
frontend emqx_dashboard
mode tcp
option tcplog
bind *:18083
default_backend emqx_dashboard_back
backend emqx_mgmt_back
mode http
# balance static-rr
server emqx-1 node1.emqx.io:8081
server emqx-2 node2.emqx.io:8081
backend emqx_dashboard_back
mode http
# balance static-rr
server emqx-1 node1.emqx.io:18083
server emqx-2 node2.emqx.io:18083
##----------------------------------------------------------------
## public
##----------------------------------------------------------------
frontend emqx_tcp
mode tcp
option tcplog
bind *:1883
default_backend emqx_tcp_back
frontend emqx_ws
mode tcp
option tcplog
bind *:8083
default_backend emqx_ws_back
backend emqx_tcp_back
mode tcp
balance static-rr
server emqx-1 node1.emqx.io:1883 check-send-proxy send-proxy-v2
server emqx-2 node2.emqx.io:1883 check-send-proxy send-proxy-v2
backend emqx_ws_back
mode tcp
balance static-rr
server emqx-1 node1.emqx.io:8083 check-send-proxy send-proxy-v2
server emqx-2 node2.emqx.io:8083 check-send-proxy send-proxy-v2
##----------------------------------------------------------------
## TLS
##----------------------------------------------------------------
frontend emqx_ssl
mode tcp
option tcplog
bind *:8883 ssl crt /usr/local/etc/haproxy/certs/emqx.pem ca-file /usr/local/etc/haproxy/certs/cacert.pem verify required no-sslv3
default_backend emqx_ssl_back
frontend emqx_wss
mode tcp
option tcplog
bind *:8084 ssl crt /usr/local/etc/haproxy/certs/emqx.pem ca-file /usr/local/etc/haproxy/certs/cacert.pem verify required no-sslv3
default_backend emqx_wss_back
backend emqx_ssl_back
mode tcp
balance static-rr
server emqx-1 node1.emqx.io:1883 check-send-proxy send-proxy-v2-ssl-cn
server emqx-2 node2.emqx.io:1883 check-send-proxy send-proxy-v2-ssl-cn
backend emqx_wss_back
mode tcp
balance static-rr
server emqx-1 node1.emqx.io:8083 check-send-proxy send-proxy-v2-ssl-cn
server emqx-2 node2.emqx.io:8083 check-send-proxy send-proxy-v2-ssl-cn

View File

@ -6,17 +6,19 @@
set -x
set +e
NODE1="node1.emqx.io"
NODE2="node2.emqx.io"
LB="haproxy"
apk update && apk add git curl
git clone -b develop-4.0 https://github.com/emqx/paho.mqtt.testing.git /paho.mqtt.testing
pip install pytest
pytest -v /paho.mqtt.testing/interoperability/test_client/V5/test_connect.py -k test_basic --host "$NODE1"
pytest -v /paho.mqtt.testing/interoperability/test_client/V5/test_connect.py -k test_basic --host "$LB"
RESULT=$?
pytest -v /paho.mqtt.testing/interoperability/test_cluster --host1 "$NODE1" --host2 "$NODE2"
RESULT=$(( RESULT + $? ))
pytest -v /paho.mqtt.testing/interoperability/test_client --host "$NODE1"
pytest -v /paho.mqtt.testing/interoperability/test_client --host "$LB"
RESULT=$(( RESULT + $? ))
# pytest -v /paho.mqtt.testing/interoperability/test_cluster --host1 "node1.emqx.io" --host2 "node2.emqx.io"
# RESULT=$(( RESULT + $? ))
exit $RESULT

View File

@ -5,6 +5,7 @@ tls-cert-file /tls/redis.crt
tls-key-file /tls/redis.key
tls-ca-cert-file /tls/ca.crt
tls-replication yes
tls-cluster yes
protected-mode no
requirepass public
masterauth public

View File

@ -90,7 +90,11 @@ do
continue;
fi
if [ "${node}" = "cluster" ] ; then
yes "yes" | redis-cli --cluster create "$LOCAL_IP:7000" "$LOCAL_IP:7001" "$LOCAL_IP:7002" --pass public --no-auth-warning;
if $tls ; then
yes "yes" | redis-cli --cluster create "$LOCAL_IP:8000" "$LOCAL_IP:8001" "$LOCAL_IP:8002" --pass public --no-auth-warning --tls true --cacert /tls/ca.crt --cert /tls/redis.crt --key /tls/redis.key;
else
yes "yes" | redis-cli --cluster create "$LOCAL_IP:7000" "$LOCAL_IP:7001" "$LOCAL_IP:7002" --pass public --no-auth-warning;
fi
elif [ "${node}" = "sentinel" ] ; then
tee /_sentinel.conf>/dev/null << EOF
port 26379

View File

@ -15,7 +15,7 @@ on:
jobs:
prepare:
runs-on: ubuntu-20.04
container: emqx/build-env:erl23.2.7-ubuntu20.04
container: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
outputs:
profiles: ${{ steps.set_profile.outputs.profiles}}
@ -83,7 +83,7 @@ jobs:
$version = $( "${{ github.ref }}" -replace "^(.*)/(.*)/" )
if ($version -match "^v[0-9]+\.[0-9]+(\.[0-9]+)?") {
$regex = "[0-9]+\.[0-9]+(-alpha|-beta|-rc)?\.[0-9]"
$regex = "[0-9]+\.[0-9]+(-alpha|-beta|-rc)?\.[0-9]+"
$pkg_name = "${{ matrix.profile }}-windows-$([regex]::matches($version, $regex).value).zip"
}
else {
@ -267,7 +267,7 @@ jobs:
cd -
- name: build emqx packages
env:
ERL_OTP: erl23.2.7
ERL_OTP: erl23.2.7.2-emqx-1
PROFILE: ${{ matrix.profile }}
ARCH: ${{ matrix.arch }}
SYSTEM: ${{ matrix.os }}

View File

@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
erl_otp:
- erl23.2.7
- erl23.2.7.2-emqx-1
os:
- ubuntu20.04
- centos7

View File

@ -5,7 +5,7 @@ on: [pull_request]
jobs:
check_deps_integrity:
runs-on: ubuntu-20.04
container: emqx/build-env:erl23.2.7-ubuntu20.04
container: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
steps:
- uses: actions/checkout@v2

View File

@ -357,13 +357,20 @@ jobs:
EMQX_AUTH__REDIS__SERVER=${redis_${{ matrix.network_type }}_address}:6380
EOF
- name: setup
if: matrix.node_type == 'sentinel'
if: matrix.node_type == 'sentinel' && matrix.connect_type == 'tcp'
run: |
cat <<-EOF >> "$GITHUB_ENV"
EMQX_AUTH__REDIS__TYPE=sentinel
EMQX_AUTH__REDIS__SERVER=${redis_${{ matrix.network_type }}_address}:26379
EMQX_AUTH__REDIS__SENTINEL=mymaster
EMQX_AUTH__REDIS__POOL=1
EOF
- name: setup
if: matrix.node_type == 'sentinel' && matrix.connect_type == 'tls'
run: |
cat <<-EOF >> "$GITHUB_ENV"
EMQX_AUTH__REDIS__TYPE=sentinel
EMQX_AUTH__REDIS__SERVER=${redis_${{ matrix.network_type }}_address}:26380
EMQX_AUTH__REDIS__SENTINEL=mymaster
EOF
- name: setup
if: matrix.node_type == 'cluster' && matrix.connect_type == 'tcp'

View File

@ -24,8 +24,10 @@ jobs:
echo "${{ secrets.CI_GIT_TOKEN }}" >> scripts/git-token
make deps-emqx-ee
echo "TARGET=emqx/emqx-ee" >> $GITHUB_ENV
echo "EMQX_TAG=$(./pkg-vsn.sh)" >> $GITHUB_ENV
else
echo "TARGET=emqx/emqx" >> $GITHUB_ENV
echo "EMQX_TAG=$(./pkg-vsn.sh)" >> $GITHUB_ENV
fi
- name: make emqx image
run: make docker
@ -33,19 +35,20 @@ jobs:
timeout-minutes: 5
run: |
set -e -u -x
docker-compose -f .ci/fvt_tests/docker-compose.yaml up -d
while [ "$(docker inspect -f '{{ .State.Health.Status}}' node1.emqx.io)" != "healthy" ] || [ "$(docker inspect -f '{{ .State.Health.Status}}' node2.emqx.io)" != "healthy" ]; do
if [ $(docker ps -a -f name=fvt_tests_emqx -f status=exited -q | wc -l) -ne 0 ]; then
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:emqx stop";
exit;
else
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:waiting emqx";
sleep 5;
fi;
echo "CUTTLEFISH_ENV_OVERRIDE_PREFIX=EMQX_" >> .ci/docker-compose-file/conf.cluster.env
echo "EMQX_ZONE__EXTERNAL__RETRY_INTERVAL=2s" >> .ci/docker-compose-file/conf.cluster.env
echo "EMQX_MQTT__MAX_TOPIC_ALIAS=10" >> .ci/docker-compose-file/conf.cluster.env
docker-compose \
-f .ci/docker-compose-file/docker-compose-emqx-cluster.yaml \
-f .ci/docker-compose-file/docker-compose-python.yaml \
up -d
while ! docker exec -i node1.emqx.io bash -c "emqx eval \"['emqx@node1.emqx.io','emqx@node2.emqx.io'] = maps:get(running_nodes, ekka_cluster:info()).\"" > /dev/null 2>&1; do
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:waiting emqx";
sleep 5;
done
- name: make paho tests
run: |
if ! docker exec -i paho_client /scripts/pytest.sh; then
if ! docker exec -i python /scripts/pytest.sh; then
docker logs node1.emqx.io
docker logs node2.emqx.io
exit 1
@ -149,7 +152,7 @@ jobs:
relup_test:
runs-on: ubuntu-20.04
container: emqx/build-env:erl23.2.7-ubuntu20.04
container: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
defaults:
run:
shell: bash

View File

@ -13,7 +13,7 @@ on:
jobs:
run_static_analysis:
runs-on: ubuntu-20.04
container: emqx/build-env:erl23.2.7-ubuntu20.04
container: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
steps:
- uses: actions/checkout@v2
@ -28,6 +28,21 @@ jobs:
- name: dialyzer
run: make dialyzer
run_proper_test:
runs-on: ubuntu-20.04
container: emqx/build-env:erl23.2.7.2-emqx-1-ubuntu20.04
steps:
- uses: actions/checkout@v2
- name: set git credentials
run: |
if make emqx-ee --dry-run > /dev/null 2>&1; then
echo "https://ci%40emqx.io:${{ secrets.CI_GIT_TOKEN }}@github.com" > $HOME/.git-credentials
git config --global credential.helper store
fi
- name: proper
run: make proper
run_common_test:
runs-on: ubuntu-20.04
@ -133,4 +148,4 @@ jobs:
run: |
curl -v -k https://coveralls.io/webhook \
--header "Content-Type: application/json" \
--data "{\"repo_name\":\"$GITHUB_REPOSITORY\",\"repo_token\":\"$GITHUB_TOKEN\",\"payload\":{\"build_num\":$GITHUB_RUN_ID,\"status\":\"done\"}}"
--data "{\"repo_name\":\"$GITHUB_REPOSITORY\",\"repo_token\":\"$GITHUB_TOKEN\",\"payload\":{\"build_num\":$GITHUB_RUN_ID,\"status\":\"done\"}}" || true

View File

@ -1 +1 @@
erlang 23.2.2
erlang 23.2.7.2-emqx-1

View File

@ -5,7 +5,7 @@ BUILD = $(CURDIR)/build
SCRIPTS = $(CURDIR)/scripts
export PKG_VSN ?= $(shell $(CURDIR)/pkg-vsn.sh)
export EMQX_DESC ?= EMQ X
export EMQX_CE_DASHBOARD_VERSION ?= v4.3.0-rc.1
export EMQX_CE_DASHBOARD_VERSION ?= v4.3.0
ifeq ($(OS),Windows_NT)
export REBAR_COLOR=none
endif
@ -40,7 +40,7 @@ eunit: $(REBAR)
.PHONY: proper
proper: $(REBAR)
@ENABLE_COVER_COMPILE=1 $(REBAR) as test proper -d test/props -c
@ENABLE_COVER_COMPILE=1 $(REBAR) proper -d test/props -c
.PHONY: ct
ct: $(REBAR)
@ -56,6 +56,14 @@ $1-ct:
endef
$(foreach app,$(APPS),$(eval $(call gen-app-ct-target,$(app))))
## apps/name-prop targets
.PHONY: $(APPS:%=%-prop)
define gen-app-prop-target
$1-prop:
$(REBAR) proper -d test/props -v -m $(shell $(CURDIR)/scripts/find-props.sh $1)
endef
$(foreach app,$(APPS),$(eval $(call gen-app-prop-target,$(app))))
.PHONY: cover
cover: $(REBAR)
@ENABLE_COVER_COMPILE=1 $(REBAR) cover

View File

@ -5,12 +5,12 @@
[![Coverage Status](https://coveralls.io/repos/github/emqx/emqx/badge.svg)](https://coveralls.io/github/emqx/emqx)
[![Docker Pulls](https://img.shields.io/docker/pulls/emqx/emqx)](https://hub.docker.com/r/emqx/emqx)
[![Slack Invite](<https://slack-invite.emqx.io/badge.svg>)](https://slack-invite.emqx.io)
[![Twitter](https://img.shields.io/badge/Twitter-EMQ%20X-1DA1F2?logo=twitter)](https://twitter.com/emqtt)
[![Twitter](https://img.shields.io/badge/Twitter-EMQ-1DA1F2?logo=twitter)](https://twitter.com/EMQTech)
[![Community](https://img.shields.io/badge/Community-EMQ%20X-yellow)](https://askemq.com)
[![最棒的物联网 MQTT 开源团队期待您的加入](https://www.emqx.io/static/img/github_readme_cn_bg.png)](https://careers.emqx.cn/)
[English](./README.md) | 简体中文 | [日本語](./README-JP.md)
[English](./README.md) | 简体中文 | [日本語](./README-JP.md) | [русский](./README-RU.md)
*EMQ X* 是一款完全开源,高度可伸缩,高可用的分布式 MQTT 消息服务器,适用于 IoT、M2M 和移动应用程序,可处理千万级别的并发客户端。
@ -128,7 +128,7 @@ DIALYZER_ANALYSE_APP=emqx_lwm2m,emqx_auth_jwt,emqx_auth_ldap make dialyzer
你可通过以下途径与 EMQ 社区及开发者联系:
- [Slack](https://slack-invite.emqx.io)
- [Twitter](https://twitter.com/emqtt)
- [Twitter](https://twitter.com/EMQTech)
- [Facebook](https://www.facebook.com/emqxmqtt)
- [Reddit](https://www.reddit.com/r/emqx/)
- [Weibo](https://weibo.com/emqtt)

View File

@ -5,11 +5,11 @@
[![Coverage Status](https://coveralls.io/repos/github/emqx/emqx/badge.svg)](https://coveralls.io/github/emqx/emqx)
[![Docker Pulls](https://img.shields.io/docker/pulls/emqx/emqx)](https://hub.docker.com/r/emqx/emqx)
[![Slack Invite](<https://slack-invite.emqx.io/badge.svg>)](https://slack-invite.emqx.io)
[![Twitter](https://img.shields.io/badge/Twitter-EMQ%20X-1DA1F2?logo=twitter)](https://twitter.com/emqtt)
[![Twitter](https://img.shields.io/badge/Twitter-EMQ-1DA1F2?logo=twitter)](https://twitter.com/EMQTech)
[![The best IoT MQTT open source team looks forward to your joining](https://www.emqx.io/static/img/github_readme_en_bg.png)](https://www.emqx.io/careers)
[English](./README.md) | [简体中文](./README-CN.md) | 日本語
[English](./README.md) | [简体中文](./README-CN.md) | 日本語 | [русский](./README-RU.md)
*EMQ X* は、高い拡張性と可用性をもつ、分散型のMQTTブローカーです。数千万のクライアントを同時に処理するIoT、M2M、モバイルアプリケーション向けです。
@ -55,7 +55,7 @@ _build/emqx/rel/emqx/bin/emqx console
## クイックスタート
emqx をソースコードからビルドした場合は、
`cd _buid/emqx/rel/emqx`でリリースビルドのディレクトリに移動してください。
`cd _build/emqx/rel/emqx`でリリースビルドのディレクトリに移動してください。
リリースパッケージからインストールした場合は、インストール先のルートディレクトリに移動してください。

141
README-RU.md Normal file
View File

@ -0,0 +1,141 @@
# Брокер EMQ X
[![GitHub Release](https://img.shields.io/github/release/emqx/emqx?color=brightgreen)](https://github.com/emqx/emqx/releases)
[![Build Status](https://travis-ci.org/emqx/emqx.svg)](https://travis-ci.org/emqx/emqx)
[![Coverage Status](https://coveralls.io/repos/github/emqx/emqx/badge.svg?branch=master)](https://coveralls.io/github/emqx/emqx?branch=master)
[![Docker Pulls](https://img.shields.io/docker/pulls/emqx/emqx)](https://hub.docker.com/r/emqx/emqx)
[![Slack Invite](<https://slack-invite.emqx.io/badge.svg>)](https://slack-invite.emqx.io)
[![Twitter](https://img.shields.io/badge/Follow-EMQ-1DA1F2?logo=twitter)](https://twitter.com/EMQTech)
[![Community](https://img.shields.io/badge/Community-EMQ%20X-yellow?logo=github)](https://github.com/emqx/emqx/discussions)
[![The best IoT MQTT open source team looks forward to your joining](https://www.emqx.io/static/img/github_readme_en_bg.png)](https://www.emqx.io/careers)
[English](./README.md) | [简体中文](./README-CN.md) | [日本語](./README-JP.md) | русский
*EMQ X* — это масштабируемый, высоко доступный, распределённый MQTT брокер с полностью открытым кодом для интернета вещей, межмашинного взаимодействия и мобильных приложений, который поддерживает миллионы одновременных подключений.
Начиная с релиза 3.0, брокер *EMQ X* полностью поддерживает протокол MQTT версии 5.0, и обратно совместим с версиями 3.1 и 3.1.1, а также протоколами MQTT-SN, CoAP, LwM2M, WebSocket и STOMP. Начиная с релиза 3.0, брокер *EMQ X* может масштабироваться до более чем 10 миллионов одновременных MQTT соединений на один кластер.
- Полный список возможностей доступен по ссылке: [EMQ X Release Notes](https://github.com/emqx/emqx/releases).
- Более подробная информация доступна на нашем сайте: [EMQ X homepage](https://www.emqx.io).
## Установка
Брокер *EMQ X* кросплатформенный, и поддерживает Linux, Unix, macOS и Windows. Он может работать на серверах с архитектурой x86_64 и устройствах на архитектуре ARM, таких как Raspberry Pi.
Более подробная информация о запуске на Windows по ссылке: [Windows.md](./Windows.md)
#### Установка EMQ X с помощью Docker-образа
```
docker run -d --name emqx -p 1883:1883 -p 8081:8081 -p 8083:8083 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx/emqx
```
#### Установка бинарного пакета
Сборки для различных операционных систем: [Загрузить EMQ X](https://www.emqx.io/downloads).
- [Установка на одном сервере](https://docs.emqx.io/en/broker/latest/getting-started/install.html)
- [Установка на кластере](https://docs.emqx.io/en/broker/latest/advanced/cluster.html)
## Сборка из исходного кода
Начиная с релиза 3.0, для сборки требуется Erlang/OTP R21 или выше.
Инструкция для сборки версии 4.3 и выше:
```bash
git clone https://github.com/emqx/emqx.git
cd emqx
make
_build/emqx/rel/emqx/bin console
```
Более ранние релизы могут быть собраны с помощью другого репозитория:
```bash
git clone https://github.com/emqx/emqx-rel.git
cd emqx-rel
make
_build/emqx/rel/emqx/bin/emqx console
```
## Первый запуск
Если emqx был собран из исходников: `cd _build/emqx/rel/emqx`.
Или перейдите в директорию, куда emqx был установлен из бинарного пакета.
```bash
# Запуск:
./bin/emqx start
# Проверка статуса:
./bin/emqx_ctl status
# Остановка:
./bin/emqx stop
```
Веб-интерфейс брокера будет доступен по ссылке: http://localhost:18083
## Тесты
### Полное тестирование
```
make eunit ct
```
### Запуск части тестов
Пример:
```bash
make apps/emqx_bridge_mqtt-ct
```
### Dialyzer
##### Статический анализ всех приложений
```
make dialyzer
```
##### Статический анализ части приложений (список через запятую)
```
DIALYZER_ANALYSE_APP=emqx_lwm2m,emqx_auth_jwt,emqx_auth_ldap make dialyzer
```
## Сообщество
### FAQ
Наиболее частые проблемы разобраны в [EMQ X FAQ](https://docs.emqx.io/en/broker/latest/faq/faq.html).
### Вопросы
Задать вопрос или поделиться идеей можно в [GitHub Discussions](https://github.com/emqx/emqx/discussions).
### Предложения
Более масштабные предложения можно присылать в виде pull request в репозиторий [EIP](https://github.com/emqx/eip).
### Разработка плагинов
Инструкция по разработке собственных плагинов доступна по ссылке: [lib-extra/README.md](./lib-extra/README.md)
## Спецификации стандарта MQTT
Следующие ссылки содержат спецификации стандартов:
[MQTT Version 3.1.1](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html)
[MQTT Version 5.0](https://docs.oasis-open.org/mqtt/mqtt/v5.0/cs02/mqtt-v5.0-cs02.html)
[MQTT SN](http://mqtt.org/new/wp-content/uploads/2009/06/MQTT-SN_spec_v1.2.pdf)
## Лицензия
Apache License 2.0, см. [LICENSE](./LICENSE).

View File

@ -5,12 +5,12 @@
[![Coverage Status](https://coveralls.io/repos/github/emqx/emqx/badge.svg?branch=master)](https://coveralls.io/github/emqx/emqx?branch=master)
[![Docker Pulls](https://img.shields.io/docker/pulls/emqx/emqx)](https://hub.docker.com/r/emqx/emqx)
[![Slack Invite](<https://slack-invite.emqx.io/badge.svg>)](https://slack-invite.emqx.io)
[![Twitter](https://img.shields.io/badge/Follow-EMQ%20X-1DA1F2?logo=twitter)](https://twitter.com/emqtt)
[![Twitter](https://img.shields.io/badge/Follow-EMQ-1DA1F2?logo=twitter)](https://twitter.com/EMQTech)
[![Community](https://img.shields.io/badge/Community-EMQ%20X-yellow?logo=github)](https://github.com/emqx/emqx/discussions)
[![The best IoT MQTT open source team looks forward to your joining](https://www.emqx.io/static/img/github_readme_en_bg.png)](https://www.emqx.io/careers)
English | [简体中文](./README-CN.md) | [日本語](./README-JP.md)
English | [简体中文](./README-CN.md) | [日本語](./README-JP.md) | [русский](./README-RU.md)
*EMQ X* broker is a fully open source, highly scalable, highly available distributed MQTT messaging broker for IoT, M2M and Mobile applications that can handle tens of millions of concurrent clients.
@ -63,7 +63,7 @@ _build/emqx/rel/emqx/bin/emqx console
## Quick Start
If emqx is built from source, `cd _buid/emqx/rel/emqx`.
If emqx is built from source, `cd _build/emqx/rel/emqx`.
Or change to the installation root directory if emqx is installed from a release package.
```bash

View File

@ -73,6 +73,7 @@ auth.http.super_req.headers.content-type = "application/x-www-form-urlencoded"
auth.http.super_req.params = "clientid=%c,username=%u"
## HTTP URL API path for ACL Request
## Comment out this config to disable ACL checks
##
## Value: URL
##

View File

@ -60,6 +60,10 @@ end}.
end
end}.
%% @doc URL for ACL checks. Example: http://127.0.0.1:80/mqtt/acl
%% ACL checks are disabled for this plugin if this config is
%% commented out from the config file, or when the overriding
%% environment variable is set to empty string.
{mapping, "auth.http.acl_req.url", "emqx_auth_http.acl_req", [
{datatype, string}
]}.
@ -124,4 +128,4 @@ end}.
{mapping, "auth.http.ssl.server_name_indication", "emqx_auth_http.server_name_indication", [
{datatype, string}
]}.
]}.

View File

@ -1,6 +1,4 @@
{deps,
[{ehttpc, {git, "https://github.com/emqx/ehttpc", {tag, "0.1.2"}}}
]}.
{deps, []}.
{edoc_opts, [{preprocess, true}]}.
{erl_opts, [warn_unused_vars,

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -53,15 +53,14 @@ translate_env(EnvName) ->
{ok, PoolSize} = application:get_env(?APP, pool_size),
{ok, ConnectTimeout} = application:get_env(?APP, connect_timeout),
URL = proplists:get_value(url, Req),
{ok, #{host := Host0,
{ok, #{host := Host,
path := Path0,
port := Port,
scheme := Scheme}} = emqx_http_lib:uri_parse(URL),
Path = path(Path0),
{Inet, Host} = parse_host(Host0),
MoreOpts = case Scheme of
http ->
[{transport_opts, [Inet]}];
[{transport_opts, emqx_misc:ipv6_probe([])}];
https ->
CACertFile = application:get_env(?APP, cacertfile, undefined),
CertFile = application:get_env(?APP, certfile, undefined),
@ -86,7 +85,7 @@ translate_env(EnvName) ->
, {ciphers, emqx_tls_lib:default_ciphers()}
| TLSOpts
],
[{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
[{transport, ssl}, {transport_opts, emqx_misc:ipv6_probe(NTLSOpts)}]
end,
PoolOpts = [{host, Host},
{port, Port},
@ -146,17 +145,6 @@ unload_hooks() ->
_ = ehttpc_sup:stop_pool('emqx_auth_http/acl_req'),
ok.
parse_host(Host) ->
case inet:parse_address(Host) of
{ok, Addr} when size(Addr) =:= 4 -> {inet, Addr};
{ok, Addr} when size(Addr) =:= 8 -> {inet6, Addr};
{error, einval} ->
case inet:getaddr(Host, inet6) of
{ok, _} -> {inet6, Host};
{error, _} -> {inet, Host}
end
end.
to_lower(Headers) ->
[{string:to_lower(K), V} || {K, V} <- Headers].

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -36,35 +36,75 @@
%%--------------------------------------------------------------------
all() ->
[{group, http_inet},
[
{group, http_inet},
{group, http_inet6},
{group, https_inet},
{group, https_inet6}].
{group, https_inet6},
pub_sub_no_acl,
no_hook_if_config_unset
].
groups() ->
Cases = emqx_ct:all(?MODULE),
[{Name, Cases} || Name <- [http_inet, http_inet6, https_inet, https_inet6]].
init_per_group(GrpName, Cfg) ->
[Schema, Inet] = [list_to_atom(X) || X <- string:tokens(atom_to_list(GrpName), "_")],
http_auth_server:start(Schema, Inet),
Fun = fun(App) -> set_special_configs(App, Schema, Inet) end,
emqx_ct_helpers:start_apps([emqx_auth_http], Fun),
[Scheme, Inet] = [list_to_atom(X) || X <- string:tokens(atom_to_list(GrpName), "_")],
ok = setup(Scheme, Inet),
Cfg.
end_per_group(_GrpName, _Cfg) ->
http_auth_server:stop(),
emqx_ct_helpers:stop_apps([emqx_auth_http, emqx]).
teardown().
set_special_configs(emqx, _Schmea, _Inet) ->
init_per_testcase(pub_sub_no_acl, Cfg) ->
Scheme = http,
Inet = inet,
http_auth_server:start(Scheme, Inet),
Fun = fun(App) -> set_special_configs(App, Scheme, Inet, no_acl) end,
emqx_ct_helpers:start_apps([emqx_auth_http], Fun),
?assert(is_hooked('client.authenticate')),
?assertNot(is_hooked('client.check_acl')),
Cfg;
init_per_testcase(no_hook_if_config_unset, Cfg) ->
setup(http, inet),
Cfg;
init_per_testcase(_, Cfg) ->
%% init per group
Cfg.
end_per_testcase(pub_sub_no_acl, _Cfg) ->
teardown();
end_per_testcase(no_hook_if_config_unset, _Cfg) ->
teardown();
end_per_testcase(_, _Cfg) ->
%% teardown per group
ok.
setup(Scheme, Inet) ->
http_auth_server:start(Scheme, Inet),
Fun = fun(App) -> set_special_configs(App, Scheme, Inet, normal) end,
emqx_ct_helpers:start_apps([emqx_auth_http], Fun),
?assert(is_hooked('client.authenticate')),
?assert(is_hooked('client.check_acl')).
teardown() ->
http_auth_server:stop(),
application:stop(emqx_auth_http),
?assertNot(is_hooked('client.authenticate')),
?assertNot(is_hooked('client.check_acl')),
emqx_ct_helpers:stop_apps([emqx]).
set_special_configs(emqx, _Scheme, _Inet, _AuthConfig) ->
application:set_env(emqx, allow_anonymous, true),
application:set_env(emqx, enable_acl_cache, false),
LoadedPluginPath = filename:join(["test", "emqx_SUITE_data", "loaded_plugins"]),
application:set_env(emqx, plugins_loaded_file,
emqx_ct_helpers:deps_path(emqx, LoadedPluginPath));
set_special_configs(emqx_auth_http, Schema, Inet) ->
ServerAddr = http_server(Schema, Inet),
set_special_configs(emqx_auth_http, Scheme, Inet, PluginConfig) ->
[application:unset_env(?APP, Par) || Par <- [acl_req, auth_req]],
ServerAddr = http_server(Scheme, Inet),
AuthReq = #{method => get,
url => ServerAddr ++ "/mqtt/auth",
@ -79,11 +119,14 @@ set_special_configs(emqx_auth_http, Schema, Inet) ->
headers => [{"content-type", "application/json"}],
params => [{"access", "%A"}, {"username", "%u"}, {"clientid", "%c"}, {"ipaddr", "%a"}, {"topic", "%t"}, {"mountpoint", "%m"}]},
Schema =:= https andalso set_https_client_opts(),
Scheme =:= https andalso set_https_client_opts(),
application:set_env(emqx_auth_http, auth_req, maps:to_list(AuthReq)),
application:set_env(emqx_auth_http, super_req, maps:to_list(SuperReq)),
application:set_env(emqx_auth_http, acl_req, maps:to_list(AclReq)).
case PluginConfig of
normal -> ok = application:set_env(emqx_auth_http, acl_req, maps:to_list(AclReq));
no_acl -> ok
end.
%% @private
set_https_client_opts() ->
@ -95,16 +138,16 @@ set_https_client_opts() ->
application:set_env(emqx_auth_http, server_name_indication, "disable").
%% @private
http_server(http, inet) -> "http://127.0.0.1:8991";
http_server(http, inet6) -> "http://[::1]:8991";
http_server(https, inet) -> "https://127.0.0.1:8991";
http_server(https, inet6) -> "https://[::1]:8991".
http_server(http, inet) -> "http://127.0.0.1:8991"; % ipv4
http_server(http, inet6) -> "http://localhost:8991"; % test hostname resolution
http_server(https, inet) -> "https://localhost:8991"; % test hostname resolution
http_server(https, inet6) -> "https://[::1]:8991". % ipv6
%%------------------------------------------------------------------------------
%% Testcases
%%------------------------------------------------------------------------------
t_check_acl(_) ->
t_check_acl(Cfg) when is_list(Cfg) ->
SuperUser = ?USER(<<"superclient">>, <<"superuser">>, mqtt, {127,0,0,1}, external),
deny = emqx_access_control:check_acl(SuperUser, subscribe, <<"users/testuser/1">>),
deny = emqx_access_control:check_acl(SuperUser, publish, <<"anytopic">>),
@ -125,7 +168,7 @@ t_check_acl(_) ->
deny = emqx_access_control:check_acl(User2, publish, <<"a/b/c">>),
deny = emqx_access_control:check_acl(User2, subscribe, <<"$SYS/testuser/1">>).
t_check_auth(_) ->
t_check_auth(Cfg) when is_list(Cfg) ->
User1 = ?USER(<<"client1">>, <<"testuser1">>, mqtt, {127,0,0,1}, external, undefined),
User2 = ?USER(<<"client2">>, <<"testuser2">>, mqtt, {127,0,0,1}, exteneral, undefined),
User3 = ?USER(<<"client3">>, undefined, mqtt, {127,0,0,1}, exteneral, undefined),
@ -142,8 +185,7 @@ t_check_auth(_) ->
{error, bad_username_or_password} = emqx_access_control:authenticate(User3#{password => <<"pwd">>}).
t_sub_pub(_) ->
ct:pal("start client"),
pub_sub_no_acl(Cfg) when is_list(Cfg) ->
{ok, T1} = emqtt:start_link([{host, "localhost"},
{clientid, <<"client1">>},
{username, <<"testuser1">>},
@ -164,12 +206,52 @@ t_sub_pub(_) ->
emqtt:disconnect(T1),
emqtt:disconnect(T2).
t_comment_config(_) ->
AuthCount = length(emqx_hooks:lookup('client.authenticate')),
AclCount = length(emqx_hooks:lookup('client.check_acl')),
t_pub_sub(Cfg) when is_list(Cfg) ->
{ok, T1} = emqtt:start_link([{host, "localhost"},
{clientid, <<"client1">>},
{username, <<"testuser1">>},
{password, <<"pass1">>}]),
{ok, _} = emqtt:connect(T1),
emqtt:publish(T1, <<"topic">>, <<"body">>, [{qos, 0}, {retain, true}]),
timer:sleep(1000),
{ok, T2} = emqtt:start_link([{host, "localhost"},
{clientid, <<"client2">>},
{username, <<"testuser2">>},
{password, <<"pass2">>}]),
{ok, _} = emqtt:connect(T2),
emqtt:subscribe(T2, <<"topic">>),
receive
{publish, _Topic, Payload} ->
?assertEqual(<<"body">>, Payload)
after 1000 -> false end,
emqtt:disconnect(T1),
emqtt:disconnect(T2).
no_hook_if_config_unset(Cfg) when is_list(Cfg) ->
?assert(is_hooked('client.authenticate')),
?assert(is_hooked('client.check_acl')),
application:stop(?APP),
[application:unset_env(?APP, Par) || Par <- [acl_req, auth_req]],
application:start(?APP),
?assertEqual([], emqx_hooks:lookup('client.authenticate')),
?assertEqual(AuthCount - 1, length(emqx_hooks:lookup('client.authenticate'))),
?assertEqual(AclCount - 1, length(emqx_hooks:lookup('client.check_acl'))).
?assertNot(is_hooked('client.authenticate')),
?assertNot(is_hooked('client.check_acl')).
is_hooked(HookName) ->
Callbacks = emqx_hooks:lookup(HookName),
F = fun(Callback) ->
case emqx_hooks:callback_action(Callback) of
{emqx_auth_http, check, _} ->
'client.authenticate' = HookName, % assert
true;
{emqx_acl_http, check_acl, _} ->
'client.check_acl' = HookName, % assert
true;
_ ->
false
end
end,
case lists:filter(F, Callbacks) of
[_] -> true;
[] -> false
end.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%c%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -222,10 +222,5 @@ format_msg(Message)
format_msg(Message) when is_tuple(Message) ->
iolist_to_binary(io_lib:format("~p", [Message])).
-if(?OTP_RELEASE >= 23).
urldecode(S) ->
[{R, _}] = uri_string:dissect_query(S), R.
-else.
urldecode(S) ->
http_uri:decode(S).
-endif.
emqx_http_lib:uri_decode(S).

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -301,10 +301,5 @@ format_msg(Message)
format_msg(Message) when is_tuple(Message) ->
iolist_to_binary(io_lib:format("~p", [Message])).
-if(?OTP_RELEASE >= 23).
urldecode(S) ->
[{R, _}] = uri_string:dissect_query(S), R.
-else.
urldecode(S) ->
http_uri:decode(S).
-endif.
emqx_http_lib:uri_decode(S).

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -58,7 +58,7 @@ load_auth_hook() ->
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
ok = emqx_auth_mnesia:register_metrics(),
Params = #{
hash_type => application:get_env(emqx_auth_mnesia, hash_type, sha256)
hash_type => application:get_env(emqx_auth_mnesia, password_hash, sha256)
},
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -47,33 +47,13 @@ groups() ->
[].
init_per_suite(Config) ->
ok = emqx_ct_helpers:start_apps([emqx_modules, emqx_management, emqx_auth_mnesia], fun set_special_configs/1),
ok = emqx_ct_helpers:start_apps([emqx_management, emqx_auth_mnesia], fun set_special_configs/1),
create_default_app(),
Config.
end_per_suite(_Config) ->
delete_default_app(),
emqx_ct_helpers:stop_apps([emqx_modules, emqx_management, emqx_auth_mnesia]).
init_per_testcase(t_check_as_clientid, Config) ->
Params = #{
hash_type => application:get_env(emqx_auth_mnesia, hash_type, sha256),
key_as => clientid
},
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]),
Config;
init_per_testcase(_, Config) ->
Params = #{
hash_type => application:get_env(emqx_auth_mnesia, hash_type, sha256),
key_as => username
},
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]),
Config.
end_per_suite(_, Config) ->
emqx:unhook('client.authenticate', fun emqx_auth_mnesia:check/3),
Config.
emqx_ct_helpers:stop_apps([emqx_management, emqx_auth_mnesia]).
set_special_configs(emqx) ->
application:set_env(emqx, allow_anonymous, true),
@ -275,6 +255,30 @@ t_username_rest_api(_Config) ->
{ok, Result5} = request_http_rest_lookup([Path]),
?assertMatch(#{}, get_http_data(Result5)).
t_password_hash(_) ->
clean_all_users(),
{ok, Default} = application:get_env(emqx_auth_mnesia, password_hash),
application:set_env(emqx_auth_mnesia, password_hash, plain),
%% change the password_hash to 'plain'
application:stop(emqx_auth_mnesia),
ok = application:start(emqx_auth_mnesia),
Params = #{<<"username">> => ?USERNAME, <<"password">> => ?PASSWORD},
{ok, _} = request_http_rest_add(["auth_username"], Params),
%% check
User = #{username => ?USERNAME,
clientid => undefined,
password => ?PASSWORD,
zone => external},
{ok, #{auth_result := success,
anonymous := false}} = emqx_access_control:authenticate(User),
application:set_env(emqx_auth_mnesia, password_hash, Default),
application:stop(emqx_auth_mnesia),
ok = application:start(emqx_auth_mnesia).
%%------------------------------------------------------------------------------
%% Helpers
%%------------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
{deps,
%% NOTE: mind poolboy version when updating eredis_cluster version
%% poolboy version may clash with emqx_auth_mongo
[{eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.6.4"}}},
[
{poolboy, {git, "https://github.com/emqx/poolboy.git", {tag, "1.5.2"}}}
]}.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -38,7 +38,7 @@ connect(Opts) ->
Host = case Sentinel =:= "" of
true -> get_value(host, Opts);
false ->
_ = eredis_sentinel:start_link(get_value(servers, Opts)),
_ = eredis_sentinel:start_link(get_value(servers, Opts), get_value(options, Opts, [])),
"sentinel:" ++ Sentinel
end,
case eredis:start_link(Host,

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -337,7 +337,7 @@ connecting(#{reconnect_delay_ms := ReconnectDelayMs} = State) ->
end.
connected(state_timeout, connected, #{inflight := Inflight} = State) ->
case retry_inflight(State, Inflight) of
case retry_inflight(State#{inflight := []}, Inflight) of
{ok, NewState} ->
{keep_state, NewState, {next_event, internal, maybe_send}};
{error, NewState} ->
@ -348,10 +348,10 @@ connected(internal, maybe_send, State) ->
{keep_state, NewState};
connected(info, {disconnected, Conn, Reason},
#{connection := Connection, name := Name, reconnect_delay_ms := ReconnectDelayMs} = State) ->
#{connection := Connection, name := Name, reconnect_delay_ms := ReconnectDelayMs} = State) ->
?tp(info, disconnected, #{name => Name, reason => Reason}),
case Conn =:= maps:get(client_pid, Connection, undefined) of
true ->
?LOG(info, "Bridge ~p diconnected~nreason=~p", [Name, Reason]),
{next_state, idle, State#{connection => undefined}, {state_timeout, ReconnectDelayMs, reconnect}};
false ->
keep_state_and_data
@ -434,12 +434,14 @@ do_connect(#{forwards := Forwards,
subscriptions := Subs,
connect_module := ConnectModule,
connect_cfg := ConnectCfg,
inflight := Inflight,
name := Name} = State) ->
ok = subscribe_local_topics(Forwards, Name),
case emqx_bridge_connect:start(ConnectModule, ConnectCfg#{subscriptions => Subs}) of
{ok, Conn} ->
?LOG(info, "Bridge ~p is connecting......", [Name]),
{ok, eval_bridge_handler(State#{connection => Conn}, connected)};
Res = eval_bridge_handler(State#{connection => Conn}, connected),
?tp(info, connected, #{name => Name, inflight => length(Inflight)}),
{ok, Res};
{error, Reason} ->
{error, Reason, State}
end.
@ -475,10 +477,12 @@ collect(Acc) ->
%% Retry all inflight (previously sent but not acked) batches.
retry_inflight(State, []) -> {ok, State};
retry_inflight(State, [#{q_ack_ref := QAckRef, batch := Batch} | Inflight]) ->
case do_send(State#{inflight := Inflight}, QAckRef, Batch) of
{ok, State1} -> retry_inflight(State1, Inflight);
{error, State1} -> {error, State1}
retry_inflight(State, [#{q_ack_ref := QAckRef, batch := Batch} | Rest] = OldInf) ->
case do_send(State, QAckRef, Batch) of
{ok, State1} ->
retry_inflight(State1, Rest);
{error, #{inflight := NewInf} = State1} ->
{error, State1#{inflight := NewInf ++ OldInf}}
end.
pop_and_send(#{inflight := Inflight, max_inflight := Max } = State) ->

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -27,14 +27,15 @@
-type ack_ref() :: emqx_bridge_worker:ack_ref().
-type batch() :: emqx_bridge_worker:batch().
start(Cfg) ->
start(#{client_pid := Pid} = Cfg) ->
Pid ! {self(), ?MODULE, ready},
{ok, Cfg}.
stop(_) -> ok.
%% @doc Callback for `emqx_bridge_connect' behaviour
-spec send(_, batch()) -> {ok, ack_ref()} | {error, any()}.
send(#{stub_pid := Pid}, Batch) ->
send(#{client_pid := Pid}, Batch) ->
Ref = make_ref(),
Pid ! {stub_message, self(), Ref, Batch},
{ok, Ref}.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -191,9 +191,15 @@ t_stub_normal(Config) when is_list(Config) ->
connect_module => emqx_bridge_stub_conn,
forward_mountpoint => <<"forwarded">>,
start_type => auto,
stub_pid => self()
client_pid => self()
},
{ok, Pid} = emqx_bridge_worker:start_link(?FUNCTION_NAME, Cfg),
receive
{Pid, emqx_bridge_stub_conn, ready} -> ok
after
5000 ->
error(timeout)
end,
ClientId = <<"ClientId">>,
try
{ok, ConnPid} = emqtt:start_link([{clientid, ClientId}]),
@ -203,6 +209,9 @@ t_stub_normal(Config) when is_list(Config) ->
{stub_message, WorkerPid, BatchRef, _Batch} ->
WorkerPid ! {batch_ack, BatchRef},
ok
after
5000 ->
error(timeout)
end,
?SNK_WAIT(inflight_drained),
?SNK_WAIT(replayq_drained),
@ -218,7 +227,7 @@ t_stub_overflow(Config) when is_list(Config) ->
connect_module => emqx_bridge_stub_conn,
forward_mountpoint => <<"forwarded">>,
start_type => auto,
stub_pid => self(),
client_pid => self(),
max_inflight => MaxInflight
},
{ok, Worker} = emqx_bridge_worker:start_link(?FUNCTION_NAME, Cfg),
@ -250,7 +259,7 @@ t_stub_random_order(Config) when is_list(Config) ->
connect_module => emqx_bridge_stub_conn,
forward_mountpoint => <<"forwarded">>,
start_type => auto,
stub_pid => self(),
client_pid => self(),
max_inflight => MaxInflight
},
{ok, Worker} = emqx_bridge_worker:start_link(?FUNCTION_NAME, Cfg),
@ -273,6 +282,53 @@ t_stub_random_order(Config) when is_list(Config) ->
ok = emqx_bridge_worker:stop(Worker)
end.
t_stub_retry_inflight(Config) when is_list(Config) ->
Topic = <<"to_stub_retry_inflight/a">>,
MaxInflight = 10,
Cfg = #{forwards => [Topic],
connect_module => emqx_bridge_stub_conn,
forward_mountpoint => <<"forwarded">>,
reconnect_delay_ms => 10,
start_type => auto,
client_pid => self(),
max_inflight => MaxInflight
},
{ok, Worker} = emqx_bridge_worker:start_link(?FUNCTION_NAME, Cfg),
ClientId = <<"ClientId2">>,
try
case ?block_until(#{?snk_kind := connected, inflight := 0}, 2000, 1000) of
{ok, #{inflight := 0}} -> ok;
Other -> ct:fail("~p", [Other])
end,
{ok, ConnPid} = emqtt:start_link([{clientid, ClientId}]),
{ok, _} = emqtt:connect(ConnPid),
lists:foreach(
fun(I) ->
Data = integer_to_binary(I),
_ = emqtt:publish(ConnPid, Topic, Data, ?QOS_1)
end, lists:seq(1, MaxInflight)),
%% receive acks but do not ack
Acks1 = stub_receive(MaxInflight),
?assertEqual(MaxInflight, length(Acks1)),
%% simulate a disconnect
Worker ! {disconnected, self(), test},
?SNK_WAIT(disconnected),
case ?block_until(#{?snk_kind := connected, inflight := MaxInflight}, 2000, 20) of
{ok, _} -> ok;
Error -> ct:fail("~p", [Error])
end,
%% expect worker to retry inflight, so to receive acks again
Acks2 = stub_receive(MaxInflight),
?assertEqual(MaxInflight, length(Acks2)),
lists:foreach(fun({Pid, Ref}) -> Pid ! {batch_ack, Ref} end,
lists:reverse(Acks2)),
?SNK_WAIT(inflight_drained),
?SNK_WAIT(replayq_drained),
emqtt:disconnect(ConnPid)
after
ok = emqx_bridge_worker:stop(Worker)
end.
stub_receive(N) ->
stub_receive(N, []).

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -151,7 +151,7 @@ To subscribe any topic, issue following command:
- if clientid is absent, a "bad_request" will be returned.
- {topicname} in URI should be percent-encoded to prevent special characters, such as + and #.
- {username} and {password} are optional.
- if {username} or {password} is incorrect, the error code `uauthorized` will be returned.
- if {username} or {password} is incorrect, the error code `unauthorized` will be returned.
- topic is subscribed with qos1.
- if the subscription failed due to ACL deny, the error code `forbidden` will be returned.
@ -169,7 +169,7 @@ To cancel observation, issue following command:
- if clientid is absent, a "bad_request" will be returned.
- {topicname} in URI should be percent-encoded to prevent special characters, such as + and #.
- {username} and {password} are optional.
- if {username} or {password} is incorrect, the error code `uauthorized` will be returned.
- if {username} or {password} is incorrect, the error code `unauthorized` will be returned.
CoAP Client Notification Operation (subscribed Message)
-------------------------------------------------------
@ -192,7 +192,7 @@ Issue a coap put command to publish messages. For example:
- if clientid is absent, a "bad_request" will be returned.
- {topicname} in URI should be percent-encoded to prevent special characters, such as + and #.
- {username} and {password} are optional.
- if {username} or {password} is incorrect, the error code `uauthorized` will be returned.
- if {username} or {password} is incorrect, the error code `unauthorized` will be returned.
- payload could be any binary data.
- payload data type is "application/octet-stream".
- publish message will be sent with qos0.
@ -211,7 +211,7 @@ Device should issue a get command periodically, serve as a ping to keep mqtt ses
- {any_topicname} is optional, and should be percent-encoded to prevent special characters.
- {clientid} is mandatory. If clientid is absent, a "bad_request" will be returned.
- {username} and {password} are optional.
- if {username} or {password} is incorrect, the error code `uauthorized` will be returned.
- if {username} or {password} is incorrect, the error code `unauthorized` will be returned.
- coap client should do keepalive work periodically to keep mqtt session online, especially those devices in a NAT network.
@ -231,7 +231,7 @@ ClientId, Username, Password and Topic
ClientId/username/password/topic in the coap URI are the concepts in mqtt. That is to say, emqx-coap is trying to fit coap message into mqtt system, by borrowing the client/username/password/topic from mqtt.
The Auth/ACL/Hook features in mqtt also applies on coap stuff. For example:
- If username/password is not authorized, coap client will get an uauthorized error.
- If username/password is not authorized, coap client will get an unauthorized error.
- If username or clientid is not allowed to published specific topic, coap message will be dropped in fact, although coap client will get an acknoledgement from emqx-coap.
- If a coap message is published, a 'message.publish' hook is able to capture this message as well.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -37,7 +37,9 @@
, stop/1
]).
-export([call/2]).
-export([ call/2
, call/3
]).
%% gen_server.
-export([ init/1
@ -93,6 +95,9 @@ publish(Pid, Topic, Payload) ->
%% For emqx_management plugin
call(Pid, Msg) ->
call(Pid, Msg, infinity).
call(Pid, Msg, _) ->
Pid ! Msg, ok.
%%--------------------------------------------------------------------
@ -100,8 +105,8 @@ call(Pid, Msg) ->
%%--------------------------------------------------------------------
init({ClientId, Username, Password, Channel}) ->
?LOG(debug, "try to start adapter ClientId=~p, Username=~p, Password=~p, Channel=~p",
[ClientId, Username, Password, Channel]),
?LOG(debug, "try to start adapter ClientId=~p, Username=~p, Password=~p, "
"Channel=~0p", [ClientId, Username, Password, Channel]),
State0 = #state{peername = Channel,
clientid = ClientId,
username = Username,

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -65,7 +65,7 @@ coap_get(ChId, ?PS_PREFIX, TopicPath, Query, Content=#coap_content{format = Form
end;
{error, auth_failure} ->
put(mqtt_client_pid, undefined),
{error, uauthorized};
{error, unauthorized};
{error, bad_request} ->
put(mqtt_client_pid, undefined),
{error, bad_request};

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@ -56,7 +56,7 @@ coap_get(ChId, ?MQTT_PREFIX, Path, Query, _Content) ->
#coap_content{};
{error, auth_failure} ->
put(mqtt_client_pid, undefined),
{error, forbidden};
{error, unauthorized};
{error, bad_request} ->
put(mqtt_client_pid, undefined),
{error, bad_request};

View File

@ -1,5 +1,5 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More