List of usage examples for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_ACCEPTED
MqttConnectReturnCode CONNECTION_ACCEPTED
To view the source code for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_ACCEPTED.
Click Source Link
From source file:com.caricah.iotracah.core.handlers.ConnectionHandler.java
License:Apache License
/** * * 3.1.4 Response/* w w w.j ava 2 s .c om*/ * <p> * Note that a Server MAY support multiple protocols (including earlier versions of this protocol) * on the same TCP port or other network endpoint. If the Server determines that the protocol is MQTT 3.1.1 * then it validates the connection attempt as follows. * <p> * 1. If the Server does not receive a CONNECT Packet within a reasonable amount of time after * the Network Connection is established, the Server SHOULD close the connection. * <p> * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * <p> * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * <p> * If validation is successful the Server performs the following steps. * <p> * 1. If the ClientId represents a Client already connected to the Server then * the Server MUST disconnect the existing Client [MQTT-3.1.4-2]. * 2. The Server MUST perform the processing of CleanSession that is described * in section 3.1.2.4 [MQTT-3.1.4-3]. * 3. The Server MUST acknowledge the CONNECT Packet with a CONNACK Packet * containing a zero return code [MQTT-3.1.4-4]. * 4. Start message delivery and keep alive monitoring. * <p> * Clients are allowed to send further Control Packets immediately after sending a CONNECT Packet; * Clients need not wait for a CONNACK Packet to arrive from the Server. If the Server rejects the CONNECT, * it MUST NOT process any data sent by the Client after the CONNECT Packet [MQTT-3.1.4-5]. * <p> * Non normative comment * Clients typically wait for a CONNACK Packet, * However, if the Client exploits its freedom to send Control Packets before it receives a CONNACK, * it might simplify the Client implementation as it does not have to police the connected state. * The Client accepts that any data that it sends before it receives a CONNACK packet from the * Server will not be processed if the Server rejects the connection. * * @return * @throws RetriableException * @throws UnRetriableException */ @Override public void handle(ConnectMessage connectMessage) throws RetriableException, UnRetriableException { log.debug(" handle : client initiating a new connection."); /** * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * * 3.1[ The Server MUST process a second CONNECT Packet sent from a Client as a protocol * violation and disconnect the Client [MQTT-3.1.0-2]. See section 4.8 for information about handling errors.] * * */ try { if (!MqttVersion.MQTT_3_1_1.protocolName().equals(connectMessage.getProtocolName()) && !MqttVersion.MQTT_3_1.protocolName().equals(connectMessage.getProtocolName())) { /** * If the protocol name is incorrect the Server MAY disconnect the Client, * or it MAY continue processing the CONNECT packet in accordance with some other specification. * In the latter case, the Server MUST NOT continue to process the CONNECT packet in line with * this specification [MQTT-3.1.2-1]. * */ throw new UnknownProtocalException(); } if (MqttVersion.MQTT_3_1_1.protocolLevel() != connectMessage.getProtocalLevel() && MqttVersion.MQTT_3_1.protocolLevel() != connectMessage.getProtocalLevel()) { /** * The 8 bit unsigned value that represents the revision level of the protocol used by the Client. * The value of the Protocol Level field for the version 3.1.1 of the protocol is 4 (0x04). * The Server MUST respond to the CONNECT Packet with a CONNACK return code 0x01 (unacceptable protocol level) * and then disconnect the Client if the Protocol Level is not supported by the Server [MQTT-3.1.2-2]. */ throw new MqttUnacceptableProtocolVersionException(); } else { log.debug(" handle: the required protocal was selected."); } //TODO: The Server MUST validate that the reserved flag in the CONNECT Control Packet is set to zero and disconnect the Client if it is not zero [MQTT-3.1.2-3]. //We now proceed to openning a session on our core service interface. boolean cleanSession = connectMessage.isCleanSession(); /** * The Server MUST allow ClientIds which are between 1 and 23 UTF-8 encoded bytes in length, * and that contain only the characters * "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [MQTT-3.1.3-5]. * * The Server MAY allow ClientIds that contain more than 23 encoded bytes. * The Server MAY allow ClientIds that contain characters not included in the list given above. * * * A Server MAY allow a Client to supply a ClientId that has a length of zero bytes, * however if it does so the Server MUST treat this as a special case and assign a unique ClientId to that Client. * It MUST then process the CONNECT packet as if the Client had provided that unique ClientId [MQTT-3.1.3-6]. * */ String clientIdentifier = connectMessage.getClientId(); /** * If the Client supplies a zero-byte ClientId, the Client MUST also set CleanSession to 1 [MQTT-3.1.3-7]. * * If the Client supplies a zero-byte ClientId with CleanSession set to 0, * the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) * and then close the Network Connection [MQTT-3.1.3-8]. */ if ((null == clientIdentifier || clientIdentifier.isEmpty())) { if (!cleanSession) { throw new MqttIdentifierRejectedException(); } } else { //Run a regular expression to check for invalid characters in our clientIdentifier. if (!pattern.matcher(clientIdentifier).matches()) { throw new MqttIdentifierRejectedException(); } } log.debug(" handle: we are ready now to obtain the core session."); Observable<IOTClient> newClientObservable = openSubject(connectMessage.getCluster(), connectMessage.getNodeId(), connectMessage.getConnectionId(), clientIdentifier, cleanSession, connectMessage.getUserName(), connectMessage.getPassword(), connectMessage.getKeepAliveTime(), connectMessage.getSourceHost(), connectMessage.getProtocol()); newClientObservable.subscribe( (iotSession) -> { log.debug(" handle: obtained a client session : {}. ", iotSession); /** * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * */ //Respond to server with a connection successfull. ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_ACCEPTED); connectAcknowledgeMessage = iotSession.copyTransmissionData(connectAcknowledgeMessage); connectAcknowledgeMessage.setAuthKey(iotSession.getAuthKey()); pushToServer(connectAcknowledgeMessage); if (connectMessage.isHasWill()) { /** * If the Will Flag is set to 1 this indicates that, if the Connect request is accepted, * a Will Message MUST be stored on the Server and associated with the Network Connection. * The Will Message MUST be published when the Network Connection is subsequently closed unless * the Will Message has been deleted by the Server on receipt of a DISCONNECT Packet [MQTT-3.1.2-8]. */ PublishMessage publishMessage = PublishMessage.from(PublishMessage.ID_TO_SHOW_IS_WILL, false, connectMessage.getWillQos(), false, connectMessage.getWillTopic(), ByteBuffer.wrap(connectMessage.getWillMessage().getBytes()), false); publishMessage.setClientId(iotSession.getSessionId()); publishMessage.setSessionId(iotSession.getSessionId()); publishMessage.setPartitionId(iotSession.getPartitionId()); // We have the appropriate id's to save the will. getDatastore().saveWill(iotSession, publishMessage); log.debug(" handle: message has will : {} ", publishMessage); } else { //We need to clear the existing will if any. getDatastore().removeWill(iotSession); } //Perform a reset for our session. getWorker().getSessionResetManager().process(iotSession); }, (e) -> { log.error(" onError : Problems ", e); ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof AuthenticationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); } else if (e instanceof AuthorizationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); pushToServer(connectAcknowledgeMessage); }, () -> { }); } catch (MqttUnacceptableProtocolVersionException | MqttIdentifierRejectedException | AuthenticationException | UnknownProtocalException e) { log.debug(" handle : Client connection issues ", e); //Respond to server with a connection unsuccessfull. ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof MqttIdentifierRejectedException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED); } else if (e instanceof MqttUnacceptableProtocolVersionException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else if (e instanceof UnknownProtocalException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); throw new ShutdownException(connectAcknowledgeMessage); } catch (Exception systemError) { ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); connectAcknowledgeMessage.copyTransmissionData(connectMessage); log.error(" handle : System experienced the error ", systemError); throw new ShutdownException(connectAcknowledgeMessage); } }
From source file:com.caricah.iotracah.core.worker.DumbWorker.java
License:Apache License
/** * Provides the Observer with a new item to observe. * <p>/*w w w.j a va 2 s. c o m*/ * The {@link com.caricah.iotracah.core.modules.Server} may call this method 0 or more times. * <p> * The {@code Observable} will not call this method again after it calls either {@link #onCompleted} or * {@link #onError}. * * @param iotMessage the item emitted by the Observable */ @Override public void onNext(IOTMessage iotMessage) { getExecutorService().submit(() -> { log.info(" onNext : received {}", iotMessage); try { IOTMessage response = null; switch (iotMessage.getMessageType()) { case ConnectMessage.MESSAGE_TYPE: ConnectMessage connectMessage = (ConnectMessage) iotMessage; response = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_ACCEPTED); break; case SubscribeMessage.MESSAGE_TYPE: SubscribeMessage subscribeMessage = (SubscribeMessage) iotMessage; List<Integer> grantedQos = new ArrayList<>(); subscribeMessage.getTopicFilterList().forEach(topic -> { String topicKey = quickCheckIdKey("", Arrays.asList(topic.getKey().split(Constant.PATH_SEPARATOR))); Set<String> channelIds = subscriptions.get(topicKey); if (Objects.isNull(channelIds)) { channelIds = new HashSet<>(); } channelIds.add(subscribeMessage.getConnectionId()); subscriptions.put(topicKey, channelIds); grantedQos.add(topic.getValue()); }); response = SubscribeAcknowledgeMessage.from(subscribeMessage.getMessageId(), grantedQos); break; case UnSubscribeMessage.MESSAGE_TYPE: UnSubscribeMessage unSubscribeMessage = (UnSubscribeMessage) iotMessage; response = UnSubscribeAcknowledgeMessage.from(unSubscribeMessage.getMessageId()); break; case Ping.MESSAGE_TYPE: response = iotMessage; break; case PublishMessage.MESSAGE_TYPE: PublishMessage publishMessage = (PublishMessage) iotMessage; Set<String> matchingTopics = getMatchingSubscriptions("", publishMessage.getTopic()); for (String match : matchingTopics) { Set<String> channelIds = subscriptions.get(match); if (Objects.nonNull(channelIds)) { channelIds.forEach(id -> { PublishMessage clonePublishMessage = publishMessage.cloneMessage(); clonePublishMessage.copyTransmissionData(iotMessage); clonePublishMessage.setConnectionId(id); pushToServer(clonePublishMessage); }); } } if (MqttQoS.AT_MOST_ONCE.value() == publishMessage.getQos()) { break; } else if (MqttQoS.AT_LEAST_ONCE.value() == publishMessage.getQos()) { response = AcknowledgeMessage.from(publishMessage.getMessageId()); break; } case PublishReceivedMessage.MESSAGE_TYPE: case ReleaseMessage.MESSAGE_TYPE: case CompleteMessage.MESSAGE_TYPE: case DisconnectMessage.MESSAGE_TYPE: case AcknowledgeMessage.MESSAGE_TYPE: default: DisconnectMessage disconnectMessage = DisconnectMessage.from(true); disconnectMessage.copyTransmissionData(iotMessage); throw new ShutdownException(disconnectMessage); } if (Objects.nonNull(response)) { response.copyTransmissionData(iotMessage); pushToServer(response); } } catch (ShutdownException e) { IOTMessage response = e.getResponse(); if (Objects.nonNull(response)) { pushToServer(response); } } catch (Exception e) { log.error(" onNext : Serious error that requires attention ", e); } }); }
From source file:com.caricah.iotracah.server.mqttserver.netty.MqttServerImpl.java
License:Apache License
@Override public void postProcess(IOTMessage ioTMessage) { switch (ioTMessage.getMessageType()) { case ConnectAcknowledgeMessage.MESSAGE_TYPE: ConnectAcknowledgeMessage conMessage = (ConnectAcknowledgeMessage) ioTMessage; /**// w w w. j a va2 s. co m * Use the connection acknowledgement message to store session id for persistance. */ Channel channel = getChannel(ioTMessage.getConnectionId()); if (Objects.nonNull(channel)) { if (MqttConnectReturnCode.CONNECTION_ACCEPTED.equals(conMessage.getReturnCode())) { channel.attr(ServerImpl.REQUEST_SESSION_ID).set(ioTMessage.getSessionId()); } else { closeClient(ioTMessage.getConnectionId()); } } break; default: super.postProcess(ioTMessage); } }
From source file:io.crate.mqtt.protocol.MqttProcessor.java
public void handleConnect(Channel channel, MqttConnectMessage msg) { String clientId = msg.payload().clientIdentifier(); LOGGER.debug("CONNECT for client <{}>", clientId); if (!(msg.variableHeader().version() == MqttVersion.MQTT_3_1.protocolLevel() || msg.variableHeader().version() == MqttVersion.MQTT_3_1_1.protocolLevel())) { sendErrorResponse(channel, MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION) .addListener(f -> LOGGER.warn("CONNECT sent UNACCEPTABLE_PROTOCOL_VERSION")); return;/*from www . j a va2 s .c om*/ } // We require the clean session header to be true if client id is not provided // See MQTT-3.1.3-8 http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html if (clientId == null || clientId.length() == 0) { if (msg.variableHeader().isCleanSession() == false) { sendErrorResponse(channel, MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED) .addListener(cf -> LOGGER.warn("CONNECT sent IDENTIFIER_REJECTED")); return; } clientId = UUID.randomUUID().toString(); LOGGER.info("Client connected with server generated identifier: {}", clientId); } NettyUtils.clientID(channel, clientId); int keepAlive = msg.variableHeader().keepAliveTimeSeconds(); if (keepAlive > 0) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Client connected with keepAlive of {} s", keepAlive); } NettyUtils.keepAlive(channel, keepAlive); if (channel.pipeline().names().contains("idleStateHandler")) { channel.pipeline().remove("idleStateHandler"); } // avoid terminating connections too early int allIdleTimeSeconds = Math.round(keepAlive * 1.5f); channel.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, allIdleTimeSeconds)); } channel.writeAndFlush(MqttMessageFactory.newConnAck(MqttConnectReturnCode.CONNECTION_ACCEPTED, true)) .addListener(cf -> LOGGER.info("CONNECT sent CONNECTION_ACCEPTED")); }
From source file:io.crate.mqtt.protocol.MqttProcessorTest.java
@Test public void testConnectWithoutClientId() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(); // clientId may be null if the session is clean MqttMessage msg = connectMessage(null, true); processor.handleConnect(ch, (MqttConnectMessage) msg); MqttConnAckMessage response = ch.readOutbound(); assertThat(response.variableHeader().connectReturnCode(), is(MqttConnectReturnCode.CONNECTION_ACCEPTED)); assertTrue(response.variableHeader().isSessionPresent()); // clientID must not be null if the session is not clean msg = connectMessage(null, false);//from ww w .ja va2 s. c o m processor.handleConnect(ch, (MqttConnectMessage) msg); response = ch.readOutbound(); assertThat(response.variableHeader().connectReturnCode(), is(MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED)); assertFalse(response.variableHeader().isSessionPresent()); }
From source file:io.crate.mqtt.protocol.MqttProcessorTest.java
@Test public void testConnectAck() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(); MqttMessage msg = connectMessage("client", true); processor.handleConnect(ch, (MqttConnectMessage) msg); MqttConnAckMessage response = ch.readOutbound(); assertThat(response.variableHeader().connectReturnCode(), is(MqttConnectReturnCode.CONNECTION_ACCEPTED)); assertTrue(response.variableHeader().isSessionPresent()); }
From source file:io.netty.example.mqtt.heartBeat.MqttHeartBeatBrokerHandler.java
License:Apache License
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { MqttMessage mqttMessage = (MqttMessage) msg; System.out.println("Received MQTT message: " + mqttMessage); switch (mqttMessage.fixedHeader().messageType()) { case CONNECT: MqttFixedHeader connackFixedHeader = new MqttFixedHeader(MqttMessageType.CONNACK, false, MqttQoS.AT_MOST_ONCE, false, 0); MqttConnAckVariableHeader mqttConnAckVariableHeader = new MqttConnAckVariableHeader( MqttConnectReturnCode.CONNECTION_ACCEPTED, false); MqttConnAckMessage connack = new MqttConnAckMessage(connackFixedHeader, mqttConnAckVariableHeader); ctx.writeAndFlush(connack);// w ww . j a v a 2 s . c o m break; case PINGREQ: MqttFixedHeader pingreqFixedHeader = new MqttFixedHeader(MqttMessageType.PINGRESP, false, MqttQoS.AT_MOST_ONCE, false, 0); MqttMessage pingResp = new MqttMessage(pingreqFixedHeader); ctx.writeAndFlush(pingResp); break; case DISCONNECT: ctx.close(); break; default: System.out.println("Unexpected message type: " + mqttMessage.fixedHeader().messageType()); ReferenceCountUtil.release(msg); ctx.close(); } }
From source file:io.vertx.mqtt.impl.MqttClientImpl.java
License:Apache License
/** * Used for calling the connect handler when the server replies to the request * * @param msg connection response message *//* w ww . ja v a2 s . c o m*/ void handleConnack(MqttConnAckMessage msg) { synchronized (this.connection) { this.isConnected = msg.code() == MqttConnectReturnCode.CONNECTION_ACCEPTED; if (this.connectHandler != null) { if (msg.code() == MqttConnectReturnCode.CONNECTION_ACCEPTED) { this.connectHandler.handle(Future.succeededFuture(msg)); } else { MqttConnectionException exception = new MqttConnectionException(msg.code()); log.error(String.format("Connection refused by the server - code: %s", msg.code())); this.connectHandler.handle(Future.failedFuture(exception)); } } } }
From source file:io.vertx.mqtt.impl.MqttEndpointImpl.java
License:Apache License
private MqttEndpointImpl connack(MqttConnectReturnCode returnCode, boolean sessionPresent) { MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.CONNACK, false, MqttQoS.AT_MOST_ONCE, false, 0);//from w ww . j av a 2 s.c om MqttConnAckVariableHeader variableHeader = new MqttConnAckVariableHeader(returnCode, sessionPresent); io.netty.handler.codec.mqtt.MqttMessage connack = MqttMessageFactory.newMessage(fixedHeader, variableHeader, null); this.write(connack); // if a server sends a CONNACK packet containing a non zero return code it MUST then close the Network Connection (MQTT 3.1.1 spec) if (returnCode != MqttConnectReturnCode.CONNECTION_ACCEPTED) { this.close(); } else { this.isConnected = true; } return this; }
From source file:io.vertx.mqtt.impl.MqttEndpointImpl.java
License:Apache License
public MqttEndpointImpl accept(boolean sessionPresent) { if (this.isConnected) { throw new IllegalStateException("Connection already accepted"); }/*from w w w . jav a 2 s . c om*/ return this.connack(MqttConnectReturnCode.CONNECTION_ACCEPTED, sessionPresent); }