GithubHelp home page GithubHelp logo

streamnative / mop Goto Github PK

View Code? Open in Web Editor NEW
164.0 25.0 51.0 3.38 MB

MQTT on Pulsar implemented using Pulsar Protocol Handler

License: Apache License 2.0

Java 99.19% Python 0.36% Shell 0.42% Dockerfile 0.04%
apache-pulsar mqtt mqtt-broker protocol-handler mop messaging iot pulsar

mop's Introduction

Codacy Badge LICENSE

MQTT on Pulsar (MoP)

MQTT-on-Pulsar (aka MoP) is developed to support MQTT protocol natively on Apache Pulsar.

Get started

Download or build MoP protocol handler

  1. Clone the MoP project from GitHub to your local.

    git clone https://github.com/streamnative/mop.git
    cd mop
  2. Build the project.

    mvn clean install -DskipTests
  3. The NAR file can be found at this location.

    ./mqtt-impl/target/pulsar-protocol-handler-mqtt-${version}.nar

Install MoP protocol handler

Configure the Pulsar broker to run the MoP protocol handler as a plugin by adding configurations to the Pulsar configuration file, such as broker.conf or standalone.conf.

  1. Set the configuration of the MoP protocol handler.

    Add the following properties and set their values in the Pulsar configuration file, such as conf/broker.conf or conf/standalone.conf.

    Property Suggested value Default value
    messagingProtocols mqtt null
    protocolHandlerDirectory Location of MoP NAR file ./protocols

    Example

    messagingProtocols=mqtt
    protocolHandlerDirectory=./protocols
    
  2. Set the MQTT server listeners.

    Example

    mqttListeners=mqtt://127.0.0.1:1883
    advertisedAddress=127.0.0.1
    

    Note

    The default hostname of advertisedAddress is InetAddress.getLocalHost().getHostName(). If you'd like to config this, please keep the same as Pulsar broker's advertisedAddress.

Load MoP protocol handler

After you install the MoP protocol handler to Pulsar broker, you can restart the Pulsar brokers to load the MoP protocol handler.

How to use Proxy

To use the proxy, follow the following steps. For detailed steps, refer to Deploy a cluster on bare metal.

  1. Prepare a ZooKeeper cluster.

  2. Initialize the cluster metadata.

  3. Prepare a BookKeeper cluster.

  4. Copy the pulsar-protocol-handler-mqtt-${version}.nar to the $PULSAR_HOME/protocols directory.

  5. Start the Pulsar broker.

    Here is an example of the Pulsar broker configuration.

    messagingProtocols=mqtt
    protocolHandlerDirectory=./protocols
    brokerServicePort=6651
    mqttListeners=mqtt://127.0.0.1:1883
    advertisedAddress=127.0.0.1
    
    mqttProxyEnabled=true
    mqttProxyPort=5682

Verify MoP protocol handler

There are many MQTT client that can be used to verify the MoP protocol handler, such as MQTTBox, MQTT Toolbox. You can choose a CLI tool or interface tool to verify the MoP protocol handler.

The following example shows how to verify the MoP protocol handler with FuseSource MqttClient.

  1. Add the dependency.

    <dependency>
        <groupId>org.fusesource.mqtt-client</groupId>
        <artifactId>mqtt-client</artifactId>
        <version>1.16</version>
    </dependency>
  2. Publish messages and consume messages.

    MQTT mqtt = new MQTT();
    mqtt.setHost("127.0.0.1", 1883);
    BlockingConnection connection = mqtt.blockingConnection();
    connection.connect();
    Topic[] topics = { new Topic("persistent://public/default/my-topic", QoS.AT_LEAST_ONCE) };
    connection.subscribe(topics);
    
    // publish message
    connection.publish("persistent://public/default/my-topic", "Hello MOP!".getBytes(), QoS.AT_LEAST_ONCE, false);
    
    // receive message
    Message received = connection.receive();

Security

Enabling Authentication

MoP currently supports basic and token authentication methods. The token authentication method works with any of the token based Pulsar authentication providers such as the built-in JWT provider and external token authentication providers like biscuit-pulsar.

To use authentication for MQTT connections your Pulsar cluster must already have authentication enabled with your chosen authentication provider(s) configured.

You can then enable MQTT authentication with the following configuration properties:

mqttAuthenticationEnabled=true
mqttAuthenticationMethods=token

mqttAuthenticationMethods can be set to a comma delimited list if you wish to enable multiple authentication providers. MoP will attempt each in order when authenticating client connections.

With authentication enabled MoP will not allow anonymous connections currently.

Authenticating client connections

Basic Authentication

Set the MQTT username and password client settings.

Token Authentication

Set the MQTT password to the token body, currently username will be disregarded but MUST be set to some value as this is required by the MQTT specification.

Enabling Authorization

MoP currently supports authorization. When authorization enabled, MoP will check the authenticated role if it has the ability to pub/sub topics, eg: When sending messages, you need to have the produce permission of the topic. When subscribing to a topic, you need to have the consume permission of the topic. You can reference here to grant permissions.

You can then enable MQTT authorization with the following configuration properties:

mqttAuthorizationEnabled=true

If MoP proxy enabled, following configuration needs to be configured and brokerClientAuthenticationParameters should configure lookup permission at least:

brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationBasic
brokerClientAuthenticationParameters={"userId":"superUser","password":"superPass"}

Enabling TLS

MoP currently supports TLS transport encryption.

Generate crt and key file :

openssl genrsa 2048 > server.key
chmod 400 server.key
openssl req -new -x509 -nodes -sha256 -days 365 -key server.key -out server.crt

TLS with broker

  1. Config mqtt broker to load tls config.

    mqttListeners=mqtt+ssl://127.0.0.1:8883
    mqttTlsCertificateFilePath=/xxx/server.crt
    mqttTlsKeyFilePath=/xxx/server.key
    
  2. Config client to load tls config.

    MQTT mqtt = new MQTT();
    // default tls port
    mqtt.setHost(URI.create("ssl://127.0.0.1:8883")); 
    File crtFile = new File("server.crt");
    Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("server", certificate);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    mqtt.setSslContext(sslContext);
    BlockingConnection connection = mqtt.blockingConnection();
    connection.connect();

TLS with proxy

  1. Config mqtt broker to load tls config.

    mqttProxyEnable=true
    mqttProxyTlsEnabled=true
    mqttTlsCertificateFilePath=/xxx/server.crt
    mqttTlsKeyFilePath=/xxx/server.key
    
  2. Config client to load tls config.

    MQTT mqtt = new MQTT();
    // default proxy tls port
    mqtt.setHost(URI.create("ssl://127.0.0.1:5683")); 
    File crtFile = new File("server.crt");
    Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("server", certificate);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    mqtt.setSslContext(sslContext);
    BlockingConnection connection = mqtt.blockingConnection();
    connection.connect();

TLS PSK with broker

Please reference here to learn more about TLS-PSK.

  1. Config mqtt broker to load tls psk config.

    mqttTlsPskEnabled=true
    mqttListeners=mqtt+ssl+psk://127.0.0.1:8884
    // any string can be specified
    mqttTlsPskIdentityHint=alpha
    // identity is semicolon list of string with identity:secret format
    mqttTlsPskIdentity=mqtt:mqtt123
    

    Optional configs

    Config key Comment
    mqttTlsPskIdentityFile When you want identities in a single file with many pairs, you can config this. Identities will load from both tlsPskIdentity and tlsPskIdentityFile
    mqttTlsProtocols TLS PSK protocols, default are [ TLSv1, TLSv1.1, TLSv1.2 ]
    mqttTlsCiphers TLS PSK ciphers, default are [ TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, TLS_PSK_WITH_AES_128_CBC_SHA, TLS_PSK_WITH_AES_256_CBC_SHA ]
  2. As current known mqtt Java client does not support TLS-PSK, it's better to verify this by mosquitto cli

    # Default with tlsv1.2
    mosquitto_pub --psk-identity mqtt --psk 6d717474313233 -p 8884 -t "/a/b/c" -m "hello mqtt"
    
    # Test with tlsv1.1
    mosquitto_pub --psk-identity mqtt --psk 6d717474313233 -p 8884 -t "/a/b/c" -m "hello mqtt" --tls-version tlsv1.1
    
    # Test with tlsv1
    mosquitto_pub --psk-identity mqtt --psk 6d717474313233 -p 8884 -t "/a/b/c" -m "hello mqtt" --tls-version tlsv1
    

TLS PSK with proxy

  1. Config mqtt proxy to load tls psk config.

    mqttProxyEnable=true
    mqttProxyTlsPskEnabled=true
    // default tls psk port
    mqttProxyTlsPskPort=5684
    // any string can be specified
    mqttTlsPskIdentityHint=alpha
    // identity is semicolon list of string with identity:secret format
    mqttTlsPskIdentity=mqtt:mqtt123
    
  2. Test with mosquitto cli

    mosquitto_pub --psk-identity mqtt --psk 6d717474313233 -p 5684 -t "/a/b/c" -m "hello mqtt"
    
  3. Add PSK identities dynamically.

    You can add psk identities dynamically by REST API in proxy mode.

    curl -X POST http://pulsar-broker-webservice-address:port/mop/add_psk_identity -d "identity=mqtt2:mqtt222;mqtt3:mqtt333"
    

Topic Names & Filters

For Apache Pulsar, The topic name consists of 4 parts:

<domain>://<tenant>/<namespace>/<local-name>

And / is not allowed in the local topic name. But for the MQTT topic name can have multiple levels such as:

/a/b/c/d/e/f

MoP mapping the MQTT topic name to Pulsar topic name as follows:

  1. If the MQTT topic name does not start with the topic domain, MoP treats the URL encoded MQTT topic name as the Pulsar local topic name, and the default tenant and default namespace will be used to map the Pulsar topic name.
  2. If the MQTT topic name starts with the topic domain, MoP will treat the first level topic name as the tenant and the second level topic name as the namespace and the remaining topic name levels will be covert as the local topic name with URL encoded.

Examples:

MQTT topic name Apache Pulsar topic name
/a/b/c persistent://public/default/%2Fa%2Fb%2Fc
a persistent://public/default/a
persistent://my-tenant/my-ns/a/b/c persistent://my-tenant/my-ns/a%2Fb%2Fc
persistent://my-tenant/my-ns/a persistent://my-tenant/my-ns/a
non-persistent://my-tenant/my-ns/a non-persistent://my-tenant/my-ns/a
non-persistent://my-tenant/my-ns/a/b/c non-persistent://my-tenant/my-ns/a%2Fb%2Fc

So if you want to consume messages by Pulsar Client from the topic /a/b/c, the topic name for the Pulsar consumer should be persistent://public/default/%2Fa%2Fb%2Fc. If you want to consume messages from a Pulsar topic by the MQTT client, use the Pulsar topic name as the MQTT topic name directly.

MoP topic supports single-level wildcard + and multi-level wildcard #. The topic name filter also follows the above topic name mapping rules.

  1. If the topic filter starts with the topic domain, MoP only filters the topic under the namespace that the topic filter provided.
  2. If the topic filter does not start with the topic domain, MoP only filters the topic name under the default namespace.

Examples:

MQTT topic name Topic filter Is match
/a/b/c /a/+/c Yes
/a/b/c /a/# Yes
/a/b/c a/# No
/a/b/c persistent://my-tenant/my-namespace//a/# No
/a/b/c persistent://public/default//a/# Yes
persistent://public/default/a/b/c persistent://public/default/a/# Yes
persistent://public/default/a/b/c persistent://public/default/a/+/c Yes
persistent://public/default/a/b/c persistent://public/default//a/+/c No
persistent://public/default/a/b/c persistent://my-tenant/my-namespace/a/+/c No

Notice:

The default tenant and the default namespace for the MoP are configurable, by default, the default tenant is public and the default namespace is default.

Metrics

MoP will uniformly output its own metrics to Prometheus.

Name Type Description
mop_active_client_count Gauge The active client count
mop_total_client_count Counter The total client count
mop_maximum_client_count Counter The maximum client count
mop_sub_count Gauge The subscription count
mop_send_count Counter The total send msg count
mop_send_bytes Counter The total send msg in bytes
mop_received_count Counter The total received msg count
mop_received_bytes Counter The total received msg in bytes

MoP can also expose metrics through the http interface. Add below configs first and then restart pulsar broker.

additionalServlets=mqtt-servlet
additionalServletDirectory=[protocolHandlerDir]

Then you can obtain mop information in json format through /mop/stats:

curl http://pulsar-broker-webservice-address:port/mop/stats
{"cluster":"test","subscriptions":{"subs":["/a/b/c"],"count":1},"clients":{"total":1,"maximum":1,"active":0,"active_clients":[]},"namespace":"default","messages":{"received_bytes":57351,"received_count":10,"send_count":20,"send_bytes":60235},"version":"2.9.0-SNAPSHOT","tenant":"public","uptime":"46 seconds"}

MoP available configurations

Please refer here

Using MQTT over WebSocket

Please refer here

Project maintainers

License

This library is licensed under the terms of the Apache License 2.0 and may include packages written by third parties which carry their own copyright notices and license terms.

About StreamNative

Founded in 2019 by the original creators of Apache Pulsar, StreamNative is one of the leading contributors to the open-source Apache Pulsar project. We have helped engineering teams worldwide make the move to Pulsar with StreamNative Cloud, a fully managed service to help teams accelerate time-to-production.

mop's People

Contributors

beyondyinjl2 avatar caihualin avatar casuallc avatar codacy-badger avatar codelipenghui avatar coderzc avatar dependabot[bot] avatar gaoran10 avatar geomagilles avatar hhh551 avatar huanli-meng avatar hujie6 avatar joecqupt avatar josephglanville avatar liangyuanpeng avatar mattisonchao avatar merlimat avatar sijie avatar simon2579 avatar technoboy- avatar tsturzl avatar wolfstudy avatar yaalsn avatar yimiun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mop's Issues

[Tests] MoP Tests

  • Integration tests
  • Stability tests
  • Performance tests
  • Test with Proxy and multiple MoP brokers.

Request is denied: namespace=public/default

Env:
pulsar official helm deployed in k8s
version:
pulsar:2.7.2
mop:master
Exception:

image

I try restart client to subscribe topic , and three or four times, one success,pls

released source can not build package

I download verified released source v2.7.1.4 and run mvn clean install -DskipTests, just got the error.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-remote-resources-plugin:1.5:process (process-resource-bundles) on project pulsar-protocol-handler-mqtt-parent: Failed to resolve dependencies for one or more projects in the reactor. Reason: Unable to get dependency information for org.apache.pulsar:pulsar-broker:jar:2.7.1.4: Failed to retrieve POM for org.apache.pulsar:pulsar-broker:jar:2.7.1.4: Could not transfer artifact org.apache.pulsar:pulsar-broker:pom:2.7.1.4 from/to bintray-streamnative-maven (https://dl.bintray.com/streamnative/maven): Access denied to: https://dl.bintray.com/streamnative/maven/org/apache/pulsar/pulsar-broker/2.7.1.4/pulsar-broker-2.7.1.4.pom , ReasonPhrase:Forbidden.
[ERROR]   org.apache.pulsar:pulsar-broker:jar:2.7.1.4

I wonder is this the design??

When mqtt proxy port 5682 is connected, there is a + or # sign in the subscription topic, and an error is reported

pulsar version 2.8.1
mop 2.8.1.0

When mqtt 1883 port is connected, there is a + or # sign in the subscription topic. It is normal

When mqtt proxy port 5682 is connected, there is a + or # sign in the subscription topic, and an error is reported, Disconnect

topic example: /a/#
error:
17:48:10.693 [pulsar-io-29-3] INFO io.streamnative.pulsar.handlers.mqtt.support.DefaultProtocolMethodProcessorImpl - [Subscribe] [[id: 0x7bfe505e, L:/127.0.0.1:1883 - R:/127.0.0.1:60697]] msg: MqttSubscribeMessage[fixedHeader=MqttFixedHeader[messageType=SUBSCRIBE, isDup=false, qosLevel=AT_LEAST_ONCE, isRetain=false, remainingLength=9], variableHeader=MqttMessageIdAndPropertiesVariableHeader[messageId=51601, properties=io.netty.handler.codec.mqtt.MqttProperties@1dcb8506], payload=MqttSubscribePayload[MqttTopicSubscription[topicFilter=/a/#, option=SubscriptionOption[qos=AT_MOST_ONCE, noLocal=false, retainAsPublished=false, retainHandling=SEND_AT_SUBSCRIBE]]]]
17:48:10.694 [pulsar-io-29-3] ERROR io.streamnative.pulsar.handlers.mqtt.support.DefaultProtocolMethodProcessorImpl - [null] Failed to process MQTT subscribe.
java.util.concurrent.CompletionException: java.lang.NullPointerException
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273) ~[?:1.8.0_171]
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280) ~[?:1.8.0_171]
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:659) ~[?:1.8.0_171]
at java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:669) ~[?:1.8.0_171]
at java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:1997) [?:1.8.0_171]
at io.streamnative.pulsar.handlers.mqtt.utils.PulsarTopicUtils.getOrCreateSubscription(PulsarTopicUtils.java:71) ~[?:?]
at io.streamnative.pulsar.handlers.mqtt.support.DefaultProtocolMethodProcessorImpl.lambda$processSubscribe$1(DefaultProtocolMethodProcessorImpl.java:317) ~[?:?]
at java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:981) [?:1.8.0_171]
at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2124) [?:1.8.0_171]
at io.streamnative.pulsar.handlers.mqtt.support.DefaultProtocolMethodProcessorImpl.processSubscribe(DefaultProtocolMethodProcessorImpl.java:313) [HeTx-YSOEoMroq5t1w13wQ/:?]
at io.streamnative.pulsar.handlers.mqtt.MQTTInboundHandler.channelRead(MQTTInboundHandler.java:63) [HeTx-YSOEoMroq5t1w13wQ/:?]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) [io.netty-netty-codec-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) [io.netty-netty-codec-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) [io.netty-netty-handler-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) [io.netty-netty-common-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [io.netty-netty-common-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [io.netty-netty-common-4.1.66.Final.jar:4.1.66.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
Caused by: java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878) ~[com.google.guava-guava-30.1-jre.jar:?]
at org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap.get(ConcurrentOpenHashMap.java:102) ~[org.apache.pulsar-pulsar-common-2.8.1.jar:2.8.1]
at org.apache.pulsar.broker.service.persistent.PersistentTopic.getSubscription(PersistentTopic.java:1596) ~[org.apache.pulsar-pulsar-broker-2.8.1.jar:2.8.1]
at org.apache.pulsar.broker.service.persistent.PersistentTopic.getSubscription(PersistentTopic.java:163) ~[org.apache.pulsar-pulsar-broker-2.8.1.jar:2.8.1]
at io.streamnative.pulsar.handlers.mqtt.utils.PulsarTopicUtils.lambda$getOrCreateSubscription$3(PulsarTopicUtils.java:76) ~[?:?]
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:656) ~[?:1.8.0_171]
... 33 more
17:48:18.314 [pulsar-client-io-72-1] ERROR io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyProtocolMethodProcessor - The broker channel((localhost,1883)) is not writable!

TLS listener support.

Currently MoP only supports plaintext connections. TLS support should be able to be enabled on a per-listener basis.

mac os uses mqtt to report an error: Lorg/apache/pulsar/broker/ServiceConfiguration;)Ljava/lang/String;

macos big sur11.4
apache-pulsar-2.8.0/protocols/
2 versions
pulsar-protocol-handler-mqtt-2.9.0-SNAPSHOT.nar
pulsar-protocol-handler-mqtt-2.8.0.8.nar

vim conf/standalone.conf
messagingProtocols=mqtt
protocolHandlerDirectory=./protocols
brokerServicePort=6651
mqttListeners=mqtt://127.0.0.1:1883
advertisedAddress=127.0.0.1

mqttProxyEnable=true
mqttProxyPort=5682

start pulsar
bin/pulsar standalone

error:
ERROR org.apache.pulsar.PulsarStandaloneStarter - Failed to start pulsar service.
java.lang.NoSuchMethodError: org.apache.pulsar.broker.PulsarService.advertisedAddress(Lorg/apache/pulsar/broker/ServiceConfiguration;)Ljava/lang/String;
at io.streamnative.pulsar.handlers.mqtt.MQTTProtocolHandler.start(MQTTProtocolHandler.java:95) ~[?:?]
at org.apache.pulsar.broker.protocol.ProtocolHandlerWithClassLoader.start(ProtocolHandlerWithClassLoader.java:66) ~[org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
at org.apache.pulsar.broker.protocol.ProtocolHandlers.lambda$start$4(ProtocolHandlers.java:142) ~[org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
at java.lang.Iterable.forEach(Iterable.java:75) ~[?:1.8.0_171]
at org.apache.pulsar.broker.protocol.ProtocolHandlers.start(ProtocolHandlers.java:142) ~[org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
at org.apache.pulsar.broker.PulsarService.start(PulsarService.java:785) ~[org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
at org.apache.pulsar.PulsarStandalone.start(PulsarStandalone.java:296) ~[org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
at org.apache.pulsar.PulsarStandaloneStarter.main(PulsarStandaloneStarter.java:121) [org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]
16:12:37.229 [Thread-1] INFO org.apache.pulsar.broker.service.GracefulExecutorServicesTerminationHandler - Starting termination handler for 4 executors.
16:12:37.229 [globalEventExecutor-2-2] INFO org.apache.pulsar.broker.service.GracefulExecutorServicesTerminationHandler - Starting termination handler for 7 executors.
16:12:37.230 [Thread-1] INFO org.apache.pulsar.broker.service.GracefulExecutorServicesTerminationHandler - Shutdown completed.
16:12:37.230 [globalEventExecutor-2-2] INFO org.apache.pulsar.broker.service.GracefulExecutorServicesTerminationHandler - Shutdown completed.
16:12:37.386 [Thread-1] ERROR org.apache.bookkeeper.client.MetadataUpdateLoop - UpdateLoop(ledgerId=855,loopId=41e400ad) Error writing metadata to store
org.apache.bookkeeper.client.BKException$BKClientClosedException: BookKeeper client is closed
at org.apache.bookkeeper.meta.CleanupLedgerManager.close(CleanupLedgerManager.java:245) ~[org.apache.bookkeeper-bookkeeper-server-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.client.BookKeeper.close(BookKeeper.java:1439) ~[org.apache.bookkeeper-bookkeeper-server-4.14.1.jar:4.14.1]
at org.apache.distributedlog.BookKeeperClient.close(BookKeeperClient.java:273) ~[org.apache.distributedlog-distributedlog-core-4.14.1.jar:4.14.1]
at org.apache.distributedlog.impl.BKNamespaceDriver.doClose(BKNamespaceDriver.java:404) ~[org.apache.distributedlog-distributedlog-core-4.14.1.jar:4.14.1]
at org.apache.distributedlog.impl.BKNamespaceDriver.close(BKNamespaceDriver.java:385) ~[org.apache.distributedlog-distributedlog-core-4.14.1.jar:4.14.1]
at com.google.common.io.Closeables.close(Closeables.java:78) ~[com.google.guava-guava-30.1-jre.jar:?]
at org.apache.distributedlog.util.Utils.close(Utils.java:544) ~[org.apache.distributedlog-distributedlog-core-4.14.1.jar:4.14.1]
at org.apache.distributedlog.BKDistributedLogNamespace.close(BKDistributedLogNamespace.java:340) ~[org.apache.distributedlog-distributedlog-core-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.stream.server.service.DLNamespaceProviderService.doClose(DLNamespaceProviderService.java:135) ~[org.apache.bookkeeper-stream-storage-server-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.common.component.AbstractLifecycleComponent.close(AbstractLifecycleComponent.java:123) ~[org.apache.bookkeeper-bookkeeper-common-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.common.component.LifecycleComponentStack.lambda$close$6(LifecycleComponentStack.java:154) ~[org.apache.bookkeeper-bookkeeper-common-4.14.1.jar:4.14.1]
at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:406) [com.google.guava-guava-30.1-jre.jar:?]
at org.apache.bookkeeper.common.component.LifecycleComponentStack.close(LifecycleComponentStack.java:154) [org.apache.bookkeeper-bookkeeper-common-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent.doClose(StreamStorageLifecycleComponent.java:60) [org.apache.bookkeeper-stream-storage-server-4.14.1.jar:4.14.1]
at org.apache.bookkeeper.common.component.AbstractLifecycleComponent.close(AbstractLifecycleComponent.java:123) [org.apache.bookkeeper-bookkeeper-common-4.14.1.jar:4.14.1]
at org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble.stop(LocalBookkeeperEnsemble.java:492) [org.apache.pulsar-pulsar-zookeeper-utils-2.8.0.jar:2.8.0]
at org.apache.pulsar.PulsarStandaloneStarter$1.run(PulsarStandaloneStarter.java:102) [org.apache.pulsar-pulsar-broker-2.8.0.jar:2.8.0]

mqtt cancels the subscription and disconnects directly

pulsar-broker-rabbitmq1.log error

14:32:33.511 [mqtt-redirect-io-44-1] INFO io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyProtocolMethodProcessor - processUnSubscribe...
14:32:33.526 [mqtt-redirect-io-44-1] INFO io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyExchanger - channel read: MqttMessage[fixedHeader=, variableHeader=, payload=]
14:32:33.526 [mqtt-redirect-io-44-1] ERROR io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyExchanger - Failed to decode mqttMessage.
io.netty.handler.codec.DecoderException: Illegal BIT 2 or 1 in fixed header of UNSUBACK message, must be 0, found 1
at io.netty.handler.codec.mqtt.MqttDecoder.decodeFixedHeader(MqttDecoder.java:214) ~[netty-codec-mqtt-4.1.67.Final.jar:4.1.67.Final]
at io.netty.handler.codec.mqtt.MqttDecoder.decode(MqttDecoder.java:88) ~[netty-codec-mqtt-4.1.67.Final.jar:4.1.67.Final]
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507) [io.netty-netty-codec-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) [io.netty-netty-codec-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) [io.netty-netty-codec-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) [io.netty-netty-handler-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [io.netty-netty-transport-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795) [io.netty-netty-transport-native-epoll-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480) [io.netty-netty-transport-native-epoll-4.1.66.Final.jar:4.1.66.Final]
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378) [io.netty-netty-transport-native-epoll-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) [io.netty-netty-common-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [io.netty-netty-common-4.1.66.Final.jar:4.1.66.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [io.netty-netty-common

Pulsar batch handling

Currently, if the messages are sent by Pulsar with batch mode, the mqtt broker can dispatch the batch messages to the mqtt client, but the acknowledgment does not handle well.

mqtt does not support sending or subscribing permissions to the specified topic

mqtt starts the token authentication method and uses the tool to create the token:
bin/pulsar tokens create --secret-key file:///opt/my-secret.key
--subject test-user1
The token is as follows:
eyJhbI1NiJ9.eyJzdWIiOiJ0VzZXIyIn0.c_eE4mh4tOw_K8tKG_lI8FATkgqVTpUsBBrDOTlWg48

Use token to connect to mqtt, but it can subscribe to topic and send topic data at will, how to restrict the sending and subscribing authority to only specified topic

ClassNotFound from locally built Pulsar standalone

Hi, I've added the .nar file to ./protocol in a local build of Pulsar and am getting a class not found exception when running ./bin/pulsar standalone. Your help is greatly appreciated!

13:01:55.325 [pulsar-io-29-1] INFO io.streamnative.pulsar.handlers.mqtt.support.ProtocolMethodProcessorImpl - [Subscribe] [[id: 0xe2f7eae5, L:/127.0.0.1:1883 - R:/127.0.0.1:58408]] msg: MqttSubscribeMessage[fixedHeader=MqttFixedHeader[messageType=SUBSCRIBE, isDup=false, qosLevel=AT_LEAST_ONCE, isRetain=false, remainingLength=41], variableHeader=MqttMessageIdVariableHeader[messageId=1], payload=MqttSubscribePayload[MqttTopicSubscription[topicFilter=persistent://public/default/my-topic, qualityOfService=AT_LEAST_ONCE]]]
13:01:55.325 [pulsar-io-29-1] ERROR io.streamnative.pulsar.handlers.mqtt.support.ProtocolMethodProcessorImpl - [persistent://public/default/my-topic] [7f000001e3e460bf5c32] Failed to create subscription on Pulsar topic.
java.util.concurrent.CompletionException: java.lang.NoClassDefFoundError: org/apache/pulsar/common/api/proto/PulsarApi$CommandSubscribe$InitialPosition
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[?:?]
at java.util.concurrent.CompletableFuture.uniAcceptNow(CompletableFuture.java:757) [?:?]
at java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:731) [?:?]
at java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:2108) [?:?]
at io.streamnative.pulsar.handlers.mqtt.utils.PulsarTopicUtils.getOrCreateSubscription(PulsarTopicUtils.java:44) ~[pulsar-protocol-handler-mqtt-2.8.0-SNAPSHOT.nar-unpacked/:?]
at io.streamnative.pulsar.handlers.mqtt.support.ProtocolMethodProcessorImpl.processSubscribe(ProtocolMethodProcessorImpl.java:268) [pulsar-protocol-handler-mqtt-2.8.0-SNAPSHOT.nar-unpacked/:?]
at io.streamnative.pulsar.handlers.mqtt.MQTTInboundHandler.channelRead(MQTTInboundHandler.java:60) [pulsar-protocol-handler-mqtt-2.8.0-SNAPSHOT.nar-unpacked/:?]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.63.Final.jar:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.63.Final.jar:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.63.Final.jar:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) [netty-codec-4.1.63.Final.jar:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) [netty-codec-4.1.63.Final.jar:4.1.63.Final]

pulsar to postgresql id not null???

一: Caused by: org.postgresql.util.PSQLException: 错误: null value in column "id" of relation "pulsar_postgres_jdbc_sink" violates not-null constraint
详细:失败, 行包含(null, null).
... 14 more
10:44:55.576 [pool-6-thread-1] ERROR org.apache.pulsar.io.jdbc.JdbcAbstractSink - Update count 1 not match total number of records 24
10:45:11.792 [pulsar-timer-6-1] INFO org.apache.pulsar.client.impl.ConsumerStatsRecorderImpl - [pulsar-postgres-jdbc-sink-topic] [public/default/pulsar-postgres-jdbc-sink] [e4f13] Prefetched messages: 0 --- Consume throughput received: 3.22 msgs/s --- 0.00 Mbit/s --- Ack sent rate: 0.00 ack/s --- Failed messages: 0 --- batch messages: 0 ---Failed acks: 0
10:45:35.575 [pool-6-thread-1] ERROR org.apache.pulsar.io.jdbc.JdbcAbstractSink - Got exception
org.postgresql.util.PSQLException: 错误: 当前事务被终止, 事务块结束之前的查询被忽略
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2533) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2268) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:313) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:159) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:148) ~[postgresql-42.2.12.jar:42.2.12]
at org.apache.pulsar.io.jdbc.JdbcAbstractSink.flush(JdbcAbstractSink.java:203) ~[pulsar-io-jdbc-core-2.8.1.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: org.postgresql.util.PSQLException: 错误: null value in column "id" of relation "pulsar_postgres_jdbc_sink" violates not-null constraint
详细:失败, 行包含(null, null).
... 14 more
10:45:35.576 [pool-6-thread-1] ERROR org.apache.pulsar.io.jdbc.JdbcAbstractSink - Update count 1 not match total number of records 154
10:45:55.576 [pool-6-thread-1] ERROR org.apache.pulsar.io.jdbc.JdbcAbstractSink - Got exception
org.postgresql.util.PSQLException: 错误: 当前事务被终止, 事务块结束之前的查询被忽略
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2533) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2268) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:313) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:159) ~[postgresql-42.2.12.jar:42.2.12]
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:148) ~[postgresql-42.2.12.jar:42.2.12]
at org.apache.pulsar.io.jdbc.JdbcAbstractSink.flush(JdbcAbstractSink.java:203) ~[pulsar-io-jdbc-core-2.8.1.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: org.postgresql.util.PSQLException: 错误: null value in column "id" of relation "pulsar_postgres_jdbc_sink" violates not-null constraint
详细:失败, 行包含(null, null).
... 14 more
10:45:55.576 [pool-6-thread-1] ERROR org.apache.pulsar.io.jdbc.JdbcAbstractSink - Update count 1 not match total number of records 15
10:46:11.794 [pulsar-timer-6-1] INFO org.apache.pulsar.client.impl.ConsumerStatsRecorderImpl - [pulsar-postgres-jdbc-sink-topic] [public/default/pulsar-postgres-jdbc-sink] [e4f13] Prefetched messages: 0 --- Consume throughput received: 2.82 msgs/s --- 0.00 Mbit/s --- Ack sent rate: 0.00 ack/s --- Failed messages: 0 --- batch messages: 0 ---Failed acks: 0
二: {"id":1,"name":"adsasda"},The tested client publications and subscriptions are also normal.

MQTT-SN support

Hi,
Thanks for your work.

Does mop support MQTT-SN protocol (MQTT For Sensor Networks) over UDP ?

In addition, it would be nice to specify in the README which MQTT version is supported: 3.1.1 ? 5.0 ?

Regards

pulsar-admin sinks localrun options

The program example in the sins pulse to PostgreSQL document is based on the cluster environment. The database table cannot be successfully inserted in the stand-alone mode. Can you create a new configuration example in the stand-alone mode? In stand-alone mode, pulsar 2.8.1.0, mop 2.8.1.0, pulsar-io-jdbc-postgres-2.8.0.nar
I want to run Pulsar to PostgresQL Sink and Pulsar to postgresQL Sink on a single machine without any exception. I also want to subscribe to the topic messages sent to Pulsar by the test client using MOP 2.8.1.0 and Pulsar 2.8.1.0. Pulsar-io-jdbc-postgres-2.8.0. nar, but messages cannot be written to the postgresQL database table pulsar-postgres-jdbc-sink. Later, I found that there was a Pulsar-Admin sinks localrun options. In the document, there was an example of collocation in the cluster environment, but collocation in the single-machine environment only explained without program examples. Could someone give me an example of running the PostgresQL Sink configuration file in single-machine mode?

mqtt does not support subscription and sending permissions for the specified topic

for example:
1 Role: aaa, authorized to tenant: aaa, namespace: all topics under aaa have all permissions.
2 Role: bbb, authorized to tenant: bbb, namespace: all topics under bbb have all permissions.
Test: Use pulsar protocol connection, role: aaa subscribe and send topic: persistent://bbb/bbb/mytopic is not authorized, but I use mqtt protocol connection, role: aaa, you can subscribe and send data to topic: persistent: //bbb/bbb/mytopic

mqtt last will

Use mqtt protocol to connect, set will, after disconnecting, will not receive will

Connection descriptor store is not shared across brokers

The MQTT spec calls for terminating existing clients with the same ClientID on CONNECT:

If the ClientId represents a Client already connected to the Server then the Server MUST disconnect the existing Client.

This is currently implemented using the ConnectionDescriptorStore however it's not shared between brokers so connection from a client to another broker within the cluster will violate this part of the spec.

We either need to decide to implement the spec correctly or document non-compliance so users can be aware.

websocket connection

Hi, does MoP accept ws connections? For example with emq broker I can use javascript mqtt libraries and connect using ws since tcp is not possible on browsers.

mqtt consumer doesn't receive mesg from pulsar-mop

Problem Statement

  • pulsar-standalone 2.5.2
  • installed mop and configured as instructed
  • currently setup in a standalone mode in both docker container and cluster
  • used different clients to publish/subscribe to topic

case 1:
used mqtt cli directly to test producer/consumer:

mqtt test -h localhost -p 1883
MQTT 3: OK
	- Maximum topic length: 0 bytes
	- QoS 0: Received 0/10 publishes in 10033.91ms
	- QoS 1: Received 0/10 publishes in 10156.59ms
	- QoS 2: 

case 2:
used patho python clients to test producer/consumer, also cannot receive mesg as consumer

case 3:
mqtt producer sends to topic (on 1883) and regular pulsar consumer (on 6650) received the message. However, messages sent out to the topic that mqtt consumer is supposed to receive didn't happen. That means producer seems to work fine but consumer was not able to receive messages.

In both cases, there was no errors in pulsar broker logs. The connection/publish/subscribe seem all succeeded but no message received on consumer end. We tried both qos = 0 and qos = 1, same effect.

What could be the issue here?

Support adding PSK identities dynamically

Motivation

Currently, PSK identities are configured when MoP startup. If adding new identities, we have to restart the server, but new clients with new identity is a common scenario.

MoP and KoP cannot be used together

Add
brokerentrymetadatainterceptors = org. Apache. Pulsar. Common. Intercept. Appendindexmetadatainterceptor
to the configuration file
Cannot subscribe to published messages through MQTT

EMQ can not bridge with MOP

when I use EMQ broker bridge with mop, error occurs
{"mqttFixedHeader":{"messageType":"CONNECT","isDup":false,"qosLevel":"AT_MOST_ONCE","isRetain":false,"remainingLength":37},"decoderResult":{"cause":{"detailMessage":"MQTT and -123 are not match","stackTrace":[],"suppressedExceptions":[]}}}
the connect payload is null

TLS PSK Support

Creating a venue in SmartZone results in a new configuration being added to SmartZone’s own mosquitto broker. The venue configuration at Figure 3 will result in the following lines:

address 201.52.221.208:8883
topic 3.0/LOC/lbstest/LS/# in
topic 3.0/LOC/lbstest/+/MGR out
bridge_tls_version tlsv1
bridge_identity lbstest
bridge_psk 7275636B757331323321

The first line is the IP address of the external location server. The topic lines allow the SZ mosquitto broker to receive results for multiple topics, and to send results ending with MGR to multiple location servers. The SZ mosquitto broker is running TLS version 1.0.

bridge_identity is the user name the SZ mosquitto broker will use to connect to the LS broker, and bridge_pskis the pre-shared key to authenticate the user. It is the hex conversion of the password that was entered when creating the venue. You can use the site https://www.rapidtables.com/convert/number/ascii-to-hex.html for the conversion. In the example above we used ruckus123! as the password/pre-shared key.

cannot receive messages using mqtt subscription.

I've found the similar issue #20 . Generally the same problem.

I'm using pulsar 2.8.0 (by docker), and mop 2.9.0-SNAPSHOT.
I've sent a message to topic by mqtt protocol, and I can receive the message using pulsar consumer, but failed on mqtt consumer.

I've used nodejs

const mqtt = require('mqtt')

const host = '10.191.5.110'
const port = '1883'
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`

const connectUrl = `mqtt://${host}:${port}`
const client = mqtt.connect(connectUrl, {
  clientId,
  clean: true,
  connectTimeout: 4000,
  reconnectPeriod: 1000,
})

const topic = 'nodejs-mqtt'
client.on('connect', () => {
  console.log('Connected')
  client.subscribe([topic], () => {
    console.log(`Subscribe to topic '${topic}'`)
  })
  client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => {
    if (error) {
      console.error(error)
    }
  })
})
client.on('message', (top, payload) => {
  console.log('Received Message:', top, payload.toString())
})

and also java (the same code in READ.MD

    @Test
    public void test03() throws Exception {
        MQTT mqtt = new MQTT();
        mqtt.setHost("10.191.5.110", 1883);
        mqtt.setClientId("java-test");
        BlockingConnection connection = mqtt.blockingConnection();
        connection.connect();
        Topic[] topics = { new Topic("persistent://public/default/nodejs-mqtt", QoS.AT_LEAST_ONCE) };
        connection.subscribe(topics);

        // publish message
        connection.publish("persistent://public/default/nodejs-mqtt", "Hello MOP!".getBytes(), QoS.AT_LEAST_ONCE, false);

        // receive message
        try {
            org.fusesource.mqtt.client.Message received = connection.receive();
            System.out.println("Message received, " + new String(received.getPayload()));
        } catch(Exception e) {
            e.printStackTrace();
        }
        
    }

but no messages returned.

I've also tried mop v2.8.0 but nothing changed.

As I'm using pulsar-manager, I can see from the management page that the subscription type in MQTT consumer is 'NONE', as it was 'EXCLUSIVE' when I was using pulsar consumer. I don't know if it matters.
image

Pls tell me what I've done wrong. Thx.

[DISCUSSION] export metrics of mqtt

I want to some metrics of mqtt, like online_client_count, disconnected_client_count in 5 min, and seems like we can't get this metrics from pulsar api of {PULSAR_IP}:{PORT}/metrics.

Any idea for this? Alone start http for metrics? I even hope that the metrics of pulsar have only one entrance -> {PULSAR_IP}:{PORT}/metrics

Cannot connect to proxy port 5682 using mqtt-client

Using mqtt-client can not connect to the 5682 proxy port, the connection has not been returned,appears after opening authentication, the code is as follows:

MQTT mqtt = new MQTT();
mqtt.setHost("127.0.0.1", 5682);
mqtt.setUserName("aaaa");
mqtt.setPassword("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhYWEifQ.L9h2m6Mpr1NM7JD8i2YuzKfusuht6fI6BYM39pgZZKs");
BlockingConnection connection = mqtt.blockingConnection();
connection.connect();
Topic[] topics = { new Topic("persistent://public/default/my-topic", QoS.AT_LEAST_ONCE) };
connection.subscribe(topics);

// publish message
connection.publish("persistent://public/default/my-topic", "Hello MOP!".getBytes(), QoS.AT_LEAST_ONCE, false);

// receive message
Message received = connection.receive();

Consume Pulsar batch message from MQTT client.

Currently, we only handle non-batch Pulsar messages in the mop. For batch messages, it's better to leverage the batch index acknowledgment feature. Otherwise, we need to maintain batch acker in the mop.

Have problem in installing

I supposed to run pulsar in docker in standalone mode, so I modified the standalone.conf file with adding the following properties:

messagingProtocols=mqtt
protocolHandlerDirectory=/root/mop/mqtt-impl/target
mqttListeners=mqtt://127.0.0.1:1883
advertisedAddress=127.0.0.1

However, when running the pulsar, it showed the following message:

02:37:07.832 [main] INFO  org.apache.pulsar.broker.protocol.ProtocolHandlerUtils - Searching for protocol handlers in /root/mop/mqtt-impl/target
02:37:07.832 [main] WARN  org.apache.pulsar.broker.protocol.ProtocolHandlerUtils - Protocol handler directory not found
02:37:07.834 [main] ERROR org.apache.pulsar.broker.PulsarService - Failed to start Pulsar service: No protocol handler is found for protocol `mqtt`. Available protocols are : {}

I had built the MoP project succesfully and the NAR file had occurred in the /root/mop/mqtt-impl/target directory correctly. I want to know if my process of installing had made some mistakes. Thank you very much.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.