diff --git a/.ci/docker-compose-file/docker-compose-emqx-broker-cluster.yaml b/.ci/docker-compose-file/docker-compose-emqx-broker-cluster.yaml
new file mode 100644
index 000000000..5d21010b9
--- /dev/null
+++ b/.ci/docker-compose-file/docker-compose-emqx-broker-cluster.yaml
@@ -0,0 +1,99 @@
+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"
+ # - "5683:5683/udp"
+ # - "9999:9999"
+ # - "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:
+ restart: always
+ container_name: node1.emqx.io
+ image: $TARGET:$EMQX_TAG
+ env_file:
+ - conf.cluster.env
+ volumes:
+ - etc:/opt/emqx/etc
+ environment:
+ - "EMQX_HOST=node1.emqx.io"
+ ports:
+ - "11881:18083"
+# - "1883:1883"
+ command:
+ - /bin/sh
+ - -c
+ - |
+ sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
+ sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
+ /opt/emqx/bin/emqx foreground
+ healthcheck:
+ test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
+ interval: 5s
+ timeout: 25s
+ retries: 5
+ networks:
+ emqx_bridge:
+ aliases:
+ - node1.emqx.io
+
+ emqx2:
+ restart: always
+ container_name: node2.emqx.io
+ image: $TARGET:$EMQX_TAG
+ env_file:
+ - conf.cluster.env
+ volumes:
+ - etc:/opt/emqx/etc
+ environment:
+ - "EMQX_HOST=node2.emqx.io"
+ ports:
+ - "11882:18083"
+ command:
+ - /bin/sh
+ - -c
+ - |
+ sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
+ sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
+ /opt/emqx/bin/emqx foreground
+ healthcheck:
+ test: ["CMD", "/opt/emqx/bin/emqx", "ping"]
+ interval: 5s
+ timeout: 25s
+ retries: 5
+ networks:
+ emqx_bridge:
+ aliases:
+ - node2.emqx.io
+volumes:
+ etc:
+networks:
+ emqx_bridge:
+ driver: bridge
+ name: emqx_bridge
+ ipam:
+ driver: default
+ config:
+ - subnet: 172.100.239.0/24
+ gateway: 172.100.239.1
diff --git a/.ci/docker-compose-file/docker-compose-emqx-cluster.yaml b/.ci/docker-compose-file/docker-compose-emqx-cluster.yaml
index 18e1bb6cc..3655928e7 100644
--- a/.ci/docker-compose-file/docker-compose-emqx-cluster.yaml
+++ b/.ci/docker-compose-file/docker-compose-emqx-cluster.yaml
@@ -27,6 +27,7 @@ services:
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
emqx1:
+ restart: always
container_name: node1.emqx.io
image: $TARGET:$EMQX_TAG
env_file:
@@ -51,6 +52,7 @@ services:
- node1.emqx.io
emqx2:
+ restart: always
container_name: node2.emqx.io
image: $TARGET:$EMQX_TAG
env_file:
diff --git a/.ci/docker-compose-file/docker-compose-enterprise-tomcat-tcp.yaml b/.ci/docker-compose-file/docker-compose-enterprise-tomcat-tcp.yaml
new file mode 100644
index 000000000..90306919f
--- /dev/null
+++ b/.ci/docker-compose-file/docker-compose-enterprise-tomcat-tcp.yaml
@@ -0,0 +1,10 @@
+version: '3.9'
+
+services:
+ web_server:
+ container_name: Tomcat
+ build:
+ context: ./http-service
+ image: web-server
+ networks:
+ - emqx_bridge
diff --git a/.ci/docker-compose-file/http-service/Dockerfile b/.ci/docker-compose-file/http-service/Dockerfile
new file mode 100644
index 000000000..df1f7f98c
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/Dockerfile
@@ -0,0 +1,15 @@
+FROM tomcat:10.0.5
+
+RUN wget https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zip \
+ && unzip apache-maven-3.6.3-bin.zip \
+ && mv apache-maven-3.6.3 /opt/apache-maven-3.6.3/ \
+ && ln -s /opt/apache-maven-3.6.3/ /opt/maven
+ENV M2_HOME=/opt/maven
+ENV M2=$M2_HOME/bin
+ENV PATH=$M2:$PATH
+COPY ./web-server /code
+WORKDIR /code
+RUN mvn package -Dmaven.skip.test=true
+RUN mv ./target/emqx-web-0.0.1.war /usr/local/tomcat/webapps/emqx-web.war
+EXPOSE 8080
+CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
diff --git a/.ci/docker-compose-file/http-service/web-server/pom.xml b/.ci/docker-compose-file/http-service/web-server/pom.xml
new file mode 100644
index 000000000..7dfd4135e
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/pom.xml
@@ -0,0 +1,65 @@
+
+ 4.0.0
+ emqx-web
+ emqx-web
+ 0.0.1
+ war
+
+
+ mysql
+ mysql-connector-java
+ 8.0.16
+
+
+ commons-dbutils
+ commons-dbutils
+ 1.7
+
+
+ commons-logging
+ commons-logging
+ 1.2
+
+
+ commons-dbcp
+ commons-dbcp
+ 1.4
+
+
+ commons-pool
+ commons-pool
+ 1.6
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 5.0.0
+ provided
+
+
+
+
+
+ src/main/reousrce
+
+ **/*.java
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+
+
+
+ maven-war-plugin
+ 3.2.3
+
+
+
+
+
\ No newline at end of file
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/AuthDAO.java b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/AuthDAO.java
new file mode 100644
index 000000000..61340df42
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/AuthDAO.java
@@ -0,0 +1,54 @@
+package com.emqx.dao;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.commons.dbutils.handlers.ScalarHandler;
+
+import com.emqx.util.EmqxDatabaseUtil;
+
+public class AuthDAO {
+
+ public String getUserName(String userName) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select password from http_user where username='"+userName+"'";
+ String password =runner.query(sql, new ScalarHandler());
+ return password;
+ }
+
+ public String getClient(String clientid) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select password from http_user where clientid='"+clientid+"'";
+ String password =runner.query(sql, new ScalarHandler());
+ return password;
+ }
+
+ public String getUserAccess(String userName) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select access from http_acl where username='"+userName+"'";
+ String access =runner.query(sql, new ScalarHandler());
+ return access;
+ }
+
+ public String getUserTopic(String userName) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select topic from http_acl where username='"+userName+"'";
+ String topic =runner.query(sql, new ScalarHandler());
+ return topic;
+ }
+
+ public String getClientAccess(String clientid) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select access from http_acl where clientid='"+clientid+"'";
+ String access =runner.query(sql, new ScalarHandler());
+ return access;
+ }
+
+ public String getClientTopic(String clientid) throws IOException, SQLException {
+ QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
+ String sql = "select topic from http_acl where clientid='"+clientid+"'";
+ String topic =runner.query(sql, new ScalarHandler());
+ return topic;
+ }
+}
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/DBUtilsTest.java b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/DBUtilsTest.java
new file mode 100644
index 000000000..9836d4b11
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/dao/DBUtilsTest.java
@@ -0,0 +1,45 @@
+package com.emqx.dao;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.commons.dbutils.handlers.ColumnListHandler;
+import org.apache.commons.dbutils.handlers.ScalarHandler;
+import org.apache.commons.dbutils.handlers.columns.StringColumnHandler;
+
+
+public class DBUtilsTest {
+
+ public static void main(String args[]) throws FileNotFoundException, IOException, SQLException {
+ Properties property = new Properties();//流文件
+
+ property.load(DBUtilsTest.class.getClassLoader().getResourceAsStream("database.properties"));
+
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(property.getProperty("jdbc.driver"));
+ dataSource.setUrl(property.getProperty("jdbc.url"));
+ dataSource.setUsername(property.getProperty("jdbc.username"));
+ dataSource.setPassword(property.getProperty("jdbc.password"));
+
+ // 初始化连接数 if(initialSize!=null)
+ //dataSource.setInitialSize(Integer.parseInt(initialSize));
+
+ // 最小空闲连接 if(minIdle!=null)
+ //dataSource.setMinIdle(Integer.parseInt(minIdle));
+
+ // 最大空闲连接 if(maxIdle!=null)
+ //dataSource.setMaxIdle(Integer.parseInt(maxIdle));
+
+ QueryRunner runner = new QueryRunner(dataSource);
+ String sql="select username from mqtt_user where id=1";
+ String result = runner.query(sql, new ScalarHandler());
+
+ System.out.println(result);
+
+ }
+}
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AclServlet.java b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AclServlet.java
new file mode 100644
index 000000000..85915d550
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AclServlet.java
@@ -0,0 +1,103 @@
+package com.emqx.servlet;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+import com.emqx.dao.AuthDAO;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+public class AclServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // TODO Auto-generated method stub
+ doPost(req, resp);
+ }
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String clientid = req.getParameter("clientid");
+ String username = req.getParameter("username");
+ String access = req.getParameter("access");
+ String topic = req.getParameter("topic");
+ //String password = req.getParameter("password");
+
+ //step0: password is not null, or not pass.
+
+ AuthDAO dao = new AuthDAO();
+ try {
+ //step1: check username access&topic
+ if(username != null) {
+ String access_1 = dao.getUserAccess(username);
+ String topic_1 = dao.getUserTopic(username);
+
+ if(access.equals(access_1)) {
+ if(topic.equals(topic_1)) {
+ resp.setStatus(200);
+ }
+ else {
+ if(clientid != null){
+ String access_2 = dao.getClientAccess(clientid);
+ String topic_2 = dao.getClientTopic(clientid);
+ if(access.equals(access_2)) {
+ if(topic.equals(topic_2)) {
+ resp.setStatus(200);
+ }
+ else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }
+ }else {//step2.1: username password is not match, then check clientid password
+ if(clientid != null){
+ String access_3 = dao.getClientAccess(clientid);
+ String topic_3 = dao.getClientTopic(clientid);
+ if(access.equals(access_3)) {
+ if(topic.equals(topic_3)) {
+ resp.setStatus(200);
+ }
+ else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }
+ }else {//step2.2: username is null, then check clientid password
+ if(clientid != null){
+ String access_4 = dao.getClientAccess(clientid);
+ String topic_4 = dao.getClientTopic(clientid);
+ if(access.equals(access_4)) {
+ if(topic.equals(topic_4)) {
+ resp.setStatus(200);
+ }
+ else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AuthServlet.java b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AuthServlet.java
new file mode 100644
index 000000000..a59ca7567
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/servlet/AuthServlet.java
@@ -0,0 +1,72 @@
+package com.emqx.servlet;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+import com.emqx.dao.AuthDAO;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+public class AuthServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // TODO Auto-generated method stub
+ doPost(req, resp);
+ }
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String clientid = req.getParameter("clientid");
+ String username =req.getParameter("username");
+ String password = req.getParameter("password");
+
+ //step0: password is not null, or not pass.
+ if(password == null) {
+ resp.setStatus(400);
+ return;
+ }
+ AuthDAO dao = new AuthDAO();
+ try {
+ //step1: check username password
+ if(username != null) {
+ String password_d = dao.getUserName(username);
+
+ if(password.equals(password_d)) {
+ resp.setStatus(200);
+ //200
+ }else {//step2.1: username password is not match, then check clientid password
+ if(clientid != null){
+ String password_c = dao.getClient(clientid);
+ if(password.equals(password_c)) {
+ resp.setStatus(200);
+ }else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }
+ }else {//step2.2: username is null, then check clientid password
+ if(clientid != null){
+ String password_c = dao.getClient(clientid);
+ if(password.equals(password_c)) {
+ resp.setStatus(200);
+ }else {
+ resp.setStatus(400);
+ }
+ }else {
+ resp.setStatus(400);
+ }
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/util/EmqxDatabaseUtil.java b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/util/EmqxDatabaseUtil.java
new file mode 100644
index 000000000..b8fb0f229
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/java/com/emqx/util/EmqxDatabaseUtil.java
@@ -0,0 +1,27 @@
+package com.emqx.util;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.BasicDataSource;
+
+import com.emqx.dao.DBUtilsTest;
+
+public class EmqxDatabaseUtil {
+
+ public static DataSource getDataSource() throws IOException {
+ Properties property = new Properties();// 流文件
+
+ property.load(EmqxDatabaseUtil.class.getClassLoader().getResourceAsStream("database.properties"));
+
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(property.getProperty("jdbc.driver"));
+ dataSource.setUrl(property.getProperty("jdbc.url"));
+ dataSource.setUsername(property.getProperty("jdbc.username"));
+ dataSource.setPassword(property.getProperty("jdbc.password"));
+
+ return dataSource;
+ }
+}
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/reousrce/database.properties b/.ci/docker-compose-file/http-service/web-server/src/main/reousrce/database.properties
new file mode 100644
index 000000000..11886f347
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/reousrce/database.properties
@@ -0,0 +1,4 @@
+jdbc.driver= com.mysql.jdbc.Driver
+jdbc.url= jdbc:mysql://mysql_server:3306/mqtt
+jdbc.username= root
+jdbc.password= public
\ No newline at end of file
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/webapp/META-INF/MANIFEST.MF b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..254272e1c
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/webapp/WEB-INF/web.xml b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..e779a4541
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,31 @@
+
+
+ emqx-web
+
+ Auth
+ com.emqx.servlet.AuthServlet
+
+
+ Acl
+ com.emqx.servlet.AclServlet
+
+
+ Auth
+ /auth
+
+
+ Acl
+ /acl
+
+
+ index.html
+ index.htm
+ index.jsp
+ default.html
+ default.htm
+ default.jsp
+
+
\ No newline at end of file
diff --git a/.ci/docker-compose-file/http-service/web-server/src/main/webapp/index.html b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/index.html
new file mode 100644
index 000000000..2db63b2ea
--- /dev/null
+++ b/.ci/docker-compose-file/http-service/web-server/src/main/webapp/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+love
+
+
+It's lucky, jiabanxiang.
+
+
\ No newline at end of file
diff --git a/.github/workflows/run_automate_tests.yaml b/.github/workflows/run_automate_tests.yaml
index 73a295d30..70a5f08a1 100644
--- a/.github/workflows/run_automate_tests.yaml
+++ b/.github/workflows/run_automate_tests.yaml
@@ -120,3 +120,302 @@ jobs:
with:
name: jmeter_logs
path: ./jmeter_logs
+
+ mysql:
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ mysql_tag:
+ - 5.7
+ - 8
+ mysql_type:
+ - mysql_auth_acl
+
+ needs: build
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/download-artifact@v2
+ with:
+ name: emqx-docker-image-zip
+ path: /tmp
+ - name: load docker image
+ env:
+ version: ${{ needs.build.outputs.version }}
+ run: |
+ unzip -q /tmp/emqx-docker-${version}.zip -d /tmp
+ docker load < /tmp/emqx-docker-${version}
+ - name: docker compose up
+ timeout-minutes: 5
+ env:
+ TARGET: emqx/emqx
+ EMQX_TAG: ${{ needs.build.outputs.version }}
+ MYSQL_TAG: ${{ matrix.mysql_tag }}
+ run: |
+ docker-compose \
+ -f .ci/docker-compose-file/docker-compose-emqx-cluster.yaml \
+ -f .ci/docker-compose-file/docker-compose-mysql-tls.yaml \
+ up -d --build
+ - name: wait docker compose up
+ timeout-minutes: 5
+ run: |
+ while [ "$(docker inspect -f '{{ .State.Health.Status}}' node1.emqx.io)" != "healthy" ] || [ "$(docker inspect -f '{{ .State.Health.Status}}' node2.emqx.io)" != "healthy" ]; do
+ echo "['$(date -u +"%y-%m-%dt%h:%m:%sz")']:waiting emqx";
+ sleep 5;
+ done
+ while [ $(docker ps -a --filter name=client --filter exited=0 | wc -l) \
+ != $(docker ps -a --filter name=client | wc -l) ]; do
+ sleep 1
+ done
+ docker ps -a
+ echo HAPROXY_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' haproxy) >> $GITHUB_ENV
+ echo MYSQL_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql) >> $GITHUB_ENV
+ - uses: actions/checkout@v2
+ with:
+ repository: emqx/emqx-fvt
+ ref: integration_test_suites
+ path: scripts
+ - uses: actions/setup-java@v1
+ with:
+ java-version: '8.0.282' # The JDK version to make available on the path.
+ java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
+ architecture: x64 # (x64 or x86) - defaults to x64
+ - name: install jmeter
+ timeout-minutes: 10
+ env:
+ JMETER_VERSION: 5.3
+ run: |
+ wget --no-verbose --no-check-certificate -O /tmp/apache-jmeter.tgz https://downloads.apache.org/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
+ cd /tmp && tar -xvf apache-jmeter.tgz
+ echo "jmeter.save.saveservice.output_format=xml" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ echo "jmeter.save.saveservice.response_data.on_error=true" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ wget --no-verbose -O /tmp/apache-jmeter-$JMETER_VERSION/lib/ext/mqtt-xmeter-2.0.2-jar-with-dependencies.jar https://raw.githubusercontent.com/xmeter-net/mqtt-jmeter/master/Download/v2.0.2/mqtt-xmeter-2.0.2-jar-with-dependencies.jar
+ ln -s /tmp/apache-jmeter-$JMETER_VERSION /opt/jmeter
+ - name: install jmeter plugin
+ run: |
+ wget --no-verbose -O "/opt/jmeter/lib/mysql-connector-java-8.0.16.jar" https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar
+ - name: run jmeter
+ run: |
+ /opt/jmeter/bin/jmeter.sh \
+ -Jjmeter.save.saveservice.output_format=xml -n \
+ -t scripts/.ci/automate-test-suite/${{ matrix.mysql_type }}.jmx \
+ -Droute="apps/emqx_auth_mysql/test/emqx_auth_mysql_SUITE_data" \
+ -Dmysql_ip=$MYSQL_IP \
+ -Demqx_ip=$HAPROXY_IP \
+ -Ddbname="mqtt" \
+ -Dmysql_user="ssluser" \
+ -Ddb_user="root" \
+ -Dmysql_pwd="public" \
+ -Dconfig_path="/tmp/etc" \
+ -Ddocker_path=".ci/docker-compose-file" \
+ -l jmeter_logs/${{ matrix.mysql_type }}_${{ matrix.mysql_tag }}.jtl \
+ -j jmeter_logs/logs/${{ matrix.mysql_type }}_${{ matrix.mysql_tag }}.log
+ - name: check logs
+ run: |
+ if cat jmeter_logs/${{ matrix.mysql_type }}_${{ matrix.mysql_tag }}.jtl | grep -e 'true' > /dev/null 2>&1; then
+ echo "check logs filed"
+ exit 1
+ fi
+ - uses: actions/upload-artifact@v1
+ if: always()
+ with:
+ name: jmeter_logs
+ path: ./jmeter_logs
+
+
+ postgresql:
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ pgsql_type:
+ - pgsql_auth_acl
+ pgsql_tag:
+ - 9
+ - 10
+ - 11
+ - 12
+ - 13
+
+ needs: build
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/download-artifact@v2
+ with:
+ name: emqx-docker-image-zip
+ path: /tmp
+ - name: load docker image
+ env:
+ version: ${{ needs.build.outputs.version }}
+ run: |
+ unzip -q /tmp/emqx-docker-${version}.zip -d /tmp
+ docker load < /tmp/emqx-docker-${version}
+ - name: docker compose up
+ timeout-minutes: 5
+ env:
+ TARGET: emqx/emqx
+ EMQX_TAG: ${{ needs.build.outputs.version }}
+ PGSQL_TAG: ${{ matrix.pgsql_tag }}
+ run: |
+ docker-compose \
+ -f .ci/docker-compose-file/docker-compose-emqx-broker-cluster.yaml \
+ -f .ci/docker-compose-file/docker-compose-pgsql-tls.yaml \
+ up -d --build
+ - name: wait docker compose up
+ timeout-minutes: 5
+ run: |
+ while [ "$(docker inspect -f '{{ .State.Health.Status}}' node1.emqx.io)" != "healthy" ] || [ "$(docker inspect -f '{{ .State.Health.Status}}' node2.emqx.io)" != "healthy" ]; do
+ echo "['$(date -u +"%y-%m-%dt%h:%m:%sz")']:waiting emqx";
+ sleep 5;
+ done
+ docker ps -a
+ echo HAPROXY_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' haproxy) >> $GITHUB_ENV
+ echo PGSQL_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pgsql) >> $GITHUB_ENV
+ echo CONFIG_PATH=$(docker inspect -f '{{ range .Mounts }}{{ if eq .Name "docker-compose-file_etc" }}{{ .Source }}{{ end }}{{ end }}' node1.emqx.io) >> $GITHUB_ENV
+ - uses: actions/checkout@v2
+ with:
+ repository: emqx/emqx-fvt
+ ref: integration_test_suites
+ path: scripts
+ - uses: actions/setup-java@v1
+ with:
+ java-version: '8.0.282' # The JDK version to make available on the path.
+ java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
+ architecture: x64 # (x64 or x86) - defaults to x64
+ - name: install jmeter
+ timeout-minutes: 10
+ env:
+ JMETER_VERSION: 5.3
+ run: |
+ wget --no-verbose --no-check-certificate -O /tmp/apache-jmeter.tgz https://downloads.apache.org/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
+ cd /tmp && tar -xvf apache-jmeter.tgz
+ echo "jmeter.save.saveservice.output_format=xml" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ echo "jmeter.save.saveservice.response_data.on_error=true" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ wget --no-verbose -O /tmp/apache-jmeter-$JMETER_VERSION/lib/ext/mqtt-xmeter-2.0.2-jar-with-dependencies.jar https://raw.githubusercontent.com/xmeter-net/mqtt-jmeter/master/Download/v2.0.2/mqtt-xmeter-2.0.2-jar-with-dependencies.jar
+ ln -s /tmp/apache-jmeter-$JMETER_VERSION /opt/jmeter
+ - name: install jmeter plugin
+ run: |
+ wget --no-verbose -O "/opt/jmeter/lib/postgresql-42.2.18.jar" https://repo1.maven.org/maven2/org/postgresql/postgresql/42.2.18/postgresql-42.2.18.jar
+ - name: run jmeter
+ run: |
+ sudo /opt/jmeter/bin/jmeter.sh \
+ -Jjmeter.save.saveservice.output_format=xml -n \
+ -t scripts/.ci/automate-test-suite/${{ matrix.pgsql_type }}.jmx \
+ -Droute="apps/emqx_auth_pgsql/test/emqx_auth_pgsql_SUITE_data" \
+ -Dca_name="ca.pem" \
+ -Dkey_name="client-key.pem" \
+ -Dcert_name="client-cert.pem" \
+ -Ddb_ip=$PGSQL_IP \
+ -Dpgsql_ip=$PGSQL_IP \
+ -Demqx_ip=$HAPROXY_IP \
+ -Dpgsql_user="root" \
+ -Dpgsql_pwd="public" \
+ -Ddbname="mqtt" \
+ -Dpgsql_db="mqtt" \
+ -Dport="5432" \
+ -Dconfig_path=$CONFIG_PATH \
+ -Ddocker_path=".ci/docker-compose-file" \
+ -l jmeter_logs/${{ matrix.pgsql_type }}_${{ matrix.pgsql_tag }}.jtl \
+ -j jmeter_logs/logs/${{ matrix.pgsql_type }}_${{ matrix.pgsql_tag }}.log
+ - name: check logs
+ run: |
+ if cat jmeter_logs/${{ matrix.pgsql_type }}_${{ matrix.pgsql_tag }}.jtl | grep -e 'true' > /dev/null 2>&1; then
+ echo "check logs filed"
+ exit 1
+ fi
+ - uses: actions/upload-artifact@v1
+ if: always()
+ with:
+ name: jmeter_logs
+ path: ./jmeter_logs
+
+ http:
+ runs-on: ubuntu-latest
+
+ needs: build
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/download-artifact@v2
+ with:
+ name: emqx-docker-image-zip
+ path: /tmp
+ - name: load docker image
+ env:
+ version: ${{ needs.build.outputs.version }}
+ run: |
+ unzip -q /tmp/emqx-docker-${version}.zip -d /tmp
+ docker load < /tmp/emqx-docker-${version}
+ - name: docker compose up
+ timeout-minutes: 5
+ env:
+ TARGET: emqx/emqx
+ EMQX_TAG: ${{ needs.build.outputs.version }}
+ MYSQL_TAG: 8
+ run: |
+ docker-compose \
+ -f .ci/docker-compose-file/docker-compose-emqx-broker-cluster.yaml \
+ -f .ci/docker-compose-file/docker-compose-mysql-tcp.yaml \
+ -f .ci/docker-compose-file/docker-compose-enterprise-tomcat-tcp.yaml \
+ up -d --build
+ - name: wait docker compose up
+ timeout-minutes: 5
+ run: |
+ while [ "$(docker inspect -f '{{ .State.Health.Status}}' node1.emqx.io)" != "healthy" ] || [ "$(docker inspect -f '{{ .State.Health.Status}}' node2.emqx.io)" != "healthy" ]; do
+ echo "['$(date -u +"%y-%m-%dt%h:%m:%sz")']:waiting emqx";
+ sleep 5;
+ done
+ docker ps -a
+ echo HAPROXY_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' haproxy) >> $GITHUB_ENV
+ echo HTTP_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' Tomcat) >> $GITHUB_ENV
+ echo MYSQL_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql) >> $GITHUB_ENV
+ echo CONFIG_PATH=$(docker inspect -f '{{ range .Mounts }}{{ if eq .Name "docker-compose-file_etc" }}{{ .Source }}{{ end }}{{ end }}' node1.emqx.io) >> $GITHUB_ENV
+ - uses: actions/checkout@v2
+ with:
+ repository: emqx/emqx-fvt
+ ref: integration_test_suites
+ path: scripts
+ - uses: actions/setup-java@v1
+ with:
+ java-version: '8.0.282' # The JDK version to make available on the path.
+ java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
+ architecture: x64 # (x64 or x86) - defaults to x64
+ - name: install jmeter
+ timeout-minutes: 10
+ env:
+ JMETER_VERSION: 5.3
+ run: |
+ wget --no-verbose --no-check-certificate -O /tmp/apache-jmeter.tgz https://downloads.apache.org/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
+ cd /tmp && tar -xvf apache-jmeter.tgz
+ echo "jmeter.save.saveservice.output_format=xml" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ echo "jmeter.save.saveservice.response_data.on_error=true" >> /tmp/apache-jmeter-$JMETER_VERSION/user.properties
+ wget --no-verbose -O /tmp/apache-jmeter-$JMETER_VERSION/lib/ext/mqtt-xmeter-2.0.2-jar-with-dependencies.jar https://raw.githubusercontent.com/xmeter-net/mqtt-jmeter/master/Download/v2.0.2/mqtt-xmeter-2.0.2-jar-with-dependencies.jar
+ ln -s /tmp/apache-jmeter-$JMETER_VERSION /opt/jmeter
+ - name: install jmeter plugin
+ run: |
+ wget --no-verbose -O "/opt/jmeter/lib/mysql-connector-java-8.0.16.jar" https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar
+ - name: run jmeter
+ run: |
+ sudo /opt/jmeter/bin/jmeter.sh \
+ -Jjmeter.save.saveservice.output_format=xml -n \
+ -t scripts/.ci/automate-test-suite/http_auth_acl.jmx \
+ -Dmysql_ip=$MYSQL_IP \
+ -Demqx_ip=$HAPROXY_IP \
+ -Dweb_server_ip=$HTTP_IP \
+ -Dconfig_path=$CONFIG_PATH \
+ -Ddocker_path=".ci/docker-compose-file" \
+ -l jmeter_logs/http_auth_acl.jtl \
+ -j jmeter_logs/logs/http_auth_acl.log
+ - name: check logs
+ run: |
+ if cat jmeter_logs/http_auth_acl.jtl | grep -e 'true' > /dev/null 2>&1; then
+ echo "check logs filed"
+ sudo cat /var/lib/docker/volumes/docker-compose-file_etc/_data/emqx.conf
+ exit 1
+ fi
+ - uses: actions/upload-artifact@v1
+ if: always()
+ with:
+ name: jmeter_logs
+ path: ./jmeter_logs
diff --git a/apps/emqx_auth_redis/test/emqx_auth_redis_SUITE_data/certs/redis.crt b/apps/emqx_auth_redis/test/emqx_auth_redis_SUITE_data/certs/redis.crt
index 5eefadf62..582a7bae2 100644
--- a/apps/emqx_auth_redis/test/emqx_auth_redis_SUITE_data/certs/redis.crt
+++ b/apps/emqx_auth_redis/test/emqx_auth_redis_SUITE_data/certs/redis.crt
@@ -1,23 +1,23 @@
-----BEGIN CERTIFICATE-----
-MIID1zCCAb8CCQC/+qKgZd+m/DANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS
-ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjAx
-MDI5MDEzNDE2WhcNMjExMDI5MDEzNDE2WjAmMRMwEQYDVQQKDApSZWRpcyBUZXN0
+MIID1zCCAb8CCQC/+qKgZd+m/jANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS
+ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjEx
+MTAxMDgwMDU1WhcNMzExMDMwMDgwMDU1WjAmMRMwEQYDVQQKDApSZWRpcyBUZXN0
MQ8wDQYDVQQDDAZTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDSs3bQ9sYi2AhFuHU75Ryk1HHSgfzA6pQAJilmJdTy0s5vyiWe1HQJaWkMcS5V
GVzGMK+c+OBqtXtDDninL3betg1YPMjSCOjPMOTC1H9K7+effwf7Iwpnw9Zro8mb
TEmMslIYhhcDedzT9Owli4QAgbgTn4l1BYuKX9CLrrKFtnr21miKu3ydViy9q7T1
pib3eigvAyk7X2fadHFArGEttsXrD6cetPPkSF/1OLWNlqzUKXzhSyrBXzO44Kks
fwR/EpTiES9g4dNOL2wvKS/YE1fNKhiCENrNxTXQo1l0yOdm2+MeyOeHFzRuS0b/
-+uGDFOPPi04KXeO6dQ5olBCPAgMBAAEwDQYJKoZIhvcNAQELBQADggIBADn0E2vG
-iQWe8/I7VbBdPhPNupVNcLvew10eIHxY2g5vSruCSVRQTgk8itVMRmDQxbb7gdDW
-jnCRbxykxbLjM9iCRljnOCsIcTi7qO7JRl8niV8dtEpPOs9lZxEdNXjIV1iZoWf3
-arBbPQSyQZvTQHG6qbFnyCdMMyyXGGvEPGQDaBiKH+Ko1qeAbCi0zupChYvxmtZ8
-hSTPlMFezDT9bKoNY0pkJSELfokEPU/Pn6Lz/NVbdzmCMjVa/xmF3s31g+DGhz95
-4AyOnCr6o0aydPVVV3pB/BCezNXPUxpp53BG0w/K2f2DnKYCvGvJbqDAaJ8bG/J1
-EFSOmwobdwVxJz3KNubmo1qJ6xOl/YT7yyqPRQRM1SY8nZW+YcoJSZjOe8wJVlob
-d0bOwN1C3HQwomyMWes187bEQP6Y36HuEbR1fK8yIOzGsGDKRFAFwQwMgw2M91lr
-EJIP5NRD3OZRuiYDiVfVhDZDaNahrAMZUcPCgeCAwc4YG6Gp2sDtdorOl4kIJYWE
-BbBZ0Jplq9+g6ciu5ChjAW8iFl0Ae5U24MxPGXnrxiRF4WWxLeZMVLXLDvlPqReD
-CHII5ifyvGEt5+RhqtZC/L+HimL+5wQgOlntqhUdLb6yWRz7YW37PFMnUXU3MXe9
-uY7m73ZLluXiLojcZxU2+cx89u5FOJxrYtrj
++uGDFOPPi04KXeO6dQ5olBCPAgMBAAEwDQYJKoZIhvcNAQELBQADggIBALRSylnk
+JJhEFRniuQ+H1kbfZlVOqnSqGkm38r8X76dnYRZfkFlxVzU2q5HPnSdiL9D3JrrH
+P7wIA5zjr76zK7GPJjkRExRZy5sTLSpsGp7YIGAZ19J3KsDVHSOvPTl38c6L217a
+YzPeQL5IrrW55URmA5PZFu3lsm9z7CNguw1wn2pCNNB+r/cRl4iELehZJT891CQe
+nV9a1YfHY/DkDoMnmrKqmeYdvje8n1uSqTnIV/wNiASU36ztxxD8ZmwprxxbjLSs
+aBjBvsR/eBHbWrz2W1dc5ppgGLuCkiEKmh6/IWX/ZQqyBCzZkmFNiTs8QiLtmoC4
+2bXkPVSyq5wT7eisGbRdcY9vGDtoW/WZOmFVA4XEDVx8M9fb4speHwoHRuTfWsA0
+6Y8P9XpYjG2tQoPpxrZaRshZ+SiHWPov7cAvY34szFePfTWR8gzbL6SgpDz30ceh
+XIuTArOMQMhfWHn3NaOc6hlkRsoviNhc5IXR9VjIdaNJCamEoLVNWZsvHJCUiP10
+yx+9/0a9vI6G+i8oKQ+eKJsfP8Ikoiolf7vU6M+/1kF+sSMxGjFwkMCxLgZB67+a
+m9kw83sVfykWLQ3eRwhdBz0/JiiYtDbbtyqgs3kPhJs9SGZUhDc/7R0lTWf4zxoJ
+l3y7pn/3nJvYrGX7uCBbWPUuqWeHVM9Ip6AZ
-----END CERTIFICATE-----