Connect to AWS IoT MessageBroker with SigV4 presignedURL using Eclipse Paho MQTT client

1k Views Asked by At

I am trying to create a Java Mqtt Client using Eclipse Paho which can connect to an AWS IoT MessageBroker using a SigV4 presigned URL generated using AwsIotWebSocketUrlSigner's getSignedUrl method. This connection will be using MQTT over Websockets and has a URL syntax starting with "wss://".

The connection code looks like this.

IMqttAsyncClient client = new MqttAsyncClient(*presignedUrl*,MqttAsyncClient.generateClientId(), new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
IMqttToken token = client.connect(options);
token.waitForCompletion();
client.setCallback( *callBackObject* );
client.subscribe(topic, AWSIotQos.QOS1.getValue());

I keep getting below Exception. It's failing at the connect() above.

MqttException (0) - java.lang.NullPointerException
    at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:664)
    at java.lang.Thread.run(Thread.java:749)
Caused by: java.lang.NullPointerException
    at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.receiveHandshakeResponse(WebSocketHandshake.java:133)
    at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.execute(WebSocketHandshake.java:74)
    at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketSecureNetworkModule.start(WebSocketSecureNetworkModule.java:77)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650)

In Eclipse Paho code Exception happens here while validating the WSS Handshake.

String connectionHeader = (String) headerMap.get(HTTP_HEADER_CONNECTION);
if (connectionHeader == null || connectionHeader.equalsIgnoreCase(HTTP_HEADER_CONNECTION_VALUE)) {
    throw new IOException("WebSocket Response header: Incorrect connection header");
}

I am able to connect using a Javascript client and presignedUrl.

Any help/sample code will is much appreciated.

1

There are 1 best solutions below

0
On BEST ANSWER

Found this while looking at how AWS Sdk does it as it uses Eclipse Paho underneath. https://github.com/aws/aws-iot-device-sdk-java/blob/647449e654096172ebfcc31d79a8c582f952219d/aws-iot-device-sdk-java/src/main/java/com/amazonaws/services/iot/client/core/AwsIotWebsocketConnection.java#L46

It was adding port no 443 to the clientEndpoint. Apparently the presignedUrl I had was not having it. So I changed the signingUrl to also have port no and it worked.