11package com .ss .mqtt .broker .network .packet .in .handler ;
22
3- import static reactor .core .publisher .Mono .fromCallable ;
4- import static reactor .core .publisher .Mono .fromRunnable ;
3+ import static com .ss .mqtt .broker .model .ConnectAckReasonCode .BAD_USER_NAME_OR_PASSWORD ;
4+ import static com .ss .mqtt .broker .model .ConnectAckReasonCode .CLIENT_IDENTIFIER_NOT_VALID ;
5+ import static com .ss .mqtt .broker .util .ReactorUtils .ifTrue ;
56import com .ss .mqtt .broker .exception .ConnectionRejectException ;
67import com .ss .mqtt .broker .exception .MalformedPacketMqttException ;
78import com .ss .mqtt .broker .model .ConnectAckReasonCode ;
9+ import com .ss .mqtt .broker .model .MqttSession ;
810import com .ss .mqtt .broker .network .client .UnsafeMqttClient ;
911import com .ss .mqtt .broker .network .packet .in .ConnectInPacket ;
1012import com .ss .mqtt .broker .service .AuthenticationService ;
1113import com .ss .mqtt .broker .service .ClientIdRegistry ;
14+ import com .ss .mqtt .broker .service .MqttSessionService ;
1215import com .ss .rlib .common .util .StringUtils ;
1316import lombok .RequiredArgsConstructor ;
1417import org .jetbrains .annotations .NotNull ;
@@ -19,6 +22,7 @@ public class ConnectInPacketHandler extends AbstractPacketHandler<UnsafeMqttClie
1922
2023 private final ClientIdRegistry clientIdRegistry ;
2124 private final AuthenticationService authenticationService ;
25+ private final MqttSessionService mqttSessionService ;
2226
2327 @ Override
2428 protected void handleImpl (@ NotNull UnsafeMqttClient client , @ NotNull ConnectInPacket packet ) {
@@ -31,61 +35,60 @@ protected void handleImpl(@NotNull UnsafeMqttClient client, @NotNull ConnectInPa
3135 }
3236
3337 authenticationService .auth (packet .getUsername (), packet .getPassword ())
34- .filter (Boolean ::booleanValue )
35- .flatMap (authenticated -> registerClient (client , packet ))
36- .switchIfEmpty (fromRunnable (() -> client .reject (ConnectAckReasonCode .BAD_USER_NAME_OR_PASSWORD )))
38+ .flatMap (ifTrue (client , packet , this ::registerClient , BAD_USER_NAME_OR_PASSWORD , client ::reject ))
39+ .flatMap (ifTrue (client , packet , this ::restoreSession , CLIENT_IDENTIFIER_NOT_VALID , client ::reject ))
3740 .subscribe ();
3841 }
3942
4043 private @ NotNull Mono <Boolean > registerClient (
4144 @ NotNull UnsafeMqttClient client ,
4245 @ NotNull ConnectInPacket packet
4346 ) {
47+
4448 var requestedClientId = packet .getClientId ();
45- if (StringUtils .isEmpty (requestedClientId )) {
46- return processWithoutClientId (client , packet , requestedClientId );
49+
50+ if (StringUtils .isNotEmpty (requestedClientId )) {
51+ return clientIdRegistry .register (requestedClientId )
52+ .map (ifTrue (requestedClientId , client ::setClientId ));
4753 } else {
48- return processWithClientId (client , packet , requestedClientId );
54+ return clientIdRegistry .generate ()
55+ .flatMap (newClientId -> clientIdRegistry .register (newClientId )
56+ .map (ifTrue (newClientId , client ::setClientId )));
4957 }
5058 }
5159
52- private @ NotNull Mono <Boolean > processWithClientId (
60+ private @ NotNull Mono <Boolean > restoreSession (
5361 @ NotNull UnsafeMqttClient client ,
54- @ NotNull ConnectInPacket packet ,
55- @ NotNull String requestedClientId
62+ @ NotNull ConnectInPacket packet
5663 ) {
57- return clientIdRegistry .register (requestedClientId )
58- .filter (Boolean ::booleanValue )
59- .flatMap (registered -> fromCallable (() -> {
60- client .setClientId (requestedClientId );
61- onConnected (client , packet , requestedClientId );
62- return true ;
63- }))
64- .switchIfEmpty (fromRunnable (() -> client .reject (ConnectAckReasonCode .CLIENT_IDENTIFIER_NOT_VALID )));
65- }
6664
67- private @ NotNull Mono <Boolean > processWithoutClientId (
68- @ NotNull UnsafeMqttClient client ,
69- @ NotNull ConnectInPacket packet ,
70- @ NotNull String requestedClientId
71- ) {
72- return clientIdRegistry .generate ()
73- .doOnNext (client ::setClientId )
74- .flatMap (clientIdRegistry ::register )
75- .filter (Boolean ::booleanValue )
76- .flatMap (registered -> fromCallable (() -> {
77- onConnected (client , packet , requestedClientId );
78- return true ;
79- }))
80- .switchIfEmpty (fromRunnable (() -> client .reject (ConnectAckReasonCode .CLIENT_IDENTIFIER_NOT_VALID )));
65+ if (packet .isCleanStart ()) {
66+ return mqttSessionService .create (client .getClientId ())
67+ .flatMap (session -> onConnected (client , packet , session , false ));
68+ } else {
69+ return mqttSessionService .restore (client .getClientId ())
70+ .flatMap (session -> onConnected (client , packet , session , true ))
71+ .switchIfEmpty (Mono .defer (() -> mqttSessionService .create (client .getClientId ())
72+ .flatMap (session -> onConnected (client , packet , session ,false ))));
73+ }
8174 }
8275
83- private void onConnected (
76+ private Mono < Boolean > onConnected (
8477 @ NotNull UnsafeMqttClient client ,
8578 @ NotNull ConnectInPacket packet ,
86- @ NotNull String requestedClientId
79+ @ NotNull MqttSession session ,
80+ boolean sessionRestored
8781 ) {
8882
83+ var connection = client .getConnection ();
84+
85+ // if it was closed in parallel
86+ if (connection .isClosed ()) {
87+ // store the session again
88+ return mqttSessionService .store (client .getClientId (), session );
89+ }
90+
91+ client .setSession (session );
8992 client .configure (
9093 packet .getSessionExpiryInterval (),
9194 packet .getReceiveMax (),
@@ -97,13 +100,14 @@ private void onConnected(
97100 client .send (client .getPacketOutFactory ().newConnectAck (
98101 client ,
99102 ConnectAckReasonCode .SUCCESS ,
100- false ,
101- requestedClientId ,
103+ sessionRestored ,
104+ packet . getClientId () ,
102105 packet .getSessionExpiryInterval (),
103106 packet .getKeepAlive ()
104107 ));
105- }
106108
109+ return Mono .just (Boolean .TRUE );
110+ }
107111
108112 private boolean checkPacketException (@ NotNull UnsafeMqttClient client , @ NotNull ConnectInPacket packet ) {
109113
0 commit comments