├── .asf.yaml ├── .gitignore ├── .travis.yml ├── LICENSE ├── NOTICE ├── README.md ├── distribution ├── bin │ ├── meta.sh │ ├── mqtt.sh │ └── runserver.sh ├── conf │ ├── connect.conf │ ├── logback.xml │ ├── meta.conf │ ├── meta_spring.xml │ ├── service.conf │ └── spring.xml ├── pom.xml └── release.xml ├── mqtt-common ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── apache │ │ │ └── rocketmq │ │ │ └── mqtt │ │ │ └── common │ │ │ ├── facade │ │ │ ├── AuthManager.java │ │ │ ├── LmqOffsetStore.java │ │ │ ├── LmqQueueStore.java │ │ │ ├── MetaPersistManager.java │ │ │ ├── RetainedPersistManager.java │ │ │ ├── SubscriptionPersistManager.java │ │ │ ├── WillMsgPersistManager.java │ │ │ └── WillMsgSender.java │ │ │ ├── hook │ │ │ ├── AbstractUpstreamHook.java │ │ │ ├── Hook.java │ │ │ ├── HookResult.java │ │ │ ├── UpstreamHook.java │ │ │ ├── UpstreamHookEnum.java │ │ │ └── UpstreamHookManager.java │ │ │ ├── meta │ │ │ ├── IpUtil.java │ │ │ ├── MetaConstants.java │ │ │ └── RaftUtil.java │ │ │ ├── model │ │ │ ├── Constants.java │ │ │ ├── Message.java │ │ │ ├── MessageEvent.java │ │ │ ├── MqttMessageUpContext.java │ │ │ ├── MqttTopic.java │ │ │ ├── PullResult.java │ │ │ ├── Queue.java │ │ │ ├── QueueOffset.java │ │ │ ├── Remark.java │ │ │ ├── RpcCode.java │ │ │ ├── RpcHeader.java │ │ │ ├── StoreResult.java │ │ │ ├── Subscription.java │ │ │ ├── Trie.java │ │ │ ├── TrieException.java │ │ │ ├── TrieMethod.java │ │ │ └── WillMessage.java │ │ │ └── util │ │ │ ├── HmacSHA1Util.java │ │ │ ├── HostInfo.java │ │ │ ├── MessageUtil.java │ │ │ ├── NamespaceUtil.java │ │ │ ├── SpringUtils.java │ │ │ ├── StatUtil.java │ │ │ └── TopicUtils.java │ └── proto │ │ └── request.proto │ └── test │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── common │ └── test │ ├── hook │ ├── TestAbstractUpstreamHook.java │ └── TestHookResult.java │ ├── model │ ├── TestMessage.java │ ├── TestQueueOffset.java │ ├── TestSubscription.java │ └── TestTrie.java │ └── util │ ├── TestHmacSHA1Util.java │ ├── TestHostInfo.java │ ├── TestMessageUtil.java │ ├── TestNamespaceUtil.java │ ├── TestStatUtil.java │ └── TestTopicUtils.java ├── mqtt-cs ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── rocketmq │ │ └── mqtt │ │ └── cs │ │ ├── channel │ │ ├── AdaptiveTlsHandler.java │ │ ├── ChannelCloseFrom.java │ │ ├── ChannelDecodeException.java │ │ ├── ChannelException.java │ │ ├── ChannelInfo.java │ │ ├── ChannelManager.java │ │ ├── ConnectHandler.java │ │ └── DefaultChannelManager.java │ │ ├── config │ │ ├── ConnectConf.java │ │ ├── ConnectConfListener.java │ │ └── WillLoopConf.java │ │ ├── hook │ │ └── UpstreamHookManagerImpl.java │ │ ├── protocol │ │ ├── mqtt │ │ │ ├── MqttPacketDispatcher.java │ │ │ ├── MqttPacketHandler.java │ │ │ ├── facotry │ │ │ │ └── MqttMessageFactory.java │ │ │ └── handler │ │ │ │ ├── MqttConnectHandler.java │ │ │ │ ├── MqttDisconnectHandler.java │ │ │ │ ├── MqttPingHandler.java │ │ │ │ ├── MqttPubAckHandler.java │ │ │ │ ├── MqttPubCompHandler.java │ │ │ │ ├── MqttPubRecHandler.java │ │ │ │ ├── MqttPubRelHandler.java │ │ │ │ ├── MqttPublishHandler.java │ │ │ │ ├── MqttSubscribeHandler.java │ │ │ │ └── MqttUnSubscribeHandler.java │ │ ├── rpc │ │ │ └── RpcPacketDispatcher.java │ │ ├── ssl │ │ │ └── SslFactory.java │ │ └── ws │ │ │ ├── WebSocketEncoder.java │ │ │ └── WebSocketServerHandler.java │ │ ├── session │ │ ├── QueueFresh.java │ │ ├── Session.java │ │ ├── infly │ │ │ ├── InFlyCache.java │ │ │ ├── MqttMsgId.java │ │ │ ├── PushAction.java │ │ │ └── RetryDriver.java │ │ ├── loop │ │ │ ├── PullResultStatus.java │ │ │ ├── QueueCache.java │ │ │ ├── SessionLoop.java │ │ │ ├── SessionLoopImpl.java │ │ │ └── WillLoop.java │ │ ├── match │ │ │ └── MatchAction.java │ │ └── notify │ │ │ └── MessageNotifyAction.java │ │ └── starter │ │ ├── ExporterServer.java │ │ ├── MqttServer.java │ │ ├── RpcServer.java │ │ └── Startup.java │ └── test │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── cs │ └── test │ ├── channel │ ├── TestChannelInfo.java │ ├── TestConnectHandler.java │ └── TestDefaultChannelManager.java │ ├── config │ └── TestConnectConfListener.java │ ├── hook │ └── TestUpstreamHookManagerImpl.java │ ├── protocol │ ├── mqtt │ │ ├── TestMqttPacketDispatcher.java │ │ └── handler │ │ │ ├── TestMqttConnectHandler.java │ │ │ ├── TestMqttDisconnectHandler.java │ │ │ ├── TestMqttPingHandler.java │ │ │ ├── TestMqttPubAckHandler.java │ │ │ ├── TestMqttPubCompHandler.java │ │ │ ├── TestMqttPubRecHandler.java │ │ │ ├── TestMqttPubRelHandler.java │ │ │ ├── TestMqttPublishHandler.java │ │ │ ├── TestMqttSubscribeHandler.java │ │ │ └── TestMqttUnSubscribeHandler.java │ ├── rpc │ │ └── TestRpcPacketDispatcher.java │ └── ws │ │ ├── TestWebSocketEncoder.java │ │ └── TestWebSocketServerHandler.java │ └── session │ ├── TestQueueFresh.java │ ├── TestSession.java │ ├── infly │ ├── TestInFlyCache.java │ ├── TestMqttMsgId.java │ ├── TestPushAction.java │ └── TestRetryDriver.java │ ├── loop │ ├── TestQueueCache.java │ └── TestSessionLoopImpl.java │ ├── match │ └── TestMatchAction.java │ └── notify │ └── TestMessageNotifyAction.java ├── mqtt-ds ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── rocketmq │ │ └── mqtt │ │ └── ds │ │ ├── auth │ │ └── AuthManagerSample.java │ │ ├── config │ │ ├── ServiceConf.java │ │ └── ServiceConfListener.java │ │ ├── meta │ │ ├── FirstTopicManager.java │ │ ├── MetaPersistManagerSample.java │ │ ├── MetaRpcClient.java │ │ ├── RetainedMsgClient.java │ │ ├── RetainedPersistManagerImpl.java │ │ ├── TopicNotExistException.java │ │ ├── WildcardManager.java │ │ ├── WillMsgClient.java │ │ └── WillMsgPersistManagerImpl.java │ │ ├── mq │ │ ├── MqAdmin.java │ │ ├── MqConsumer.java │ │ ├── MqFactory.java │ │ ├── MqProducer.java │ │ └── MqPullConsumer.java │ │ ├── notify │ │ ├── NotifyManager.java │ │ └── NotifyRetryManager.java │ │ ├── store │ │ ├── LmqOffsetStoreManager.java │ │ └── LmqQueueStoreManager.java │ │ └── upstream │ │ ├── UpstreamProcessor.java │ │ ├── UpstreamProcessorManager.java │ │ └── processor │ │ ├── BaseProcessor.java │ │ ├── ConnectProcessor.java │ │ ├── DisconnectProcessor.java │ │ ├── PublishProcessor.java │ │ ├── SubscribeProcessor.java │ │ └── UnSubscribeProcessor.java │ └── test │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── ds │ └── test │ ├── auth │ └── TestAuthManagerSample.java │ ├── config │ └── TestServiceConfListener.java │ ├── meta │ ├── TestFirstTopicManager.java │ ├── TestMetaPersistManagerSample.java │ ├── TestWildcardManager.java │ └── WillMsgPersistManagerImplTest.java │ ├── mq │ └── TestMqFactory.java │ ├── notify │ ├── TestNotifyManager.java │ └── TestNotifyRetryManager.java │ ├── store │ ├── TestLmqOffsetStoreManager.java │ └── TestLmqQueueStoreManager.java │ └── upstream │ ├── TestUpstreamProcessorManager.java │ └── processor │ ├── TestPublishProcessor.java │ ├── TestSubscribeProcessor.java │ └── TestUnSubscribeProcessor.java ├── mqtt-example ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── example │ ├── MqttConsumer.java │ ├── MqttProducer.java │ ├── MqttWillRetainConsumer.java │ ├── MqttWillRetainProducer.java │ ├── RocketMQConsumer.java │ └── RocketMQProducer.java ├── mqtt-exporter ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── exporter │ ├── MqttExporter.java │ ├── collector │ ├── MetricsBuilderFactory.java │ ├── MqttMetricsCollector.java │ ├── MqttMetricsInfo.java │ └── SubSystem.java │ ├── exception │ └── PrometheusException.java │ └── http │ ├── BackedFileOutputStream.java │ └── MqttHTTPServer.java ├── mqtt-meta ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── apache │ │ └── rocketmq │ │ └── mqtt │ │ └── meta │ │ ├── config │ │ ├── MetaConf.java │ │ └── MetaConfListener.java │ │ ├── raft │ │ ├── FailoverClosure.java │ │ ├── MqttApplyListener.java │ │ ├── MqttClosure.java │ │ ├── MqttRaftServer.java │ │ ├── MqttStateMachine.java │ │ ├── processor │ │ │ ├── HashKvStateProcessor.java │ │ │ ├── RetainedMsgStateProcessor.java │ │ │ ├── StateProcessor.java │ │ │ └── WillMsgStateProcessor.java │ │ └── rpc │ │ │ ├── AbstractRpcProcessor.java │ │ │ ├── MqttReadRpcProcessor.java │ │ │ └── MqttWriteRpcProcessor.java │ │ ├── rocksdb │ │ ├── RocksDBEngine.java │ │ └── RocksDBSnapshot.java │ │ ├── starter │ │ └── MetaStartup.java │ │ └── util │ │ ├── DiskUtils.java │ │ └── SpringUtil.java │ └── test │ └── java │ └── org │ └── apache │ └── rocketmq │ └── mqtt │ └── meta │ ├── raft │ ├── RetainedMsgClientTest.java │ └── WillMsgStateProcessorTest.java │ └── util │ └── IpUtilTest.java ├── pom.xml └── style ├── copyright ├── Apache.xml └── profiles_settings.xml ├── rmq_checkstyle.xml └── rmq_codeStyle.xml /.asf.yaml: -------------------------------------------------------------------------------- 1 | github: 2 | features: 3 | # Enable issue management 4 | issues: true 5 | # Enable wiki 6 | wiki: true 7 | 8 | protected_branches: 9 | notifications: 10 | commits: commits@rocketmq.apache.org 11 | issues: commits@rocketmq.apache.org 12 | pullrequests: commits@rocketmq.apache.org 13 | jobs: commits@rocketmq.apache.org 14 | discussions: dev@rocketmq.apache.org 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | 3 | language: java 4 | 5 | matrix: 6 | include: 7 | # On OSX, run with default JDK only. 8 | # - os: osx 9 | # On Linux, run with specific JDKs only. 10 | - os: linux 11 | env: CUSTOM_JDK="oraclejdk8" 12 | 13 | before_install: 14 | - echo 'MAVEN_OPTS="$MAVEN_OPTS -Xmx1024m -XX:MaxPermSize=512m -XX:+BytecodeVerificationLocal"' >> ~/.mavenrc 15 | - cat ~/.mavenrc 16 | - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export JAVA_HOME=$(/usr/libexec/java_home); fi 17 | - if [ "$TRAVIS_OS_NAME" == "linux" ]; then jdk_switcher use "$CUSTOM_JDK"; fi 18 | 19 | script: 20 | - travis_retry mvn -B clean apache-rat:check 21 | - travis_retry mvn -B clean install cobertura:cobertura 22 | after_success: 23 | - bash <(curl -s https://codecov.io/bash) || echo 'Codecov failed to upload' 24 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache RocketMQ 2 | Copyright 2016-2022 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /distribution/bin/meta.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # /* 5 | # * Licensed to the Apache Software Foundation (ASF) under one or more 6 | # * contributor license agreements. See the NOTICE file distributed with 7 | # * this work for additional information regarding copyright ownership. 8 | # * The ASF licenses this file to You under the Apache License, Version 2.0 9 | # * (the "License"); you may not use this file except in compliance with 10 | # * the License. You may obtain a copy of the License at 11 | # * 12 | # * http://www.apache.org/licenses/LICENSE-2.0 13 | # * 14 | # * Unless required by applicable law or agreed to in writing, software 15 | # * distributed under the License is distributed on an "AS IS" BASIS, 16 | # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # * See the License for the specific language governing permissions and 18 | # * limitations under the License. 19 | # */ 20 | # 21 | 22 | if [ -z "$ROCKETMQ_MQTT_HOME" ]; then 23 | ## resolve links - $0 may be a link to maven's home 24 | PRG="$0" 25 | 26 | # need this for relative symlinks 27 | while [ -h "$PRG" ]; do 28 | ls=$(ls -ld "$PRG") 29 | link=$(expr "$ls" : '.*-> \(.*\)$') 30 | if expr "$link" : '/.*' >/dev/null; then 31 | PRG="$link" 32 | else 33 | PRG="$(dirname "$PRG")/$link" 34 | fi 35 | done 36 | 37 | saveddir=$(pwd) 38 | 39 | ROCKETMQ_MQTT_HOME=$(dirname "$PRG")/.. 40 | 41 | # make it fully qualified 42 | ROCKETMQ_MQTT_HOME=$(cd "$ROCKETMQ_MQTT_HOME" && pwd) 43 | 44 | cd "$saveddir" 45 | fi 46 | 47 | export ROCKETMQ_MQTT_HOME 48 | 49 | BASEDIR=$HOME 50 | mkdir -p $BASEDIR/logs 51 | 52 | mainClass="org.apache.rocketmq.mqtt.meta.starter.MetaStartup" 53 | 54 | 55 | function startup() { 56 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 57 | if [ ! -z "$pid" ]; then 58 | echo "java is runing..." 59 | exit 1 60 | fi 61 | nohup sh ${ROCKETMQ_MQTT_HOME}/bin/runserver.sh $mainClass $@ >$BASEDIR/logs/start_out.log 2>&1 & 62 | } 63 | 64 | function stop() { 65 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 66 | if [ -z "$pid" ]; then 67 | echo "no java to kill" 68 | fi 69 | printf 'stop...' 70 | kill $pid 71 | sleep 3 72 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 73 | 74 | if [ ! -z $pid ]; then 75 | kill -9 $pid 76 | fi 77 | } 78 | 79 | case "$1" in 80 | start) 81 | startup $@ 82 | ;; 83 | stop) 84 | stop 85 | ;; 86 | restart) 87 | stop 88 | startup 89 | ;; 90 | *) 91 | printf "Usage: sh $0 %s {start|stop|restart}\n" 92 | exit 1 93 | ;; 94 | esac -------------------------------------------------------------------------------- /distribution/bin/mqtt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # /* 5 | # * Licensed to the Apache Software Foundation (ASF) under one or more 6 | # * contributor license agreements. See the NOTICE file distributed with 7 | # * this work for additional information regarding copyright ownership. 8 | # * The ASF licenses this file to You under the Apache License, Version 2.0 9 | # * (the "License"); you may not use this file except in compliance with 10 | # * the License. You may obtain a copy of the License at 11 | # * 12 | # * http://www.apache.org/licenses/LICENSE-2.0 13 | # * 14 | # * Unless required by applicable law or agreed to in writing, software 15 | # * distributed under the License is distributed on an "AS IS" BASIS, 16 | # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # * See the License for the specific language governing permissions and 18 | # * limitations under the License. 19 | # */ 20 | # 21 | 22 | if [ -z "$ROCKETMQ_MQTT_HOME" ]; then 23 | ## resolve links - $0 may be a link to maven's home 24 | PRG="$0" 25 | 26 | # need this for relative symlinks 27 | while [ -h "$PRG" ]; do 28 | ls=$(ls -ld "$PRG") 29 | link=$(expr "$ls" : '.*-> \(.*\)$') 30 | if expr "$link" : '/.*' >/dev/null; then 31 | PRG="$link" 32 | else 33 | PRG="$(dirname "$PRG")/$link" 34 | fi 35 | done 36 | 37 | saveddir=$(pwd) 38 | 39 | ROCKETMQ_MQTT_HOME=$(dirname "$PRG")/.. 40 | 41 | # make it fully qualified 42 | ROCKETMQ_MQTT_HOME=$(cd "$ROCKETMQ_MQTT_HOME" && pwd) 43 | 44 | cd "$saveddir" 45 | fi 46 | 47 | export ROCKETMQ_MQTT_HOME 48 | 49 | BASEDIR=$HOME 50 | mkdir -p $BASEDIR/logs 51 | 52 | mainClass="org.apache.rocketmq.mqtt.cs.starter.Startup" 53 | 54 | function startup() { 55 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 56 | if [ ! -z "$pid" ]; then 57 | echo "java is runing..." 58 | exit 1 59 | fi 60 | nohup sh ${ROCKETMQ_MQTT_HOME}/bin/runserver.sh $mainClass $@ >$BASEDIR/logs/start_out.log 2>&1 & 61 | } 62 | 63 | function stop() { 64 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 65 | if [ -z "$pid" ]; then 66 | echo "no java to kill" 67 | fi 68 | printf 'stop...' 69 | kill $pid 70 | sleep 3 71 | pid=`ps aux|grep $mainClass|grep -v grep |awk '{print $2}'` 72 | 73 | if [ ! -z $pid ]; then 74 | kill -9 $pid 75 | fi 76 | } 77 | 78 | case "$1" in 79 | start) 80 | startup $@ 81 | ;; 82 | stop) 83 | stop 84 | ;; 85 | restart) 86 | stop 87 | startup 88 | ;; 89 | *) 90 | printf "Usage: sh $0 %s {start|stop|restart}\n" 91 | exit 1 92 | ;; 93 | esac 94 | -------------------------------------------------------------------------------- /distribution/conf/connect.conf: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | mqttPort=1883 18 | 19 | enablePrometheus=true -------------------------------------------------------------------------------- /distribution/conf/meta.conf: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | selfAddress= 18 | membersAddress= 19 | -------------------------------------------------------------------------------- /distribution/conf/meta_spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /distribution/conf/service.conf: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | username= 18 | secretKey= 19 | 20 | NAMESRV_ADDR= 21 | eventNotifyRetryTopic= 22 | clientRetryTopic= 23 | 24 | metaAddr= -------------------------------------------------------------------------------- /distribution/conf/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /distribution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rocketmq-mqtt 5 | org.apache.rocketmq 6 | 1.0.2-SNAPSHOT 7 | 8 | 4.0.0 9 | pom 10 | distribution 11 | 12 | 13 | UTF-8 14 | 15 | 16 | 17 | 18 | release-all 19 | 20 | 21 | org.apache.rocketmq 22 | mqtt-cs 23 | 24 | 25 | org.apache.rocketmq 26 | mqtt-ds 27 | 28 | 29 | org.apache.rocketmq 30 | mqtt-example 31 | 32 | 33 | org.apache.rocketmq 34 | mqtt-exporter 35 | 36 | 37 | 38 | 39 | 40 | maven-assembly-plugin 41 | 42 | 43 | release-all 44 | 45 | single 46 | 47 | package 48 | 49 | 50 | release.xml 51 | 52 | false 53 | 54 | 55 | 56 | 57 | 58 | rocketmq-mqtt-${project.version} 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /distribution/release.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | all 20 | true 21 | 22 | dir 23 | tar.gz 24 | zip 25 | 26 | 27 | 28 | ../ 29 | 30 | README.md 31 | 32 | 33 | 34 | 35 | 36 | conf/** 37 | 38 | 39 | 40 | 41 | 42 | bin/** 43 | 44 | 0755 45 | 46 | 47 | 48 | 49 | 50 | true 51 | 52 | org.apache.rocketmq:mqtt-cs 53 | org.apache.rocketmq:mqtt-ds 54 | org.apache.rocketmq:mqtt-meta 55 | 56 | 57 | lib 58 | false 59 | 60 | 61 | lib 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/AuthManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 22 | 23 | public interface AuthManager { 24 | /** 25 | * MQTT packet authentication 26 | * 27 | * @param message 28 | * @return 29 | */ 30 | HookResult doAuth(MqttMessage message); 31 | } 32 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/LmqOffsetStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import org.apache.rocketmq.mqtt.common.model.Queue; 21 | import org.apache.rocketmq.mqtt.common.model.QueueOffset; 22 | import org.apache.rocketmq.mqtt.common.model.Subscription; 23 | 24 | import java.util.Map; 25 | import java.util.concurrent.CompletableFuture; 26 | 27 | public interface LmqOffsetStore { 28 | /** 29 | * save lmq offset 30 | * @param clientId 31 | * @param offsetMap 32 | */ 33 | void save(String clientId, Map> offsetMap); 34 | 35 | /** 36 | * get lmq offset 37 | * @param clientId 38 | * @param subscription 39 | * @return 40 | */ 41 | CompletableFuture> getOffset(String clientId, Subscription subscription); 42 | } 43 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/MetaPersistManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import java.util.Set; 21 | 22 | public interface MetaPersistManager { 23 | 24 | /** 25 | * get wildcards of the first topic 26 | * @param firstTopic 27 | * @return 28 | */ 29 | Set getWildcards(String firstTopic); 30 | 31 | /** 32 | * get all first topics 33 | * @return 34 | */ 35 | Set getAllFirstTopics(); 36 | 37 | /** 38 | * get all connect nodes 39 | * @return 40 | */ 41 | Set getConnectNodeSet(); 42 | } 43 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/RetainedPersistManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import org.apache.rocketmq.mqtt.common.model.Message; 21 | 22 | import java.util.ArrayList; 23 | import java.util.concurrent.CompletableFuture; 24 | 25 | public interface RetainedPersistManager { 26 | 27 | 28 | CompletableFuture storeRetainedMessage(String topic, Message message); 29 | 30 | CompletableFuture getRetainedMessage(String preciseTopic); 31 | 32 | CompletableFuture> getMsgsFromTrie(String firstTopic,String originTopicFilter); 33 | } 34 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/SubscriptionPersistManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import org.apache.rocketmq.mqtt.common.model.Subscription; 21 | 22 | import java.util.Set; 23 | import java.util.concurrent.CompletableFuture; 24 | 25 | public interface SubscriptionPersistManager { 26 | /** 27 | * loadSubscriptions 28 | * 29 | * @param clientId 30 | * @return 31 | */ 32 | CompletableFuture> loadSubscriptions(String clientId); 33 | 34 | /** 35 | * loadSubscribers 36 | * 37 | * @param topic 38 | * @return 39 | */ 40 | CompletableFuture> loadSubscribers(String topic); 41 | 42 | /** 43 | * saveSubscriptions 44 | * 45 | * @param clientId 46 | * @param subscriptions 47 | */ 48 | void saveSubscriptions(String clientId, Set subscriptions); 49 | 50 | /** 51 | * saveSubscribers 52 | * 53 | * @param topic 54 | * @param clientIds 55 | */ 56 | void saveSubscribers(String topic, Set clientIds); 57 | 58 | /** 59 | * removeSubscriptions 60 | * 61 | * @param clientId 62 | * @param subscriptions 63 | */ 64 | void removeSubscriptions(String clientId, Set subscriptions); 65 | 66 | /** 67 | * removeSubscriptions 68 | * 69 | * @param topic 70 | * @param clientIds 71 | */ 72 | void removeSubscribers(String topic, Set clientIds); 73 | } 74 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/WillMsgPersistManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import java.util.Map; 21 | import java.util.concurrent.CompletableFuture; 22 | 23 | public interface WillMsgPersistManager { 24 | 25 | CompletableFuture put(final String key, final String value); 26 | 27 | CompletableFuture delete(final String key); 28 | 29 | CompletableFuture get(final String key); 30 | 31 | CompletableFuture compareAndPut(final String key, final String expectValue, final String updateValue); 32 | 33 | CompletableFuture> scan(final String startKey, final String endKey, int scanNum); 34 | } 35 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/facade/WillMsgSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.facade; 19 | 20 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 21 | import org.apache.rocketmq.mqtt.common.model.StoreResult; 22 | 23 | import java.util.concurrent.CompletableFuture; 24 | 25 | public interface WillMsgSender { 26 | CompletableFuture sendWillMsg(String clientId, MqttPublishMessage message); 27 | } 28 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/hook/AbstractUpstreamHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.hook; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import java.util.concurrent.CompletableFuture; 25 | 26 | 27 | public abstract class AbstractUpstreamHook implements UpstreamHook { 28 | public static Logger logger = LoggerFactory.getLogger(AbstractUpstreamHook.class); 29 | public UpstreamHook nextUpstreamHook; 30 | 31 | @Override 32 | public void setNextHook(Hook hook) { 33 | this.nextUpstreamHook = (UpstreamHook) hook; 34 | } 35 | 36 | @Override 37 | public Hook getNextHook() { 38 | return this.nextUpstreamHook; 39 | } 40 | 41 | @Override 42 | public CompletableFuture doHook(MqttMessageUpContext context, MqttMessage msg) { 43 | try { 44 | CompletableFuture result = processMqttMessage(context,msg); 45 | if (nextUpstreamHook == null) { 46 | return result; 47 | } 48 | return result.thenCompose(hookResult -> { 49 | if (!hookResult.isSuccess()) { 50 | CompletableFuture nextHookResult = new CompletableFuture<>(); 51 | nextHookResult.complete(hookResult); 52 | return nextHookResult; 53 | } 54 | return nextUpstreamHook.doHook(context, msg); 55 | }); 56 | } catch (Throwable t) { 57 | logger.error("",t); 58 | CompletableFuture result = new CompletableFuture<>(); 59 | result.completeExceptionally(t); 60 | return result; 61 | } 62 | } 63 | 64 | public abstract void register(); 65 | 66 | public abstract CompletableFuture processMqttMessage(MqttMessageUpContext context, MqttMessage message) ; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/hook/Hook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.hook; 19 | 20 | public interface Hook { 21 | /** 22 | * set next hook 23 | * 24 | * @param hook 25 | */ 26 | void setNextHook(Hook hook); 27 | 28 | /** 29 | * get next hook 30 | * 31 | * @return 32 | */ 33 | Hook getNextHook(); 34 | } 35 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/hook/UpstreamHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.hook; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 22 | 23 | import java.util.concurrent.CompletableFuture; 24 | 25 | public interface UpstreamHook extends Hook { 26 | 27 | /** 28 | * do hook in upstream 29 | * @param context 30 | * @param msg 31 | * @return 32 | */ 33 | CompletableFuture doHook(MqttMessageUpContext context, MqttMessage msg); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/hook/UpstreamHookEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.hook; 19 | 20 | public enum UpstreamHookEnum { 21 | AUTH, 22 | UPSTREAM_PROCESS 23 | } 24 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/hook/UpstreamHookManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.hook; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 22 | 23 | import java.util.concurrent.CompletableFuture; 24 | 25 | public interface UpstreamHookManager { 26 | /** 27 | * add a hook 28 | * 29 | * @param index 30 | * @param upstreamHook 31 | */ 32 | void addHook(int index, UpstreamHook upstreamHook); 33 | 34 | /** 35 | * do hook in upstream 36 | * 37 | * @param context 38 | * @param msg 39 | * @return 40 | */ 41 | CompletableFuture doUpstreamHook(MqttMessageUpContext context, MqttMessage msg); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/meta/MetaConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.meta; 19 | 20 | public class MetaConstants { 21 | 22 | public static final String CATEGORY_RETAINED_MSG = "retainedMsg"; 23 | public static final String CATEGORY_WILL_MSG = "willMsg"; 24 | public static final String CATEGORY_HASH_KV = "hashKv"; 25 | 26 | public static final String NOT_FOUND = "NOT_FOUND"; 27 | 28 | public static final String READ_INDEX_TYPE = "readIndexType"; 29 | public static final String ANY_READ_TYPE = "anyRead"; 30 | 31 | public static final String OP_KV_GET = "get"; 32 | public static final String OP_KV_GET_HASH = "getHash"; 33 | public static final String OP_HASH_KV_FIELD = "field"; 34 | public static final String OP_KV_PUT = "put"; 35 | public static final String OP_KV_PUT_HASH = "putHash"; 36 | public static final String OP_KV_DEL = "del"; 37 | public static final String OP_KV_DEL_HASH = "delHash"; 38 | 39 | public static final String RETAIN_REQ_READ_PARAM_TOPIC = "topic"; 40 | public static final String RETAIN_REQ_READ_PARAM_FIRST_TOPIC = "firstTopic"; 41 | public static final String RETAIN_REQ_READ_PARAM_OPERATION_TRIE = "trie"; 42 | public static final String RETAIN_REQ_READ_PARAM_OPERATION_TOPIC = "topic"; 43 | 44 | public static final String RETAIN_REQ_WRITE_PARAM_FIRST_TOPIC = "firstTopic"; 45 | public static final String RETAIN_REQ_WRITE_PARAM_TOPIC = "topic"; 46 | public static final String RETAIN_REQ_WRITE_PARAM_IS_EMPTY = "isEmpty"; 47 | public static final String RETAIN_REQ_WRITE_PARAM_EXPIRE = "expire"; 48 | 49 | public static final String WILL_REQ_READ_GET = "get"; 50 | public static final String WILL_REQ_READ_SCAN = "scan"; 51 | public static final String WILL_REQ_READ_SCAN_NUM = "scanNum"; 52 | public static final String WILL_REQ_READ_START_KEY = "startKey"; 53 | public static final String WILL_REQ_READ_END_KEY = "endKey"; 54 | 55 | public static final String WILL_REQ_WRITE_PUT = "put"; 56 | public static final String WILL_REQ_WRITE_DELETE = "delete"; 57 | 58 | public static final String WILL_REQ_WRITE_COMPARE_AND_PUT = "compareAndPut"; 59 | public static final String WILL_REQ_WRITE_EXPECT_VALUE = "expectValue"; 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/meta/RaftUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.meta; 19 | 20 | import org.apache.commons.lang3.SystemUtils; 21 | 22 | import java.io.File; 23 | 24 | public class RaftUtil { 25 | public static final String RAFT_GROUP_NAME_PREFIX = "RAFT_GROUP_"; 26 | public static final int RAFT_GROUP_NUM = 3; 27 | public static final String[] RAFT_GROUPS; 28 | 29 | public static final int RETAIN_RAFT_GROUP_INDEX = 0; 30 | public static final int WILL_RAFT_GROUP_INDEX = 1; 31 | public static final int HASH_KV_RAFT_GROUP_INDEX = 2; 32 | 33 | static { 34 | RAFT_GROUPS = new String[RAFT_GROUP_NUM]; 35 | for (int i = 0; i < RAFT_GROUP_NUM; i++) { 36 | RAFT_GROUPS[i] = RAFT_GROUP_NAME_PREFIX + i; 37 | } 38 | } 39 | 40 | public static String RAFT_BASE_DIR(String group) { 41 | String metaBaseDir = SystemUtils.USER_HOME; 42 | if (System.getenv("META_BASE_DIR") != null) { 43 | metaBaseDir = System.getenv("META_BASE_DIR"); 44 | } 45 | return metaBaseDir + File.separator + "raft" + File.separator + group; 46 | } 47 | 48 | public static String[] LIST_RAFT_GROUPS() { 49 | return RAFT_GROUPS; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class Constants { 21 | public static final String NAMESPACE_SPLITER = "%"; 22 | public static final String MQTT_TOPIC_DELIMITER = "/"; 23 | 24 | public static final String PLUS_SIGN = "+"; 25 | public static final String NUMBER_SIGN = "#"; 26 | public static final String DOLLAR_SIGN = "$"; 27 | public static final String COLON = ":"; 28 | 29 | public static final String P2P = "/p2p/"; 30 | public static final String RETRY = "/retry/"; 31 | 32 | public static final String PROPERTY_NAMESPACE = "namespace"; 33 | public static final String PROPERTY_ORIGIN_MQTT_TOPIC = "originMqttTopic"; 34 | public static final String PROPERTY_MQTT_QOS = "qosLevel"; 35 | public static final String PROPERTY_MQTT_CLEAN_SESSION = "cleanSessionFlag"; 36 | public static final String PROPERTY_MQTT_CLIENT = "clientId"; 37 | public static final String PROPERTY_MQTT_RETRY_TIMES = "retryTimes"; 38 | public static final String PROPERTY_MQTT_EXT_DATA = "extData"; 39 | 40 | 41 | public static final String PROPERTY_MQTT_MSG_EVENT_RETRY_NODE = "retryNode"; 42 | public static final String PROPERTY_MQTT_MSG_EVENT_RETRY_TIME = "retryTime"; 43 | 44 | public static final String MQTT_TAG = "MQTT_COMMON"; 45 | 46 | public static final String PROPERTY_ORIGIN_MQTT_ISEMPTY_MSG = "IS_EMPTY_MSG"; 47 | 48 | public static final String CS_ALIVE = "alive"; 49 | 50 | public static final String CS_MASTER = "master"; 51 | 52 | public static final byte CTRL_0 = '\u0000'; 53 | 54 | public static final byte CTRL_1 = '\u0001'; 55 | 56 | public static final byte CTRL_2 = '\u0002'; 57 | 58 | public static final String NOT_FOUND = "NOT_FOUND"; 59 | public static final String SHARED_PREFIX = DOLLAR_SIGN + "share"; 60 | public static final String EMPTY_SHARE_NAME = ""; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/MessageEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | import java.util.Objects; 21 | 22 | 23 | public class MessageEvent { 24 | private String pubTopic; 25 | private String namespace; 26 | private long queueId; 27 | private String brokerName; 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (this == o) { 32 | return true; 33 | } 34 | if (o == null || getClass() != o.getClass()) { 35 | return false; 36 | } 37 | MessageEvent that = (MessageEvent) o; 38 | return Objects.equals(pubTopic, that.pubTopic) && Objects.equals(namespace, that.namespace) && Objects.equals(queueId, that.queueId) && Objects.equals(brokerName, that.brokerName); 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return Objects.hash(pubTopic, namespace, queueId, brokerName); 44 | } 45 | 46 | public String getPubTopic() { 47 | return pubTopic; 48 | } 49 | 50 | public void setPubTopic(String pubTopic) { 51 | this.pubTopic = pubTopic; 52 | } 53 | 54 | public String getNamespace() { 55 | return namespace; 56 | } 57 | 58 | public void setNamespace(String namespace) { 59 | this.namespace = namespace; 60 | } 61 | 62 | public long getQueueId() { 63 | return queueId; 64 | } 65 | 66 | public void setQueueId(long queueId) { 67 | this.queueId = queueId; 68 | } 69 | 70 | public String getBrokerName() { 71 | return brokerName; 72 | } 73 | 74 | public void setBrokerName(String brokerName) { 75 | this.brokerName = brokerName; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/MqttMessageUpContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class MqttMessageUpContext { 21 | private String namespace; 22 | private String clientId; 23 | private String channelId; 24 | private String node; 25 | 26 | public String getNamespace() { 27 | return namespace; 28 | } 29 | 30 | public void setNamespace(String namespace) { 31 | this.namespace = namespace; 32 | } 33 | 34 | public String getClientId() { 35 | return clientId; 36 | } 37 | 38 | public void setClientId(String clientId) { 39 | this.clientId = clientId; 40 | } 41 | 42 | public String getChannelId() { 43 | return channelId; 44 | } 45 | 46 | public void setChannelId(String channelId) { 47 | this.channelId = channelId; 48 | } 49 | 50 | public String getNode() { 51 | return node; 52 | } 53 | 54 | public void setNode(String node) { 55 | this.node = node; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/MqttTopic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | 21 | public class MqttTopic { 22 | private String firstTopic; 23 | private String secondTopic; 24 | 25 | public MqttTopic(String firstTopic, String secondTopic) { 26 | this.firstTopic = firstTopic; 27 | this.secondTopic = secondTopic; 28 | } 29 | 30 | public String getFirstTopic() { 31 | return firstTopic; 32 | } 33 | 34 | public void setFirstTopic(String firstTopic) { 35 | this.firstTopic = firstTopic; 36 | } 37 | 38 | public String getSecondTopic() { 39 | return secondTopic; 40 | } 41 | 42 | public void setSecondTopic(String secondTopic) { 43 | this.secondTopic = secondTopic; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/PullResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | 21 | import java.util.List; 22 | 23 | 24 | public class PullResult { 25 | public static final int PULL_SUCCESS = 301; 26 | public static final int PULL_OFFSET_MOVED = 302; 27 | public static final int NO_NEW_MSG = 303; 28 | private int code = PULL_SUCCESS; 29 | private String remark; 30 | private List messageList; 31 | private QueueOffset nextQueueOffset; 32 | 33 | public int getCode() { 34 | return code; 35 | } 36 | 37 | public void setCode(int code) { 38 | this.code = code; 39 | } 40 | 41 | public String getRemark() { 42 | return remark; 43 | } 44 | 45 | public void setRemark(String remark) { 46 | this.remark = remark; 47 | } 48 | 49 | public List getMessageList() { 50 | return messageList; 51 | } 52 | 53 | public void setMessageList(List messageList) { 54 | this.messageList = messageList; 55 | } 56 | 57 | public QueueOffset getNextQueueOffset() { 58 | return nextQueueOffset; 59 | } 60 | 61 | public void setNextQueueOffset(QueueOffset nextQueueOffset) { 62 | this.nextQueueOffset = nextQueueOffset; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/QueueOffset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | import java.util.Objects; 21 | 22 | 23 | public class QueueOffset { 24 | private volatile long offset = Long.MAX_VALUE; 25 | private volatile byte initializingStatus = -1; 26 | 27 | public QueueOffset() { 28 | } 29 | 30 | public QueueOffset(long offset) { 31 | this.offset = offset; 32 | } 33 | 34 | public boolean isInitialized() { 35 | return offset != Long.MAX_VALUE || initializingStatus == 1; 36 | } 37 | 38 | public boolean isInitializing() { 39 | return initializingStatus == 0; 40 | } 41 | 42 | public void setInitialized() { 43 | initializingStatus = 1; 44 | } 45 | 46 | public void setInitializing() { 47 | initializingStatus = 0; 48 | } 49 | 50 | public long getOffset() { 51 | return offset; 52 | } 53 | 54 | public void setOffset(long offset) { 55 | this.offset = offset; 56 | } 57 | 58 | @Override 59 | public boolean equals(Object o) { 60 | if (this == o) return true; 61 | if (o == null || getClass() != o.getClass()) return false; 62 | QueueOffset that = (QueueOffset) o; 63 | return offset == that.offset && initializingStatus == that.initializingStatus; 64 | } 65 | 66 | @Override 67 | public int hashCode() { 68 | return Objects.hash(offset, initializingStatus); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/Remark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | 21 | public class Remark { 22 | 23 | public static final String SUCCESS = "success"; 24 | public static final String FAIL = "fail"; 25 | public static final String CLIENT_ID_CONFLICT = "clientIdConflict"; 26 | public static final String INVALID_PARAM = "Invalid Param"; 27 | public static final String AUTH_FAILED = "Auth Failed"; 28 | public static final String OVERFLOW = "overflow"; 29 | public static final String EXCEPTION = "exception"; 30 | public static final String EXPIRED = "expire"; 31 | } 32 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/RpcCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class RpcCode { 21 | public static final int SUCCESS = 1; 22 | public static final int FAIL = -1; 23 | 24 | public static final int CMD_NOTIFY_MQTT_MESSAGE = 201; 25 | public static final int CMD_CLOSE_CHANNEL = 203; 26 | } 27 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/RpcHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class RpcHeader { 21 | public static final String MQTT_CHANNEL_ID = "channelId"; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/StoreResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class StoreResult { 21 | private Queue queue; 22 | private String msgId; 23 | 24 | public Queue getQueue() { 25 | return queue; 26 | } 27 | 28 | public void setQueue(Queue queue) { 29 | this.queue = queue; 30 | } 31 | 32 | public String getMsgId() { 33 | return msgId; 34 | } 35 | 36 | public void setMsgId(String msgId) { 37 | this.msgId = msgId; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/TrieException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | public class TrieException extends RuntimeException { 21 | public TrieException() { } 22 | 23 | public TrieException(String message) { 24 | super(message); 25 | } 26 | 27 | public TrieException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public TrieException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public TrieException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 36 | super(message, cause, enableSuppression, writableStackTrace); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/TrieMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | 21 | public interface TrieMethod { 22 | 23 | /** 24 | * doMethod 25 | * 26 | * @param path 27 | * @param nodeKey 28 | */ 29 | void doMethod(String path, K nodeKey); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/model/WillMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.model; 19 | 20 | import java.util.Arrays; 21 | 22 | public class WillMessage { 23 | 24 | private String willTopic; 25 | 26 | private byte[] body; 27 | 28 | private boolean retain; 29 | 30 | private int qos; 31 | 32 | public WillMessage(String willTopic, byte[] body, boolean retain, int qos) { 33 | this.willTopic = willTopic; 34 | this.body = body; 35 | this.retain = retain; 36 | this.qos = qos; 37 | } 38 | 39 | public String getWillTopic() { 40 | return willTopic; 41 | } 42 | 43 | public void setWillTopic(String willTopic) { 44 | this.willTopic = willTopic; 45 | } 46 | 47 | public byte[] getBody() { 48 | return body; 49 | } 50 | 51 | public void setBody(byte[] body) { 52 | this.body = body; 53 | } 54 | 55 | public boolean isRetain() { 56 | return retain; 57 | } 58 | 59 | public void setRetain(boolean retain) { 60 | this.retain = retain; 61 | } 62 | 63 | public int getQos() { 64 | return qos; 65 | } 66 | 67 | public void setQos(int qos) { 68 | this.qos = qos; 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "WillMessage{" + 74 | "willTopic='" + willTopic + '\'' + 75 | ", body=" + Arrays.toString(body) + 76 | ", retain=" + retain + 77 | ", qos=" + qos + 78 | '}'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/util/HmacSHA1Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.util; 19 | 20 | import org.apache.commons.codec.binary.Base64; 21 | 22 | import javax.crypto.Mac; 23 | import javax.crypto.spec.SecretKeySpec; 24 | import java.nio.charset.Charset; 25 | import java.security.InvalidKeyException; 26 | import java.security.NoSuchAlgorithmException; 27 | 28 | public class HmacSHA1Util { 29 | private static Charset charset = Charset.forName("UTF-8"); 30 | private static String algorithm = "HmacSHA1"; 31 | 32 | public static String macSignature(String text, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException { 33 | Mac mac = Mac.getInstance(algorithm); 34 | mac.init(new SecretKeySpec(secretKey.getBytes(charset), algorithm)); 35 | byte[] bytes = mac.doFinal(text.getBytes(charset)); 36 | return new String(Base64.encodeBase64(bytes), charset); 37 | } 38 | 39 | public static boolean validateSign(String text, byte[] input, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException { 40 | String sign = macSignature(text, secretKey); 41 | return sign.equals(new String(input, charset)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/util/HostInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.util; 19 | 20 | import java.net.InetAddress; 21 | import java.net.UnknownHostException; 22 | 23 | public class HostInfo { 24 | private final String hostName; 25 | private final String hostAddress; 26 | 27 | private static final HostInfo INSTALL = new HostInfo(); 28 | 29 | public static HostInfo getInstall() { 30 | return INSTALL; 31 | } 32 | 33 | private HostInfo() { 34 | String hostName; 35 | String hostAddress; 36 | try { 37 | InetAddress localhost = InetAddress.getLocalHost(); 38 | hostName = localhost.getHostName(); 39 | hostAddress = localhost.getHostAddress(); 40 | } catch (UnknownHostException e) { 41 | throw new RuntimeException(e); 42 | } 43 | this.hostName = hostName; 44 | this.hostAddress = hostAddress; 45 | } 46 | 47 | public final String getName() { 48 | return this.hostName; 49 | } 50 | 51 | public final String getAddress() { 52 | return this.hostAddress; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/util/NamespaceUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.util; 19 | 20 | import org.apache.commons.lang3.StringUtils; 21 | 22 | public class NamespaceUtil { 23 | public static final String NAMESPACE_SPLITER = "%"; 24 | private static final int RESOURCE_LENGTH = 2; 25 | public static final String MQ_DEFAULT_NAMESPACE_NAME = "DEFAULT_INSTANCE"; 26 | 27 | public static String encodeToNamespaceResource(String namespace, String resource) { 28 | return resource != null && namespace != null ? StringUtils.join(namespace, NAMESPACE_SPLITER, resource) : resource; 29 | } 30 | 31 | public static String decodeOriginResource(String resource) { 32 | if (resource != null && resource.contains(NAMESPACE_SPLITER)) { 33 | int firstIndex = resource.indexOf(NAMESPACE_SPLITER); 34 | return resource.substring(firstIndex + 1); 35 | } 36 | return resource; 37 | } 38 | 39 | public static String decodeMqttNamespaceIdFromKey(String key) { 40 | return decodeMqttNamespaceIdFromClientId(key); 41 | } 42 | 43 | public static String decodeMqttNamespaceIdFromClientId(String clientId) { 44 | return splitNamespaceStr(clientId); 45 | } 46 | 47 | public static String decodeStoreNamespaceIdFromTopic(String topic) { 48 | return splitNamespaceStr(topic); 49 | } 50 | 51 | public static String decodeNamespaceId(String resource) { 52 | return splitNamespaceStr(resource); 53 | } 54 | 55 | private static String splitNamespaceStr(String namespaceStr) { 56 | return namespaceStr != null && namespaceStr.contains(NAMESPACE_SPLITER) ? namespaceStr.split(NAMESPACE_SPLITER)[0] : null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /mqtt-common/src/main/java/org/apache/rocketmq/mqtt/common/util/SpringUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.util; 19 | 20 | import org.springframework.beans.BeansException; 21 | import org.springframework.context.support.ClassPathXmlApplicationContext; 22 | 23 | public class SpringUtils { 24 | private static ClassPathXmlApplicationContext applicationContext; 25 | 26 | public static void SetClassPathXmlApplicationContext(ClassPathXmlApplicationContext applicationContext) { 27 | SpringUtils.applicationContext = applicationContext; 28 | } 29 | 30 | public static T getBean(Class type) { 31 | if (applicationContext == null) { 32 | return null; 33 | } 34 | 35 | try { 36 | return applicationContext.getBean(type); 37 | } catch (BeansException e) { 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mqtt-common/src/main/proto/request.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | syntax = "proto3"; 19 | 20 | option java_multiple_files = true; 21 | option java_package = "org.apache.rocketmq.mqtt.common.model.consistency"; 22 | 23 | message WriteRequest { 24 | string group = 1; 25 | string key = 2; 26 | bytes data = 3; 27 | string type = 4; 28 | string operation = 5; 29 | map extData = 6; 30 | string category = 7; 31 | } 32 | 33 | message ReadRequest { 34 | string group = 1; 35 | string key = 2; 36 | string type = 3; 37 | string operation = 4; 38 | map extData = 5; 39 | string category = 6; 40 | } 41 | 42 | message Response { 43 | bytes data = 1; 44 | string errMsg = 2; 45 | bool success = 3; 46 | repeated bytes datalist = 4; 47 | map dataMap = 5; 48 | } 49 | 50 | message StoreMessage { 51 | string msgId = 1; 52 | string firstTopic = 2; 53 | string originTopic = 3; 54 | int64 offset = 4; 55 | int64 nextOffset = 5; 56 | int32 retry = 6; 57 | bool retained = 7; 58 | bool isEmpty = 8; 59 | bytes payload = 9; 60 | int64 bornTimestamp = 10; 61 | int64 storeTimestamp = 11; 62 | int32 ack = 12; 63 | map userProperties = 13; 64 | } 65 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/hook/TestAbstractUpstreamHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.hook; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.hook.AbstractUpstreamHook; 22 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 23 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 24 | import org.apache.rocketmq.mqtt.common.model.Remark; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.mockito.Mock; 28 | import org.mockito.junit.MockitoJUnitRunner; 29 | 30 | import java.util.concurrent.CompletableFuture; 31 | import java.util.concurrent.ExecutionException; 32 | 33 | import static org.junit.Assert.assertEquals; 34 | 35 | @RunWith(MockitoJUnitRunner.class) 36 | public class TestAbstractUpstreamHook { 37 | private final int code = -200; 38 | private final String remark = Remark.FAIL; 39 | 40 | @Mock 41 | private MqttMessageUpContext context; 42 | 43 | @Mock 44 | private MqttMessage mqttMessage; 45 | 46 | private AbstractUpstreamHook upstreamHook = new AbstractUpstreamHook() { 47 | @Override 48 | public void register() { 49 | } 50 | 51 | @Override 52 | public CompletableFuture processMqttMessage(MqttMessageUpContext context, MqttMessage message) { 53 | return HookResult.newHookResult(code, remark, null); 54 | } 55 | }; 56 | 57 | @Test 58 | public void test() throws ExecutionException, InterruptedException { 59 | CompletableFuture future = upstreamHook.doHook(context, mqttMessage); 60 | assertEquals(code, future.get().getCode()); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/hook/TestHookResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.hook; 19 | 20 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 21 | import org.junit.Test; 22 | 23 | import java.util.concurrent.CompletableFuture; 24 | import java.util.concurrent.ExecutionException; 25 | 26 | import static org.junit.Assert.assertEquals; 27 | import static org.junit.Assert.assertTrue; 28 | 29 | public class TestHookResult { 30 | private final int code = 200; 31 | private final int subCode = 200; 32 | private final String remark = "test"; 33 | 34 | @Test 35 | public void test() throws ExecutionException, InterruptedException { 36 | HookResult hookResult = new HookResult(code, remark, null); 37 | CompletableFuture future = HookResult.newHookResult(code, remark, null); 38 | assertEquals(hookResult, future.get()); 39 | assertTrue(future.isDone()); 40 | 41 | hookResult = new HookResult(code, subCode, remark, null); 42 | future = HookResult.newHookResult(code, subCode, remark, null); 43 | assertEquals(hookResult, future.get()); 44 | assertTrue(future.isDone()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/model/TestQueueOffset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.model; 19 | 20 | import org.apache.rocketmq.mqtt.common.model.QueueOffset; 21 | import org.junit.Assert; 22 | import org.junit.Test; 23 | 24 | public class TestQueueOffset { 25 | 26 | final long offset = 666; 27 | 28 | @Test 29 | public void test() { 30 | QueueOffset queueOffset = new QueueOffset(); 31 | Assert.assertFalse(queueOffset.isInitializing()); 32 | queueOffset.setInitializing(); 33 | Assert.assertTrue(queueOffset.isInitializing()); 34 | 35 | queueOffset.setOffset(offset); 36 | Assert.assertTrue(queueOffset.isInitialized()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/model/TestSubscription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.model; 19 | 20 | import org.apache.rocketmq.mqtt.common.model.Constants; 21 | import org.apache.rocketmq.mqtt.common.model.Subscription; 22 | import org.junit.Assert; 23 | import org.junit.Test; 24 | 25 | public class TestSubscription { 26 | 27 | final String firstTopic = "t1"; 28 | final String topicFilter = firstTopic + "/t2/"; 29 | final int qos = 1; 30 | final String clientId = "testSub"; 31 | final String p2pTopic = Constants.P2P + clientId + Constants.MQTT_TOPIC_DELIMITER; 32 | final String retryTopic = Constants.RETRY + clientId + Constants.MQTT_TOPIC_DELIMITER; 33 | 34 | @Test 35 | public void test() { 36 | Subscription subscription = new Subscription(topicFilter, qos); 37 | Assert.assertEquals(firstTopic, subscription.toFirstTopic()); 38 | Assert.assertEquals(topicFilter, subscription.toQueueName()); 39 | Assert.assertEquals(qos, subscription.getQos()); 40 | 41 | Assert.assertEquals(p2pTopic, Subscription.newP2pSubscription(clientId).getTopicFilter()); 42 | Assert.assertFalse(new Subscription().isP2p()); 43 | 44 | Assert.assertEquals(retryTopic, Subscription.newRetrySubscription(clientId).getTopicFilter()); 45 | Assert.assertTrue(new Subscription(retryTopic).isRetry()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/util/TestHmacSHA1Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.util; 19 | 20 | import org.apache.rocketmq.mqtt.common.util.HmacSHA1Util; 21 | import org.junit.Assert; 22 | import org.junit.Test; 23 | 24 | import java.nio.charset.StandardCharsets; 25 | import java.security.InvalidKeyException; 26 | import java.security.NoSuchAlgorithmException; 27 | 28 | public class TestHmacSHA1Util { 29 | 30 | @Test 31 | public void test() throws NoSuchAlgorithmException, InvalidKeyException { 32 | String clientId = "testHmacSHA1", secretKey = "SHA1Util"; 33 | 34 | byte[] signature = HmacSHA1Util.macSignature(clientId, secretKey).getBytes(StandardCharsets.UTF_8); 35 | Assert.assertTrue(HmacSHA1Util.validateSign(clientId, signature, secretKey)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/util/TestHostInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.util; 19 | 20 | import org.apache.rocketmq.mqtt.common.util.HostInfo; 21 | import org.junit.Assert; 22 | import org.junit.Test; 23 | 24 | import java.net.InetAddress; 25 | import java.net.UnknownHostException; 26 | 27 | public class TestHostInfo { 28 | 29 | @Test 30 | public void test() throws UnknownHostException { 31 | HostInfo hostINFO = HostInfo.getInstall(); 32 | Assert.assertEquals(InetAddress.getLocalHost().getHostAddress(), hostINFO.getAddress()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/util/TestNamespaceUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * * contributor license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright ownership. 6 | * * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * * (the "License"); you may not use this file except in compliance with 8 | * * the License. You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package org.apache.rocketmq.mqtt.common.test.util; 21 | 22 | import org.apache.rocketmq.mqtt.common.util.NamespaceUtil; 23 | import org.junit.Assert; 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | 27 | public class TestNamespaceUtil { 28 | 29 | String resource; 30 | String namespace; 31 | String originResource; 32 | 33 | @Before 34 | public void Before() { 35 | resource = "namespaceTest001%originResourceTest001"; 36 | namespace = "namespaceTest001"; 37 | originResource = "originResourceTest001"; 38 | } 39 | 40 | @Test 41 | public void testDecodeOriginResource() { 42 | Assert.assertEquals(originResource, NamespaceUtil.decodeOriginResource(resource)); 43 | Assert.assertEquals(originResource, NamespaceUtil.decodeOriginResource(originResource)); 44 | } 45 | 46 | @Test 47 | public void testEncodeToNamespaceResource() { 48 | Assert.assertEquals(resource, NamespaceUtil.encodeToNamespaceResource(namespace, originResource)); 49 | } 50 | 51 | @Test 52 | public void testDecodeMqttNamespaceIdFromKey() { 53 | Assert.assertEquals(namespace, NamespaceUtil.decodeMqttNamespaceIdFromKey(resource)); 54 | } 55 | 56 | @Test 57 | public void testDecodeMqttNamespaceIdFromClientId() { 58 | Assert.assertEquals(namespace, NamespaceUtil.decodeMqttNamespaceIdFromClientId(resource)); 59 | Assert.assertNull(NamespaceUtil.decodeMqttNamespaceIdFromClientId(originResource)); 60 | } 61 | 62 | @Test 63 | public void testDecodeStoreNamespaceIdFromTopic() { 64 | Assert.assertEquals(namespace, NamespaceUtil.decodeStoreNamespaceIdFromTopic(resource)); 65 | Assert.assertNull(NamespaceUtil.decodeStoreNamespaceIdFromTopic(originResource)); 66 | } 67 | 68 | @Test 69 | public void testDecodeNamespaceId() { 70 | Assert.assertEquals(namespace, NamespaceUtil.decodeNamespaceId(resource)); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /mqtt-common/src/test/java/org/apache/rocketmq/mqtt/common/test/util/TestStatUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.common.test.util; 19 | 20 | import org.apache.rocketmq.mqtt.common.util.StatUtil; 21 | import org.junit.Assert; 22 | import org.junit.Test; 23 | 24 | import java.math.BigDecimal; 25 | 26 | import static java.math.BigDecimal.ROUND_HALF_UP; 27 | 28 | public class TestStatUtil { 29 | 30 | @Test 31 | public void test() throws Exception { 32 | 33 | final int keyAPv = 10, keyBPv = 20, testRt = 1000; 34 | // test buildKey 35 | String keyA = "a", keyB = "b"; 36 | Assert.assertEquals(keyA + "," + keyB, StatUtil.buildKey(keyA, keyB)); 37 | 38 | // test addInvoke 39 | StatUtil.addInvoke(keyA, testRt); 40 | Assert.assertEquals(1, StatUtil.nowTps(keyA)); 41 | Assert.assertFalse(StatUtil.isOverFlow(keyA, 200)); 42 | 43 | // test addPv 44 | StatUtil.addPv(keyA, keyAPv); 45 | Assert.assertEquals(keyAPv + 1, StatUtil.nowTps(keyA)); 46 | 47 | // test addSecondInvoke, addSecondPV, Pv, Tps 48 | StatUtil.addSecondInvoke(keyB, testRt); 49 | Assert.assertEquals(1, StatUtil.totalPvInWindow(keyB, 60)); 50 | StatUtil.addSecondPv(keyB, keyBPv); 51 | Assert.assertEquals(keyBPv + 1, StatUtil.totalPvInWindow(keyB, 60)); 52 | Assert.assertEquals(0, StatUtil.failPvInWindow(keyB, 60)); 53 | Assert.assertEquals(0, StatUtil.topTpsInWindow(keyA, 60)); 54 | Assert.assertEquals(keyBPv + 1, StatUtil.topTpsInWindow(keyB, 60)); 55 | 56 | // test RtInWindow 57 | Assert.assertEquals(testRt, StatUtil.maxRtInWindow(keyB, 60)); 58 | Assert.assertEquals(0, StatUtil.minRtInWindow(keyB, 60)); 59 | int avgRt = new BigDecimal(testRt).divide(new BigDecimal(keyBPv + 1), 60 | ROUND_HALF_UP).intValue(); 61 | Assert.assertEquals(avgRt, StatUtil.avgRtInWindow(keyB, 60)); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/channel/ChannelCloseFrom.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.channel; 19 | 20 | public enum ChannelCloseFrom { 21 | /** 22 | * 23 | */ 24 | CLIENT, 25 | 26 | /** 27 | * 28 | */ 29 | SERVER 30 | } 31 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/channel/ChannelDecodeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.channel; 19 | 20 | 21 | public class ChannelDecodeException extends RuntimeException { 22 | public ChannelDecodeException() {} 23 | 24 | public ChannelDecodeException(String message) { 25 | super(message); 26 | } 27 | 28 | public ChannelDecodeException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | 32 | public ChannelDecodeException(Throwable cause) { 33 | super(cause); 34 | } 35 | 36 | public ChannelDecodeException(String message, Throwable cause, boolean enableSuppression, 37 | boolean writableStackTrace) { 38 | super(message, cause, enableSuppression, writableStackTrace); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/channel/ChannelException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.channel; 19 | 20 | public class ChannelException extends RuntimeException { 21 | public ChannelException() { 22 | } 23 | 24 | public ChannelException(String message) { 25 | super(message); 26 | } 27 | 28 | public ChannelException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | 32 | public ChannelException(Throwable cause) { 33 | super(cause); 34 | } 35 | 36 | public ChannelException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 37 | super(message, cause, enableSuppression, writableStackTrace); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/channel/ChannelManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.channel; 19 | 20 | import io.netty.channel.Channel; 21 | 22 | 23 | public interface ChannelManager { 24 | 25 | /** 26 | * addChannel 27 | * 28 | * @param channel 29 | */ 30 | void addChannel(Channel channel); 31 | 32 | /** 33 | * closeConnect 34 | * 35 | * @param channel 36 | * @param from 37 | * @param reason 38 | */ 39 | void closeConnect(Channel channel, ChannelCloseFrom from, String reason); 40 | 41 | /** 42 | * closeConnect 43 | * @param channelId 44 | * @param reason 45 | */ 46 | void closeConnect(String channelId, String reason); 47 | 48 | /** 49 | * get channel by Id 50 | * @param channelId 51 | * @return 52 | */ 53 | Channel getChannelById(String channelId); 54 | 55 | /** 56 | * totalConn 57 | * 58 | * @return 59 | */ 60 | int totalConn(); 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/channel/ConnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.channel; 19 | 20 | import io.netty.channel.ChannelHandler; 21 | import io.netty.channel.ChannelHandlerContext; 22 | import io.netty.channel.ChannelInboundHandlerAdapter; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.springframework.stereotype.Component; 26 | 27 | import javax.annotation.Resource; 28 | import java.util.Collections; 29 | import java.util.List; 30 | 31 | 32 | @ChannelHandler.Sharable 33 | @Component 34 | public class ConnectHandler extends ChannelInboundHandlerAdapter { 35 | private static Logger logger = LoggerFactory.getLogger(ConnectHandler.class); 36 | 37 | private final List simpleExceptions = Collections.singletonList("Connection reset by peer"); 38 | 39 | @Resource 40 | private ChannelManager channelManager; 41 | 42 | @Override 43 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 44 | ctx.fireChannelActive(); 45 | channelManager.addChannel(ctx.channel()); 46 | } 47 | 48 | @Override 49 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 50 | super.channelInactive(ctx); 51 | channelManager.closeConnect(ctx.channel(), ChannelCloseFrom.CLIENT, "be closed"); 52 | } 53 | 54 | 55 | @Override 56 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 57 | if (cause.getMessage() == null || !simpleExceptions.contains(cause.getMessage())) { 58 | logger.error("exceptionCaught {}", ctx.channel(), cause); 59 | } 60 | channelManager.closeConnect(ctx.channel(), ChannelCloseFrom.SERVER, cause.getMessage()); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/config/ConnectConfListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.config; 19 | 20 | import org.apache.rocketmq.common.MixAll; 21 | import org.apache.rocketmq.common.ThreadFactoryImpl; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import org.springframework.stereotype.Component; 25 | 26 | import javax.annotation.PostConstruct; 27 | import javax.annotation.Resource; 28 | import java.io.File; 29 | import java.io.FileInputStream; 30 | import java.io.InputStream; 31 | import java.util.Properties; 32 | import java.util.concurrent.ScheduledThreadPoolExecutor; 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.concurrent.atomic.AtomicLong; 35 | 36 | 37 | @Component 38 | public class ConnectConfListener { 39 | private static Logger logger = LoggerFactory.getLogger(ConnectConfListener.class); 40 | 41 | @Resource 42 | private ConnectConf connectConf; 43 | 44 | private File confFile; 45 | private ScheduledThreadPoolExecutor scheduler; 46 | private AtomicLong gmt = new AtomicLong(); 47 | private long refreshSecs = 3; 48 | 49 | @PostConstruct 50 | public void start() { 51 | confFile = connectConf.getConfFile(); 52 | gmt.set(confFile.lastModified()); 53 | scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactoryImpl("ConnectConfListener")); 54 | scheduler.scheduleWithFixedDelay(() -> { 55 | try { 56 | if (gmt.get() == confFile.lastModified()) { 57 | return; 58 | } 59 | gmt.set(confFile.lastModified()); 60 | InputStream in = new FileInputStream(confFile.getAbsoluteFile()); 61 | Properties properties = new Properties(); 62 | properties.load(in); 63 | in.close(); 64 | MixAll.properties2Object(properties, connectConf); 65 | logger.warn("UpdateConf:{}", confFile.getAbsolutePath()); 66 | } catch (Exception e) { 67 | logger.error("", e); 68 | } 69 | }, refreshSecs, refreshSecs, TimeUnit.SECONDS); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/config/WillLoopConf.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.config; 19 | 20 | public class WillLoopConf { 21 | private int maxScanNodeNum = 100; 22 | private int maxScanClientNum = 100000; 23 | private int scanNumOnce = 100; 24 | private boolean enableWill = true; 25 | 26 | public int getMaxScanNodeNum() { 27 | return maxScanNodeNum; 28 | } 29 | 30 | public void setMaxScanNodeNum(int maxScanNodeNum) { 31 | this.maxScanNodeNum = maxScanNodeNum; 32 | } 33 | 34 | public int getMaxScanClientNum() { 35 | return maxScanClientNum; 36 | } 37 | 38 | public void setMaxScanClientNum(int maxScanClientNum) { 39 | this.maxScanClientNum = maxScanClientNum; 40 | } 41 | 42 | public int getScanNumOnce() { 43 | return scanNumOnce; 44 | } 45 | 46 | public void setScanNumOnce(int scanNumOnce) { 47 | this.scanNumOnce = scanNumOnce; 48 | } 49 | 50 | public boolean isEnableWill() { 51 | return enableWill; 52 | } 53 | 54 | public void setEnableWill(boolean enableWill) { 55 | this.enableWill = enableWill; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/MqttPacketHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.mqtt.MqttMessage; 22 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 23 | 24 | 25 | public interface MqttPacketHandler { 26 | 27 | /** 28 | * preHandler before upstream processor, for preprocessing 29 | * 30 | * @param ctx 31 | * @param mqttMessage 32 | * @return 33 | */ 34 | boolean preHandler(ChannelHandlerContext ctx, T mqttMessage); 35 | 36 | /** 37 | * doHandler after upstream processor 38 | * 39 | * @param ctx 40 | * @param mqttMessage 41 | */ 42 | void doHandler(ChannelHandlerContext ctx, T mqttMessage, HookResult upstreamHookResult); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttDisconnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.mqtt.MqttMessage; 22 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 23 | import org.apache.rocketmq.mqtt.cs.channel.ChannelCloseFrom; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelManager; 25 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 26 | import org.springframework.stereotype.Component; 27 | 28 | import javax.annotation.Resource; 29 | 30 | 31 | 32 | @Component 33 | public class MqttDisconnectHandler implements MqttPacketHandler { 34 | 35 | @Resource 36 | private ChannelManager channelManager; 37 | 38 | @Override 39 | public boolean preHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage) { 40 | return true; 41 | } 42 | 43 | @Override 44 | public void doHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage, HookResult upstreamHookResult) { 45 | channelManager.closeConnect(ctx.channel(), ChannelCloseFrom.CLIENT, "disconnect"); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttPingHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.Channel; 21 | import io.netty.channel.ChannelHandlerContext; 22 | import io.netty.handler.codec.mqtt.MqttMessage; 23 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelInfo; 25 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 26 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.facotry.MqttMessageFactory; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | import org.springframework.stereotype.Component; 30 | 31 | 32 | @Component 33 | public class MqttPingHandler implements MqttPacketHandler { 34 | private static Logger logger = LoggerFactory.getLogger(MqttPingHandler.class); 35 | 36 | @Override 37 | public boolean preHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage) { 38 | return true; 39 | } 40 | 41 | @Override 42 | public void doHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage, HookResult upstreamHookResult) { 43 | Channel channel = ctx.channel(); 44 | ChannelInfo.touch(channel); 45 | channel.writeAndFlush(MqttMessageFactory.buildPingRespMessage()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttPubAckHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | 21 | import io.netty.channel.ChannelHandlerContext; 22 | import io.netty.handler.codec.mqtt.MqttPubAckMessage; 23 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelInfo; 25 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 26 | import org.apache.rocketmq.mqtt.cs.session.Session; 27 | import org.apache.rocketmq.mqtt.cs.session.infly.PushAction; 28 | import org.apache.rocketmq.mqtt.cs.session.infly.RetryDriver; 29 | import org.apache.rocketmq.mqtt.cs.session.loop.SessionLoop; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | import org.springframework.stereotype.Component; 33 | 34 | import javax.annotation.Resource; 35 | 36 | 37 | 38 | @Component 39 | public class MqttPubAckHandler implements MqttPacketHandler { 40 | private static Logger logger = LoggerFactory.getLogger(MqttPubAckHandler.class); 41 | 42 | @Resource 43 | private PushAction pushAction; 44 | 45 | @Resource 46 | private RetryDriver retryDriver; 47 | 48 | @Resource 49 | private SessionLoop sessionLoop; 50 | 51 | @Override 52 | public boolean preHandler(ChannelHandlerContext ctx, MqttPubAckMessage mqttMessage) { 53 | return true; 54 | } 55 | 56 | @Override 57 | public void doHandler(ChannelHandlerContext ctx, MqttPubAckMessage mqttMessage, HookResult upstreamHookResult) { 58 | int messageId = mqttMessage.variableHeader().messageId(); 59 | retryDriver.unMountPublish(messageId, ChannelInfo.getId(ctx.channel())); 60 | Session session = sessionLoop.getSession(ChannelInfo.getId(ctx.channel())); 61 | pushAction.rollNextByAck(session, messageId); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttPubCompHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.mqtt.MqttMessage; 22 | import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader; 23 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelInfo; 25 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 26 | import org.apache.rocketmq.mqtt.cs.session.Session; 27 | import org.apache.rocketmq.mqtt.cs.session.infly.PushAction; 28 | import org.apache.rocketmq.mqtt.cs.session.infly.RetryDriver; 29 | import org.apache.rocketmq.mqtt.cs.session.loop.SessionLoop; 30 | import org.springframework.stereotype.Component; 31 | 32 | import javax.annotation.Resource; 33 | 34 | 35 | @Component 36 | public class MqttPubCompHandler implements MqttPacketHandler { 37 | 38 | @Resource 39 | private RetryDriver retryDriver; 40 | 41 | @Resource 42 | private PushAction pushAction; 43 | 44 | @Resource 45 | private SessionLoop sessionLoop; 46 | 47 | @Override 48 | public boolean preHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage) { 49 | return true; 50 | } 51 | 52 | @Override 53 | public void doHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage, HookResult upstreamHookResult) { 54 | MqttMessageIdVariableHeader variableHeader = (MqttMessageIdVariableHeader) mqttMessage.variableHeader(); 55 | String channelId = ChannelInfo.getId(ctx.channel()); 56 | 57 | retryDriver.unMountPubRel(variableHeader.messageId(), ChannelInfo.getId(ctx.channel())); 58 | 59 | //The Packet Identifier becomes available for reuse once the Sender has received the PUBCOMP Packet. 60 | Session session = sessionLoop.getSession(channelId); 61 | pushAction.rollNextByAck(session, variableHeader.messageId()); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttPubRecHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.mqtt.MqttFixedHeader; 22 | import io.netty.handler.codec.mqtt.MqttMessage; 23 | import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader; 24 | import io.netty.handler.codec.mqtt.MqttMessageType; 25 | import io.netty.handler.codec.mqtt.MqttQoS; 26 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 27 | import org.apache.rocketmq.mqtt.cs.channel.ChannelInfo; 28 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 29 | import org.apache.rocketmq.mqtt.cs.session.infly.RetryDriver; 30 | import org.springframework.stereotype.Component; 31 | 32 | import javax.annotation.Resource; 33 | 34 | @Component 35 | public class MqttPubRecHandler implements MqttPacketHandler { 36 | private final MqttFixedHeader pubRelMqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBREL, false, 37 | 38 | MqttQoS.AT_LEAST_ONCE, false, 0); 39 | 40 | @Resource 41 | private RetryDriver retryDriver; 42 | 43 | @Override 44 | public boolean preHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage) { 45 | return true; 46 | } 47 | 48 | @Override 49 | public void doHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage, HookResult upstreamHookResult) { 50 | MqttMessageIdVariableHeader variableHeader = (MqttMessageIdVariableHeader) mqttMessage.variableHeader(); 51 | String channelId = ChannelInfo.getId(ctx.channel()); 52 | retryDriver.unMountPublish(variableHeader.messageId(), channelId); 53 | retryDriver.mountPubRel(variableHeader.messageId(), channelId); 54 | 55 | MqttMessage pubRelMqttMessage = new MqttMessage(pubRelMqttFixedHeader, variableHeader); 56 | ctx.channel().writeAndFlush(pubRelMqttMessage); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/mqtt/handler/MqttPubRelHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler; 19 | 20 | 21 | import io.netty.channel.ChannelHandlerContext; 22 | import io.netty.handler.codec.mqtt.MqttMessage; 23 | import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader; 24 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 25 | import org.apache.rocketmq.mqtt.cs.channel.ChannelInfo; 26 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.MqttPacketHandler; 27 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.facotry.MqttMessageFactory; 28 | import org.apache.rocketmq.mqtt.cs.session.infly.InFlyCache; 29 | import org.springframework.stereotype.Component; 30 | 31 | import javax.annotation.Resource; 32 | 33 | 34 | @Component 35 | public class MqttPubRelHandler implements MqttPacketHandler { 36 | 37 | @Resource 38 | private InFlyCache inFlyCache; 39 | 40 | @Override 41 | public boolean preHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage) { 42 | return true; 43 | } 44 | 45 | @Override 46 | public void doHandler(ChannelHandlerContext ctx, MqttMessage mqttMessage, HookResult upstreamHookResult) { 47 | final MqttMessageIdVariableHeader variableHeader = (MqttMessageIdVariableHeader) mqttMessage.variableHeader(); 48 | String channelId = ChannelInfo.getId(ctx.channel()); 49 | inFlyCache.remove(InFlyCache.CacheType.PUB, channelId, variableHeader.messageId()); 50 | 51 | ctx.channel().writeAndFlush(MqttMessageFactory.buildPubCompMessage(variableHeader)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/protocol/ws/WebSocketEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.protocol.ws; 19 | 20 | import java.util.List; 21 | 22 | import io.netty.buffer.ByteBuf; 23 | import io.netty.channel.ChannelHandlerContext; 24 | import io.netty.handler.codec.MessageToMessageEncoder; 25 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 26 | 27 | public class WebSocketEncoder extends MessageToMessageEncoder { 28 | 29 | @Override 30 | protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { 31 | msg.retain(); 32 | BinaryWebSocketFrame binaryWebSocketFrame = new BinaryWebSocketFrame(msg); 33 | out.add(binaryWebSocketFrame); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/session/QueueFresh.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.session; 19 | 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.apache.rocketmq.mqtt.common.facade.LmqQueueStore; 22 | import org.apache.rocketmq.mqtt.common.model.Queue; 23 | import org.apache.rocketmq.mqtt.common.model.Subscription; 24 | import org.springframework.stereotype.Component; 25 | 26 | import javax.annotation.Resource; 27 | import java.util.HashSet; 28 | import java.util.Set; 29 | 30 | @Component 31 | public class QueueFresh { 32 | 33 | @Resource 34 | private LmqQueueStore lmqQueueStore; 35 | 36 | public Set freshQueue(Session session, Subscription subscription) { 37 | Set queues = new HashSet<>(); 38 | Set brokers; 39 | if (subscription.isP2p()) { 40 | String findTopic = lmqQueueStore.getClientP2pTopic(); 41 | if (StringUtils.isBlank(findTopic)) { 42 | findTopic = lmqQueueStore.getClientRetryTopic(); 43 | } 44 | brokers = lmqQueueStore.getReadableBrokers(findTopic); 45 | } else if (subscription.isRetry()) { 46 | brokers = lmqQueueStore.getReadableBrokers(lmqQueueStore.getClientRetryTopic()); 47 | } else { 48 | brokers = lmqQueueStore.getReadableBrokers(subscription.toFirstTopic()); 49 | } 50 | if (brokers == null || brokers.isEmpty()) { 51 | return queues; 52 | } 53 | for (String broker : brokers) { 54 | Queue moreQueue = new Queue(); 55 | moreQueue.setQueueName(subscription.toQueueName()); 56 | moreQueue.setBrokerName(broker); 57 | queues.add(moreQueue); 58 | } 59 | session.freshQueue(subscription, queues); 60 | return queues; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/session/loop/PullResultStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.session.loop; 19 | 20 | 21 | public enum PullResultStatus { 22 | DONE, 23 | LATER 24 | } 25 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/session/loop/SessionLoop.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.session.loop; 19 | 20 | 21 | import io.netty.channel.Channel; 22 | import org.apache.rocketmq.mqtt.common.model.Queue; 23 | import org.apache.rocketmq.mqtt.common.model.Subscription; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelManager; 25 | import org.apache.rocketmq.mqtt.cs.session.Session; 26 | 27 | import java.util.List; 28 | import java.util.Set; 29 | 30 | 31 | public interface SessionLoop { 32 | 33 | /** 34 | * set ChannelManager 35 | * 36 | * @param channelManager 37 | */ 38 | void setChannelManager(ChannelManager channelManager); 39 | 40 | /** 41 | * load one mqtt session 42 | * 43 | * @param clientId 44 | * @param channel 45 | */ 46 | void loadSession(String clientId, Channel channel); 47 | 48 | /** 49 | * unload one mqtt session 50 | * 51 | * @param clientId 52 | * @param channelId 53 | * @return 54 | */ 55 | Session unloadSession(String clientId, String channelId); 56 | 57 | /** 58 | * get the session by channelId 59 | * 60 | * @param channelId 61 | * @return 62 | */ 63 | Session getSession(String channelId); 64 | 65 | /** 66 | * get session list by clientId 67 | * 68 | * @param clientId 69 | * @return 70 | */ 71 | List getSessionList(String clientId); 72 | 73 | /** 74 | * add subscription 75 | * 76 | * @param channelId 77 | * @param subscriptions 78 | */ 79 | void addSubscription(String channelId, Set subscriptions); 80 | 81 | /** 82 | * remove subscription 83 | * 84 | * @param channelId 85 | * @param subscriptions 86 | */ 87 | void removeSubscription(String channelId, Set subscriptions); 88 | 89 | /** 90 | * notify to pull message from queue 91 | * 92 | * @param session 93 | * @param subscription 94 | * @param queue 95 | */ 96 | void notifyPullMessage(Session session, Subscription subscription, Queue queue); 97 | 98 | } 99 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/starter/ExporterServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.starter; 19 | 20 | import javax.annotation.PostConstruct; 21 | import javax.annotation.PreDestroy; 22 | import javax.annotation.Resource; 23 | 24 | import org.apache.rocketmq.mqtt.common.util.HostInfo; 25 | import org.apache.rocketmq.mqtt.cs.config.ConnectConf; 26 | import org.apache.rocketmq.mqtt.exporter.MqttExporter; 27 | import org.springframework.stereotype.Component; 28 | 29 | @Component 30 | public class ExporterServer { 31 | private static final HostInfo HOST_INFO = HostInfo.getInstall(); 32 | private static final String NAMESPACE = "mqtt"; 33 | @Resource 34 | private ConnectConf connectConf; 35 | 36 | private MqttExporter mqttExporter; 37 | 38 | @PostConstruct 39 | public void init() throws Exception { 40 | if (connectConf.isEnablePrometheus()) { 41 | this.mqttExporter = new MqttExporter(NAMESPACE, HOST_INFO.getName(), HOST_INFO.getAddress(), 42 | connectConf.getExporterPort(), connectConf.isExportJvmInfo()); 43 | mqttExporter.start(); 44 | } 45 | } 46 | 47 | @PreDestroy 48 | public void shutdown() { 49 | if (this.mqttExporter != null) { 50 | this.mqttExporter.shutdown(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/starter/RpcServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.starter; 19 | 20 | 21 | import org.apache.rocketmq.common.ThreadFactoryImpl; 22 | import org.apache.rocketmq.mqtt.cs.config.ConnectConf; 23 | import org.apache.rocketmq.mqtt.cs.protocol.rpc.RpcPacketDispatcher; 24 | import org.apache.rocketmq.remoting.netty.NettyRemotingServer; 25 | import org.apache.rocketmq.remoting.netty.NettyServerConfig; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | import org.springframework.stereotype.Service; 29 | 30 | import javax.annotation.PostConstruct; 31 | import javax.annotation.Resource; 32 | import java.util.concurrent.BlockingQueue; 33 | import java.util.concurrent.LinkedBlockingQueue; 34 | import java.util.concurrent.ThreadPoolExecutor; 35 | import java.util.concurrent.TimeUnit; 36 | 37 | @Service 38 | public class RpcServer { 39 | private static Logger logger = LoggerFactory.getLogger(RpcServer.class); 40 | 41 | @Resource 42 | private ConnectConf connectConf; 43 | 44 | @Resource 45 | private RpcPacketDispatcher rpcPacketDispatcher; 46 | 47 | private NettyRemotingServer remotingServer; 48 | private BlockingQueue csBridgeRpcQueue; 49 | 50 | @PostConstruct 51 | public void start() { 52 | NettyServerConfig nettyServerConfig = new NettyServerConfig(); 53 | nettyServerConfig.setListenPort(connectConf.getRpcListenPort()); 54 | remotingServer = new NettyRemotingServer(nettyServerConfig); 55 | csBridgeRpcQueue = new LinkedBlockingQueue<>(10000); 56 | ThreadPoolExecutor executor = new ThreadPoolExecutor(8, 16, 1, TimeUnit.MINUTES, 57 | csBridgeRpcQueue, new ThreadFactoryImpl("Rpc_Server_Thread_")); 58 | remotingServer.registerDefaultProcessor(rpcPacketDispatcher, executor); 59 | remotingServer.start(); 60 | logger.warn("start rpc server , port:{}", connectConf.getRpcListenPort()); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-cs/src/main/java/org/apache/rocketmq/mqtt/cs/starter/Startup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.starter; 19 | 20 | import org.apache.rocketmq.mqtt.common.util.SpringUtils; 21 | 22 | import org.springframework.context.support.ClassPathXmlApplicationContext; 23 | 24 | 25 | public class Startup { 26 | public static void main(String[] args) { 27 | 28 | ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml"); 29 | SpringUtils.SetClassPathXmlApplicationContext(applicationContext); 30 | System.out.println("start rocketmq mqtt ..."); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/channel/TestConnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * * contributor license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright ownership. 6 | * * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * * (the "License"); you may not use this file except in compliance with 8 | * * the License. You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package org.apache.rocketmq.mqtt.cs.test.channel; 21 | 22 | import io.netty.channel.ChannelHandlerContext; 23 | import org.apache.commons.lang3.reflect.FieldUtils; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelManager; 25 | import org.apache.rocketmq.mqtt.cs.channel.ConnectHandler; 26 | import org.junit.After; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.mockito.Mock; 31 | import org.mockito.junit.MockitoJUnitRunner; 32 | 33 | import static org.mockito.ArgumentMatchers.any; 34 | import static org.mockito.Mockito.verify; 35 | 36 | @RunWith(MockitoJUnitRunner.class) 37 | public class TestConnectHandler { 38 | 39 | private ConnectHandler connectHandler; 40 | 41 | @Mock 42 | private ChannelManager channelManager; 43 | 44 | @Mock 45 | private ChannelHandlerContext ctx; 46 | 47 | @Before 48 | public void Before() throws IllegalAccessException { 49 | connectHandler = new ConnectHandler(); 50 | FieldUtils.writeDeclaredField(connectHandler, "channelManager", channelManager, true); 51 | } 52 | 53 | @After 54 | public void After() { 55 | } 56 | 57 | @Test 58 | public void testChannelActive() throws Exception { 59 | connectHandler.channelActive(ctx); 60 | verify(channelManager).addChannel(any()); 61 | } 62 | 63 | @Test 64 | public void testChannelInactive() throws Exception { 65 | connectHandler.channelInactive(ctx); 66 | verify(channelManager).closeConnect(any(), any(), any()); 67 | } 68 | 69 | @Test 70 | public void testExceptionCaught() throws Exception { 71 | connectHandler.exceptionCaught(ctx, new Throwable("err")); 72 | verify(channelManager).closeConnect(any(), any(), any()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/hook/TestUpstreamHookManagerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * * contributor license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright ownership. 6 | * * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * * (the "License"); you may not use this file except in compliance with 8 | * * the License. You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package org.apache.rocketmq.mqtt.cs.test.hook; 21 | 22 | import io.netty.handler.codec.mqtt.MqttMessage; 23 | import org.apache.commons.lang3.reflect.FieldUtils; 24 | import org.apache.rocketmq.mqtt.common.hook.UpstreamHook; 25 | import org.apache.rocketmq.mqtt.common.hook.UpstreamHookManager; 26 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 27 | import org.apache.rocketmq.mqtt.cs.hook.UpstreamHookManagerImpl; 28 | import org.junit.After; 29 | import org.junit.Before; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.Mock; 33 | import org.mockito.junit.MockitoJUnitRunner; 34 | 35 | import java.util.concurrent.atomic.AtomicBoolean; 36 | 37 | import static org.mockito.ArgumentMatchers.any; 38 | import static org.mockito.Mockito.mock; 39 | import static org.mockito.Mockito.times; 40 | import static org.mockito.Mockito.verify; 41 | 42 | @RunWith(MockitoJUnitRunner.class) 43 | public class TestUpstreamHookManagerImpl { 44 | 45 | private UpstreamHookManager upstreamHookManager; 46 | 47 | @Mock 48 | private UpstreamHook upstreamHook; 49 | 50 | @Before 51 | public void Before() { 52 | upstreamHookManager = new UpstreamHookManagerImpl(); 53 | } 54 | 55 | @After 56 | public void After() {} 57 | 58 | @Test(expected = IllegalArgumentException.class ) 59 | public void testAddHookIllegalArgException() throws IllegalAccessException { 60 | FieldUtils.writeDeclaredField(upstreamHookManager, "isAssembled", new AtomicBoolean(true), true); 61 | upstreamHookManager.addHook(0, upstreamHook); 62 | } 63 | 64 | @Test 65 | public void testDoUpstreamHook() { 66 | upstreamHookManager.addHook(0, upstreamHook); 67 | upstreamHookManager.doUpstreamHook(mock(MqttMessageUpContext.class), mock(MqttMessage.class)); 68 | 69 | verify(upstreamHook, times(1)).getNextHook(); 70 | verify(upstreamHook, times(1)).setNextHook(any()); 71 | verify(upstreamHook, times(1)).doHook(any(), any()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/protocol/mqtt/handler/TestMqttDisconnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.test.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.mqtt.MqttMessage; 22 | import org.apache.commons.lang3.reflect.FieldUtils; 23 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 24 | import org.apache.rocketmq.mqtt.cs.channel.ChannelManager; 25 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler.MqttDisconnectHandler; 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.mockito.Mock; 29 | import org.mockito.junit.MockitoJUnitRunner; 30 | 31 | import static org.mockito.ArgumentMatchers.any; 32 | import static org.mockito.Mockito.verify; 33 | import static org.mockito.Mockito.verifyNoMoreInteractions; 34 | 35 | 36 | @RunWith(MockitoJUnitRunner.class) 37 | public class TestMqttDisconnectHandler { 38 | 39 | private MqttDisconnectHandler disconnectHandler; 40 | 41 | @Mock 42 | private ChannelManager channelManager; 43 | 44 | @Mock 45 | private ChannelHandlerContext ctx; 46 | 47 | @Mock 48 | private MqttMessage mqttMessage; 49 | 50 | @Mock 51 | private HookResult hookResult; 52 | 53 | @Test 54 | public void testDoHandler() throws IllegalAccessException { 55 | disconnectHandler = new MqttDisconnectHandler(); 56 | FieldUtils.writeDeclaredField(disconnectHandler, "channelManager", channelManager, true); 57 | 58 | disconnectHandler.doHandler(ctx, mqttMessage, hookResult); 59 | verify(channelManager).closeConnect(any(), any(), any()); 60 | verifyNoMoreInteractions(channelManager); 61 | } 62 | } -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/protocol/mqtt/handler/TestMqttPingHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.test.protocol.mqtt.handler; 19 | 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.channel.socket.nio.NioSocketChannel; 22 | import io.netty.handler.codec.mqtt.MqttMessage; 23 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 24 | import org.apache.rocketmq.mqtt.cs.protocol.mqtt.handler.MqttPingHandler; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.mockito.Mock; 28 | import org.mockito.Spy; 29 | import org.mockito.junit.MockitoJUnitRunner; 30 | 31 | import static org.mockito.ArgumentMatchers.any; 32 | import static org.mockito.Mockito.doReturn; 33 | import static org.mockito.Mockito.verify; 34 | import static org.mockito.Mockito.when; 35 | 36 | @RunWith(MockitoJUnitRunner.class) 37 | public class TestMqttPingHandler { 38 | 39 | private MqttPingHandler pingHandler; 40 | 41 | @Mock 42 | private ChannelHandlerContext ctx; 43 | 44 | @Mock 45 | private MqttMessage mqttMessage; 46 | 47 | @Mock 48 | private HookResult hookResult; 49 | 50 | @Spy 51 | private NioSocketChannel channel; 52 | 53 | @Test 54 | public void testDoHandler() { 55 | pingHandler = new MqttPingHandler(); 56 | when(ctx.channel()).thenReturn(channel); 57 | doReturn(null).when(channel).writeAndFlush(any()); 58 | 59 | pingHandler.doHandler(ctx, mqttMessage, hookResult); 60 | verify(ctx).channel(); 61 | verify(channel).writeAndFlush(any()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/protocol/ws/TestWebSocketEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.test.protocol.ws; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.buffer.Unpooled; 22 | import io.netty.channel.embedded.EmbeddedChannel; 23 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 24 | import org.apache.rocketmq.mqtt.cs.protocol.ws.WebSocketEncoder; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.mockito.junit.MockitoJUnitRunner; 28 | 29 | import static org.junit.Assert.assertEquals; 30 | import static org.junit.Assert.assertNull; 31 | import static org.junit.Assert.assertTrue; 32 | 33 | @RunWith(MockitoJUnitRunner.class) 34 | public class TestWebSocketEncoder { 35 | 36 | private WebSocketEncoder webSocketEncoder = new WebSocketEncoder(); 37 | private final int content = 666; 38 | 39 | @Test 40 | public void test() { 41 | ByteBuf byteMsg = Unpooled.buffer(); 42 | byteMsg.writeByte(content); 43 | 44 | EmbeddedChannel channel = new EmbeddedChannel(webSocketEncoder); 45 | assertTrue(channel.writeOutbound(byteMsg)); 46 | assertTrue(channel.finish()); 47 | 48 | assertEquals(new BinaryWebSocketFrame(byteMsg), channel.readOutbound()); 49 | assertNull(channel.readOutbound()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/protocol/ws/TestWebSocketServerHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.cs.test.protocol.ws; 19 | 20 | import io.netty.channel.ChannelPipeline; 21 | import io.netty.channel.embedded.EmbeddedChannel; 22 | import io.netty.handler.codec.http.DefaultFullHttpRequest; 23 | import io.netty.handler.codec.http.FullHttpRequest; 24 | import io.netty.handler.codec.http.websocketx.PongWebSocketFrame; 25 | import org.apache.rocketmq.mqtt.cs.protocol.ws.WebSocketServerHandler; 26 | import org.junit.Before; 27 | import org.junit.Test; 28 | import org.junit.runner.RunWith; 29 | import org.mockito.junit.MockitoJUnitRunner; 30 | 31 | import static io.netty.handler.codec.DecoderResult.UNFINISHED; 32 | import static io.netty.handler.codec.http.HttpMethod.CONNECT; 33 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 34 | import static org.junit.Assert.assertNull; 35 | 36 | @RunWith(MockitoJUnitRunner.class) 37 | public class TestWebSocketServerHandler { 38 | 39 | private WebSocketServerHandler webSocketServerHandler = new WebSocketServerHandler(); 40 | private EmbeddedChannel channel = new EmbeddedChannel(); 41 | 42 | @Before 43 | public void setUp() throws Exception { 44 | ChannelPipeline pipeline = channel.pipeline(); 45 | pipeline.addLast(webSocketServerHandler); 46 | } 47 | 48 | @Test 49 | public void testHttpRequestUpgradeNull() { 50 | FullHttpRequest httpRequest = new DefaultFullHttpRequest(HTTP_1_1, CONNECT, "ws://localhost:8888/mqtt"); 51 | channel.writeInbound(httpRequest); 52 | 53 | assertNull(channel.readInbound()); 54 | } 55 | 56 | @Test 57 | public void testSendHttpResponse() { 58 | FullHttpRequest httpRequest = new DefaultFullHttpRequest(HTTP_1_1, CONNECT, "ws://localhost:8888/mqtt"); 59 | httpRequest.setDecoderResult(UNFINISHED); 60 | channel.writeInbound(httpRequest); 61 | 62 | assertNull(channel.readInbound()); 63 | } 64 | 65 | @Test 66 | public void testPongWebSocketFrame() { 67 | PongWebSocketFrame socketFrame = new PongWebSocketFrame(); 68 | channel.writeInbound(socketFrame); 69 | 70 | assertNull(channel.readInbound()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /mqtt-cs/src/test/java/org/apache/rocketmq/mqtt/cs/test/session/infly/TestMqttMsgId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * * contributor license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright ownership. 6 | * * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * * (the "License"); you may not use this file except in compliance with 8 | * * the License. You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package org.apache.rocketmq.mqtt.cs.test.session.infly; 21 | 22 | import org.apache.rocketmq.mqtt.cs.session.infly.MqttMsgId; 23 | import org.junit.Assert; 24 | import org.junit.Test; 25 | import org.junit.runner.RunWith; 26 | import org.mockito.junit.MockitoJUnitRunner; 27 | 28 | @RunWith(MockitoJUnitRunner.class) 29 | public class TestMqttMsgId { 30 | 31 | @Test 32 | public void test() { 33 | MqttMsgId mqttMsgId = new MqttMsgId(); 34 | mqttMsgId.init(); 35 | 36 | String clientId = "testMsgId"; 37 | int loopCount = 0, maxMsgId = 65535; 38 | while (loopCount < maxMsgId) { 39 | Assert.assertEquals(loopCount + 1, mqttMsgId.nextId(clientId)); 40 | loopCount++; 41 | } 42 | // new round by triggering 'inUseMsgIds.clear' when 'startingMessageId' == 65535 43 | Assert.assertEquals(loopCount, mqttMsgId.nextId(clientId)); 44 | 45 | mqttMsgId.releaseId(maxMsgId, ""); 46 | mqttMsgId.releaseId(maxMsgId, clientId); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mqtt-ds/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rocketmq-mqtt 5 | org.apache.rocketmq 6 | 1.0.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | mqtt-ds 11 | 12 | 13 | org.apache.rocketmq 14 | mqtt-common 15 | 16 | 17 | org.apache.rocketmq 18 | mqtt-exporter 19 | 20 | 21 | org.apache.rocketmq 22 | rocketmq-client 23 | 24 | 25 | org.apache.rocketmq 26 | rocketmq-tools 27 | 28 | 29 | io.netty 30 | netty-all 31 | 32 | 33 | org.springframework 34 | spring-core 35 | 36 | 37 | org.springframework 38 | spring-context 39 | 40 | 41 | org.springframework 42 | spring-beans 43 | 44 | 45 | com.github.ben-manes.caffeine 46 | caffeine 47 | 48 | 49 | junit 50 | junit 51 | test 52 | 53 | 54 | org.mockito 55 | mockito-core 56 | test 57 | 58 | 59 | com.alipay.sofa 60 | jraft-core 61 | 62 | 63 | com.alipay.sofa 64 | rpc-grpc-impl 65 | 66 | 67 | 68 | 69 | 8 70 | 8 71 | 72 | 73 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/config/ServiceConfListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.config; 19 | 20 | import org.apache.rocketmq.common.MixAll; 21 | import org.apache.rocketmq.common.ThreadFactoryImpl; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import org.springframework.stereotype.Component; 25 | 26 | import javax.annotation.PostConstruct; 27 | import javax.annotation.Resource; 28 | import java.io.File; 29 | import java.io.FileInputStream; 30 | import java.io.InputStream; 31 | import java.util.Properties; 32 | import java.util.concurrent.ScheduledThreadPoolExecutor; 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.concurrent.atomic.AtomicLong; 35 | 36 | 37 | @Component 38 | public class ServiceConfListener { 39 | private static Logger logger = LoggerFactory.getLogger(ServiceConfListener.class); 40 | 41 | @Resource 42 | private ServiceConf serviceConf; 43 | 44 | private File confFile; 45 | private ScheduledThreadPoolExecutor scheduler; 46 | private AtomicLong gmt = new AtomicLong(); 47 | private long refreshCheckInterval = 3; 48 | 49 | @PostConstruct 50 | public void start() { 51 | confFile = serviceConf.getConfFile(); 52 | gmt.set(confFile.lastModified()); 53 | scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactoryImpl("ServiceConfListener")); 54 | scheduler.scheduleWithFixedDelay(() -> { 55 | try { 56 | if (gmt.get() == confFile.lastModified()) { 57 | return; 58 | } 59 | gmt.set(confFile.lastModified()); 60 | InputStream in = new FileInputStream(confFile.getAbsoluteFile()); 61 | Properties properties = new Properties(); 62 | properties.load(in); 63 | in.close(); 64 | MixAll.properties2Object(properties, serviceConf); 65 | logger.warn("UpdateConf:{}", confFile.getAbsolutePath()); 66 | } catch (Exception e) { 67 | logger.error("", e); 68 | } 69 | }, refreshCheckInterval, refreshCheckInterval, TimeUnit.SECONDS); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/meta/TopicNotExistException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.meta; 19 | 20 | public class TopicNotExistException extends RuntimeException { 21 | public TopicNotExistException() { 22 | } 23 | 24 | public TopicNotExistException(String message) { 25 | super(message); 26 | } 27 | 28 | public TopicNotExistException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | 32 | public TopicNotExistException(Throwable cause) { 33 | super(cause); 34 | } 35 | 36 | public TopicNotExistException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 37 | super(message, cause, enableSuppression, writableStackTrace); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/mq/MqAdmin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.mq; 19 | 20 | 21 | 22 | import org.apache.rocketmq.client.exception.MQClientException; 23 | import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; 24 | 25 | import java.util.Properties; 26 | 27 | public class MqAdmin { 28 | private DefaultMQAdminExt defaultMQAdminExt; 29 | 30 | public MqAdmin(Properties properties) { 31 | this(properties.getProperty("NAMESRV_ADDR")); 32 | } 33 | 34 | public MqAdmin(String nameSrv) { 35 | defaultMQAdminExt = new DefaultMQAdminExt(); 36 | defaultMQAdminExt.setVipChannelEnabled(false); 37 | defaultMQAdminExt.setNamesrvAddr(nameSrv); 38 | } 39 | 40 | public DefaultMQAdminExt getDefaultMQAdminExt() { 41 | return defaultMQAdminExt; 42 | } 43 | 44 | public void setAdminGroup(String group) { 45 | defaultMQAdminExt.setAdminExtGroup(group); 46 | } 47 | 48 | public void start() { 49 | try { 50 | defaultMQAdminExt.start(); 51 | } catch (MQClientException e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/mq/MqProducer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.mq; 19 | 20 | 21 | import org.apache.rocketmq.client.exception.MQClientException; 22 | import org.apache.rocketmq.client.producer.DefaultMQProducer; 23 | import org.apache.rocketmq.common.UtilAll; 24 | 25 | import java.util.Properties; 26 | 27 | 28 | public class MqProducer { 29 | 30 | private DefaultMQProducer defaultMQProducer; 31 | 32 | public MqProducer(Properties properties) { 33 | this(properties.getProperty("NAMESRV_ADDR")); 34 | } 35 | 36 | public MqProducer(String nameSrv) { 37 | defaultMQProducer = new DefaultMQProducer(); 38 | defaultMQProducer.setNamesrvAddr(nameSrv); 39 | defaultMQProducer.setInstanceName(buildInstanceName()); 40 | defaultMQProducer.setVipChannelEnabled(false); 41 | } 42 | 43 | public String buildInstanceName() { 44 | return Integer.toString(UtilAll.getPid()) 45 | + "#" + System.nanoTime(); 46 | } 47 | 48 | public DefaultMQProducer getDefaultMQProducer() { 49 | return defaultMQProducer; 50 | } 51 | 52 | public void setProducerGroup(String producerGroup) { 53 | defaultMQProducer.setProducerGroup(producerGroup); 54 | } 55 | 56 | public void start() { 57 | try { 58 | defaultMQProducer.start(); 59 | } catch (MQClientException e) { 60 | throw new RuntimeException(e); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/mq/MqPullConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.mq; 19 | 20 | import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer; 21 | import org.apache.rocketmq.client.exception.MQClientException; 22 | import org.apache.rocketmq.common.UtilAll; 23 | 24 | import java.util.Properties; 25 | 26 | 27 | public class MqPullConsumer { 28 | private DefaultMQPullConsumer defaultMQPullConsumer; 29 | 30 | public MqPullConsumer(Properties properties) { 31 | this(properties.getProperty("NAMESRV_ADDR")); 32 | } 33 | 34 | public MqPullConsumer(String nameSrv) { 35 | defaultMQPullConsumer = new DefaultMQPullConsumer(); 36 | defaultMQPullConsumer.setNamesrvAddr(nameSrv); 37 | defaultMQPullConsumer.setInstanceName(this.buildInstanceName()); 38 | defaultMQPullConsumer.setVipChannelEnabled(false); 39 | } 40 | 41 | public String buildInstanceName() { 42 | return Integer.toString(UtilAll.getPid()) 43 | + "#" + System.nanoTime(); 44 | } 45 | 46 | public void setConsumerGroup(String consumerGroup) { 47 | defaultMQPullConsumer.setConsumerGroup(consumerGroup); 48 | } 49 | 50 | public DefaultMQPullConsumer getDefaultMQPullConsumer() { 51 | return defaultMQPullConsumer; 52 | } 53 | 54 | public void start() { 55 | try { 56 | defaultMQPullConsumer.start(); 57 | } catch (MQClientException e) { 58 | throw new RuntimeException(e); 59 | } 60 | Runtime.getRuntime().addShutdownHook(new Thread() { 61 | @Override 62 | public void run() { 63 | defaultMQPullConsumer.shutdown(); 64 | } 65 | }); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/upstream/UpstreamProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.upstream; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 22 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 23 | import org.apache.rocketmq.remoting.exception.RemotingException; 24 | 25 | import java.util.concurrent.CompletableFuture; 26 | import java.util.concurrent.ExecutionException; 27 | 28 | public interface UpstreamProcessor { 29 | /** 30 | * process mqtt upstream packet 31 | * @param context 32 | * @param message 33 | * @return 34 | */ 35 | CompletableFuture process(MqttMessageUpContext context, MqttMessage message) throws RemotingException, com.alipay.sofa.jraft.error.RemotingException, ExecutionException, InterruptedException; 36 | } 37 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/upstream/processor/BaseProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.upstream.processor; 19 | 20 | import java.util.concurrent.LinkedBlockingQueue; 21 | import java.util.concurrent.ThreadPoolExecutor; 22 | import java.util.concurrent.TimeUnit; 23 | 24 | import org.apache.rocketmq.common.ThreadFactoryImpl; 25 | import org.apache.rocketmq.mqtt.ds.upstream.UpstreamProcessor; 26 | 27 | 28 | public abstract class BaseProcessor implements UpstreamProcessor { 29 | 30 | protected ThreadPoolExecutor executor = new ThreadPoolExecutor( 31 | 8, 32 | 16, 33 | 1, 34 | TimeUnit.MINUTES, 35 | new LinkedBlockingQueue<>(10000), 36 | new ThreadFactoryImpl("UpstreamBaseProcessor_")); 37 | 38 | } -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/upstream/processor/ConnectProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.upstream.processor; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 22 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 23 | import org.apache.rocketmq.mqtt.ds.upstream.UpstreamProcessor; 24 | import org.springframework.stereotype.Component; 25 | 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | @Component 29 | public class ConnectProcessor extends BaseProcessor implements UpstreamProcessor { 30 | 31 | @Override 32 | public CompletableFuture process(MqttMessageUpContext context, MqttMessage message) { 33 | return HookResult.newHookResult(HookResult.SUCCESS, null, null); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /mqtt-ds/src/main/java/org/apache/rocketmq/mqtt/ds/upstream/processor/DisconnectProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.upstream.processor; 19 | 20 | import io.netty.handler.codec.mqtt.MqttMessage; 21 | import org.apache.rocketmq.mqtt.common.hook.HookResult; 22 | import org.apache.rocketmq.mqtt.common.model.MqttMessageUpContext; 23 | import org.apache.rocketmq.mqtt.ds.upstream.UpstreamProcessor; 24 | import org.springframework.stereotype.Component; 25 | 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | @Component 29 | public class DisconnectProcessor extends BaseProcessor implements UpstreamProcessor { 30 | 31 | @Override 32 | public CompletableFuture process(MqttMessageUpContext context, MqttMessage message) { 33 | return HookResult.newHookResult(HookResult.SUCCESS, null, null); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /mqtt-ds/src/test/java/org/apache/rocketmq/mqtt/ds/test/config/TestServiceConfListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.ds.test.config; 19 | 20 | import org.apache.commons.lang3.reflect.FieldUtils; 21 | import org.apache.rocketmq.mqtt.ds.config.ServiceConf; 22 | import org.apache.rocketmq.mqtt.ds.config.ServiceConfListener; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.Mock; 26 | import org.mockito.junit.MockitoJUnitRunner; 27 | 28 | import java.io.File; 29 | 30 | import static org.mockito.Mockito.times; 31 | import static org.mockito.Mockito.verify; 32 | import static org.mockito.Mockito.when; 33 | 34 | @RunWith(MockitoJUnitRunner.class) 35 | public class TestServiceConfListener { 36 | 37 | @Mock 38 | private ServiceConf serviceConf; 39 | 40 | @Mock 41 | private File confFile; 42 | 43 | private ServiceConfListener confListener; 44 | private final long firstModifiedTime = 1000; 45 | private final long secondModifiedTime = 2000; 46 | 47 | @Test 48 | public void test() throws Exception { 49 | confListener = new ServiceConfListener(); 50 | FieldUtils.writeDeclaredField(confListener, "serviceConf", serviceConf, true); 51 | FieldUtils.writeDeclaredField(confListener, "confFile", confFile, true); 52 | FieldUtils.writeDeclaredField(confListener, "refreshCheckInterval", 1, true); 53 | 54 | when(serviceConf.getConfFile()).thenReturn(confFile); 55 | when(confFile.lastModified()).thenReturn(firstModifiedTime, secondModifiedTime); 56 | when(confFile.getAbsoluteFile()).thenReturn(File.createTempFile("temp", ".properties")); 57 | 58 | confListener.start(); 59 | Thread.sleep(1100); 60 | 61 | verify(serviceConf).getConfFile(); 62 | verify(confFile, times(3)).lastModified(); 63 | verify(confFile).getAbsoluteFile(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /mqtt-ds/src/test/java/org/apache/rocketmq/mqtt/ds/test/notify/TestNotifyRetryManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * * contributor license agreements. See the NOTICE file distributed with 5 | * * this work for additional information regarding copyright ownership. 6 | * * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * * (the "License"); you may not use this file except in compliance with 8 | * * the License. You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package org.apache.rocketmq.mqtt.ds.test.notify; 21 | 22 | import com.alibaba.fastjson.JSON; 23 | import org.apache.commons.lang3.reflect.FieldUtils; 24 | import org.apache.commons.lang3.reflect.MethodUtils; 25 | import org.apache.rocketmq.common.message.MessageExt; 26 | import org.apache.rocketmq.mqtt.common.model.Constants; 27 | import org.apache.rocketmq.mqtt.common.model.MessageEvent; 28 | import org.apache.rocketmq.mqtt.ds.notify.NotifyManager; 29 | import org.apache.rocketmq.mqtt.ds.notify.NotifyRetryManager; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.Mock; 33 | import org.mockito.junit.MockitoJUnitRunner; 34 | 35 | import java.lang.reflect.InvocationTargetException; 36 | import java.nio.charset.StandardCharsets; 37 | import java.util.Collections; 38 | 39 | @RunWith(MockitoJUnitRunner.class) 40 | public class TestNotifyRetryManager { 41 | 42 | @Mock 43 | private NotifyManager notifyManager; 44 | 45 | private NotifyRetryManager notifyRetryManager; 46 | 47 | @Test 48 | public void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { 49 | notifyRetryManager = new NotifyRetryManager(); 50 | FieldUtils.writeDeclaredField(notifyRetryManager, "notifyManager", notifyManager, true); 51 | 52 | MessageExt messageExt = new MessageExt(); 53 | messageExt.putUserProperty(Constants.PROPERTY_MQTT_MSG_EVENT_RETRY_NODE, "test"); 54 | messageExt.putUserProperty(Constants.PROPERTY_MQTT_MSG_EVENT_RETRY_TIME, "1"); 55 | MessageEvent messageEvent = new MessageEvent(); 56 | messageExt.setBody(JSON.toJSONString(Collections.singleton(messageEvent)).getBytes(StandardCharsets.UTF_8)); 57 | 58 | MethodUtils.invokeMethod(notifyRetryManager, true, "doRetryNotify", messageExt); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /mqtt-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rocketmq-mqtt 5 | org.apache.rocketmq 6 | 1.0.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | mqtt-example 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | org.eclipse.paho 20 | org.eclipse.paho.client.mqttv3 21 | 1.2.2 22 | 23 | 24 | org.apache.rocketmq 25 | mqtt-common 26 | 27 | 28 | -------------------------------------------------------------------------------- /mqtt-example/src/main/java/org/apache/rocketmq/mqtt/example/RocketMQConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.example; 19 | 20 | import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; 21 | import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; 22 | import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; 23 | import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; 24 | import org.apache.rocketmq.client.exception.MQClientException; 25 | import org.apache.rocketmq.common.message.MessageExt; 26 | import org.apache.rocketmq.mqtt.common.model.Constants; 27 | 28 | import java.text.SimpleDateFormat; 29 | import java.util.Date; 30 | import java.util.List; 31 | 32 | public class RocketMQConsumer { 33 | 34 | public static void main(String[] args) throws MQClientException { 35 | // Instantiate with specified consumer group name. 36 | DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("GID_test01"); 37 | 38 | // Specify name server addresses. 39 | consumer.setNamesrvAddr(System.getenv("namesrv")); 40 | 41 | // Subscribe one more more topics to consume. 42 | String firstTopic = System.getenv("firstTopic"); 43 | consumer.subscribe(firstTopic, Constants.MQTT_TAG); 44 | // Register callback to execute on arrival of messages fetched from brokers. 45 | consumer.registerMessageListener(new MessageListenerConcurrently() { 46 | 47 | @Override 48 | public ConsumeConcurrentlyStatus consumeMessage(List msgs, 49 | ConsumeConcurrentlyContext context) { 50 | MessageExt messageExt = msgs.get(0); 51 | System.out.println(now() + "Receive: " + new String(messageExt.getBody())); 52 | return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; 53 | } 54 | }); 55 | 56 | //Launch the consumer instance. 57 | consumer.start(); 58 | 59 | System.out.printf("Consumer Started.%n"); 60 | } 61 | 62 | private static String now() { 63 | SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); 64 | return sf.format(new Date()) + "\t"; 65 | } 66 | } -------------------------------------------------------------------------------- /mqtt-exporter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rocketmq-mqtt 5 | org.apache.rocketmq 6 | 1.0.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | mqtt-exporter 11 | 12 | 13 | 14 | io.prometheus 15 | simpleclient 16 | 17 | 18 | io.prometheus 19 | simpleclient_hotspot 20 | 21 | 22 | io.prometheus 23 | simpleclient_httpserver 24 | 25 | 26 | org.slf4j 27 | slf4j-api 28 | 29 | 30 | ch.qos.logback 31 | logback-classic 32 | 33 | 34 | com.google.guava 35 | guava 36 | 37 | 38 | -------------------------------------------------------------------------------- /mqtt-exporter/src/main/java/org/apache/rocketmq/mqtt/exporter/MqttExporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.exporter; 19 | 20 | import io.prometheus.client.hotspot.DefaultExports; 21 | import org.apache.rocketmq.mqtt.exporter.collector.MqttMetricsCollector; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | public class MqttExporter { 26 | protected static final Logger LOG = LoggerFactory.getLogger(MqttExporter.class); 27 | 28 | private final String nameSpace; 29 | private final String hostName; 30 | private final String hostIp; 31 | private final int exporterPort; 32 | private final boolean exportJvmInfo; 33 | 34 | public MqttExporter(String nameSpace, String hostName, String hostIp, int exporterPort, boolean exportJvmInfo) { 35 | this.nameSpace = nameSpace; 36 | this.hostName = hostName; 37 | this.hostIp = hostIp; 38 | this.exporterPort = exporterPort; 39 | this.exportJvmInfo = exportJvmInfo; 40 | } 41 | 42 | public void start() throws Exception { 43 | if (this.exportJvmInfo) { 44 | DefaultExports.initialize(); 45 | } 46 | MqttMetricsCollector.initialize(this.nameSpace, this.hostName, this.hostIp, this.exporterPort); 47 | LOG.info("metrics exporter start success"); 48 | 49 | } 50 | 51 | public void shutdown() { 52 | MqttMetricsCollector.shutdown(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /mqtt-exporter/src/main/java/org/apache/rocketmq/mqtt/exporter/collector/MetricsBuilderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.exporter.collector; 19 | 20 | import io.prometheus.client.Counter; 21 | import io.prometheus.client.Gauge; 22 | import io.prometheus.client.Histogram; 23 | import io.prometheus.client.SimpleCollector.Builder; 24 | 25 | public class MetricsBuilderFactory { 26 | 27 | private static Builder newGaugeBuilder(MqttMetricsInfo mqttMetricsInfo) { 28 | return Gauge.build(). 29 | name(mqttMetricsInfo.getName()). 30 | help(mqttMetricsInfo.getHelp()). 31 | labelNames(mqttMetricsInfo.getLabelNames()); 32 | 33 | } 34 | 35 | private static Builder newCounterBuilder(MqttMetricsInfo mqttMetricsInfo) { 36 | return Counter.build(). 37 | name(mqttMetricsInfo.getName()). 38 | help(mqttMetricsInfo.getHelp()). 39 | labelNames(mqttMetricsInfo.getLabelNames()); 40 | } 41 | 42 | private static Builder newHistogramBuilder(MqttMetricsInfo mqttMetricsInfo) { 43 | return Histogram.build(). 44 | name(mqttMetricsInfo.getName()). 45 | help(mqttMetricsInfo.getHelp()). 46 | labelNames(mqttMetricsInfo.getLabelNames()). 47 | buckets(mqttMetricsInfo.getBuckets()); 48 | } 49 | 50 | public static Builder newCollectorBuilder(MqttMetricsInfo mqttMetricsInfo) { 51 | switch (mqttMetricsInfo.getType()) { 52 | case COUNTER: 53 | return newCounterBuilder(mqttMetricsInfo); 54 | case GAUGE: 55 | return newGaugeBuilder(mqttMetricsInfo); 56 | case HISTOGRAM: 57 | return newHistogramBuilder(mqttMetricsInfo); 58 | default: 59 | break; 60 | 61 | } 62 | return null; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /mqtt-exporter/src/main/java/org/apache/rocketmq/mqtt/exporter/collector/SubSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.exporter.collector; 19 | 20 | public enum SubSystem { 21 | DS("ds"), 22 | CS("cs"); 23 | 24 | private final String value; 25 | 26 | SubSystem(String value) { 27 | this.value = value; 28 | } 29 | 30 | public String getValue() { 31 | return value; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "SubSystem{" + 37 | "value='" + value + '\'' + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mqtt-exporter/src/main/java/org/apache/rocketmq/mqtt/exporter/exception/PrometheusException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.exporter.exception; 19 | 20 | public class PrometheusException extends Exception { 21 | 22 | public PrometheusException(String message) { 23 | super(message); 24 | } 25 | 26 | public PrometheusException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | 30 | public PrometheusException(Throwable cause) { 31 | super(cause); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mqtt-meta/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | rocketmq-mqtt 6 | org.apache.rocketmq 7 | 1.0.2-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | mqtt-meta 12 | 13 | mqtt-meta 14 | 15 | 16 | 4.3.16.RELEASE 17 | 8 18 | 8 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | 25 | io.grpc 26 | protoc-gen-grpc-java 27 | pom 28 | 29 | 30 | 31 | io.grpc 32 | grpc-testing 33 | 34 | 35 | com.alipay.sofa 36 | jraft-core 37 | 38 | 39 | com.alipay.sofa 40 | rpc-grpc-impl 41 | 42 | 43 | com.alipay.sofa 44 | jraft-rheakv-core 45 | 46 | 47 | org.apache.rocketmq 48 | mqtt-common 49 | 50 | 51 | org.mockito 52 | mockito-core 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/config/MetaConfListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.config; 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.InputStream; 23 | import java.util.Properties; 24 | import java.util.concurrent.ScheduledThreadPoolExecutor; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.concurrent.atomic.AtomicLong; 27 | import javax.annotation.PostConstruct; 28 | import javax.annotation.Resource; 29 | 30 | import org.apache.rocketmq.common.MixAll; 31 | import org.apache.rocketmq.common.ThreadFactoryImpl; 32 | import org.slf4j.Logger; 33 | import org.slf4j.LoggerFactory; 34 | import org.springframework.stereotype.Component; 35 | 36 | @Component 37 | public class MetaConfListener { 38 | private static Logger logger = LoggerFactory.getLogger(MetaConfListener.class); 39 | 40 | @Resource 41 | private MetaConf metaConf; 42 | 43 | private File confFile; 44 | private ScheduledThreadPoolExecutor scheduler; 45 | private AtomicLong gmt = new AtomicLong(); 46 | private long refreshSecs = 3; 47 | 48 | @PostConstruct 49 | public void start() { 50 | confFile = metaConf.getConfFile(); 51 | if (confFile == null) { 52 | return; 53 | } 54 | gmt.set(confFile.lastModified()); 55 | scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactoryImpl("ConnectConfListener")); 56 | scheduler.scheduleWithFixedDelay(() -> { 57 | try { 58 | if (gmt.get() == confFile.lastModified()) { 59 | return; 60 | } 61 | gmt.set(confFile.lastModified()); 62 | InputStream in = new FileInputStream(confFile.getAbsoluteFile()); 63 | Properties properties = new Properties(); 64 | properties.load(in); 65 | in.close(); 66 | MixAll.properties2Object(properties, metaConf); 67 | logger.warn("UpdateConf:{}", confFile.getAbsolutePath()); 68 | } catch (Exception e) { 69 | logger.error("", e); 70 | } 71 | }, refreshSecs, refreshSecs, TimeUnit.SECONDS); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/raft/FailoverClosure.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.raft; 19 | 20 | import com.alipay.sofa.jraft.Closure; 21 | import org.apache.rocketmq.mqtt.common.model.consistency.Response; 22 | 23 | public interface FailoverClosure extends Closure { 24 | 25 | void setResponse(Response response); 26 | 27 | void setThrowable(Throwable throwable); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/raft/MqttApplyListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.raft; 19 | 20 | import com.google.protobuf.Message; 21 | import org.apache.rocketmq.mqtt.meta.rocksdb.RocksDBEngine; 22 | 23 | public interface MqttApplyListener { 24 | 25 | /** 26 | * never to block 27 | * 28 | * @param message 29 | * @param rocksDBEngine 30 | */ 31 | void onApply(Message message, RocksDBEngine rocksDBEngine); 32 | } 33 | -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/raft/rpc/MqttWriteRpcProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.raft.rpc; 19 | 20 | import com.alipay.sofa.jraft.rpc.RpcContext; 21 | import com.alipay.sofa.jraft.rpc.RpcProcessor; 22 | import org.apache.rocketmq.mqtt.common.model.consistency.WriteRequest; 23 | import org.apache.rocketmq.mqtt.common.util.StatUtil; 24 | import org.apache.rocketmq.mqtt.meta.raft.MqttRaftServer; 25 | 26 | /** 27 | * The RPC Processor for write request 28 | */ 29 | public class MqttWriteRpcProcessor extends AbstractRpcProcessor implements RpcProcessor { 30 | private final MqttRaftServer server; 31 | 32 | public MqttWriteRpcProcessor(MqttRaftServer server) { 33 | this.server = server; 34 | } 35 | 36 | @Override 37 | public void handleRequest(RpcContext rpcCtx, WriteRequest request) { 38 | StatUtil.addPv(StatUtil.buildKey("WriteRpc", request.getGroup()), 1); 39 | handleRequest(server, request.getGroup(), rpcCtx, request); 40 | } 41 | 42 | @Override 43 | public String interest() { 44 | return WriteRequest.class.getName(); 45 | } 46 | } -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/starter/MetaStartup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.rocketmq.mqtt.meta.starter; 18 | 19 | import org.apache.rocketmq.mqtt.meta.util.SpringUtil; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.context.support.ClassPathXmlApplicationContext; 23 | 24 | public class MetaStartup { 25 | private static final Logger LOGGER = LoggerFactory.getLogger(MetaStartup.class); 26 | 27 | public static void main(String[] args) { 28 | 29 | ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:meta_spring.xml"); 30 | SpringUtil.setApplicationContext(applicationContext); 31 | LOGGER.info("start meta ..."); 32 | } 33 | } -------------------------------------------------------------------------------- /mqtt-meta/src/main/java/org/apache/rocketmq/mqtt/meta/util/SpringUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.util; 19 | 20 | import org.springframework.context.ApplicationContext; 21 | 22 | public class SpringUtil { 23 | 24 | private static ApplicationContext applicationContext; 25 | 26 | public static void setApplicationContext(ApplicationContext applicationContext) { 27 | SpringUtil.applicationContext = applicationContext; 28 | } 29 | 30 | public static T getBeanByClass(Class requiredType) { 31 | return applicationContext.getBean(requiredType); 32 | } 33 | 34 | public static Object getBean(String beanName) 35 | { 36 | return applicationContext.getBean(beanName); 37 | } 38 | 39 | 40 | public static ApplicationContext getApplicationContext() { 41 | return applicationContext; 42 | } 43 | } -------------------------------------------------------------------------------- /mqtt-meta/src/test/java/org/apache/rocketmq/mqtt/meta/util/IpUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.apache.rocketmq.mqtt.meta.util; 19 | 20 | import org.apache.rocketmq.mqtt.common.meta.IpUtil; 21 | import org.apache.rocketmq.mqtt.meta.config.MetaConf; 22 | import org.junit.Assert; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.Mock; 26 | import org.mockito.junit.MockitoJUnitRunner; 27 | 28 | import static org.mockito.Mockito.when; 29 | 30 | 31 | /** 32 | * @author dongyuan.pdy 33 | * date 2022-05-31 34 | */ 35 | 36 | @RunWith(MockitoJUnitRunner.class) 37 | public class IpUtilTest { 38 | @Mock 39 | private MetaConf serviceConf; 40 | 41 | @Test 42 | public void convertAllNodeAddressTest() { 43 | when(serviceConf.getAllNodeAddress()).thenReturn("127.0.0.1"); 44 | when(serviceConf.getMetaPort()).thenReturn(25000); 45 | String allNodes = IpUtil.convertAllNodeAddress(serviceConf.getAllNodeAddress(), serviceConf.getMetaPort()); 46 | Assert.assertEquals("127.0.0.1:25000", allNodes); 47 | 48 | when(serviceConf.getAllNodeAddress()).thenReturn("127.0.0.1,127.0.0.2"); 49 | when(serviceConf.getMetaPort()).thenReturn(25000); 50 | String allNodes1 = IpUtil.convertAllNodeAddress(serviceConf.getAllNodeAddress(), serviceConf.getMetaPort()); 51 | Assert.assertEquals("127.0.0.1:25000,127.0.0.2:25000", allNodes1); 52 | } 53 | 54 | @Test 55 | public void getLocalAddressCompatible() { 56 | String ip = IpUtil.getLocalAddressCompatible(); 57 | Assert.assertNotNull(ip); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /style/copyright/Apache.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /style/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 31 | 32 | 35 | 36 | 39 | 40 | 43 | 44 | 47 | 48 | 51 | 52 | 55 | 56 | 59 | 60 | 63 | 64 | --------------------------------------------------------------------------------