List of usage examples for io.netty.handler.codec.mqtt MqttIdentifierRejectedException MqttIdentifierRejectedException
public MqttIdentifierRejectedException()
From source file:com.caricah.iotracah.core.handlers.ConnectionHandler.java
License:Apache License
/** * * 3.1.4 Response/*from w w w .jav a2 s. c o m*/ * <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); } }