@@ -44,26 +44,26 @@ public class IoTCoreClient implements MessageClient {
4444 private Set <String > subscribedIotCoreTopics = ConcurrentHashMap .newKeySet ();
4545 @ Getter (AccessLevel .PROTECTED )
4646 private Set <String > toSubscribeIotCoreTopics = new HashSet <>();
47-
48- private Consumer <Message > messageHandler ;
47+ private volatile Consumer <Message > messageHandler ;
4948 private Future <?> subscribeFuture ;
5049 private final Object subscribeLock = new Object ();
51-
5250 private final MqttClient iotMqttClient ;
5351 private final ExecutorService executorService ;
5452
5553 private final Consumer <MqttMessage > iotCoreCallback = (message ) -> {
5654 String topic = message .getTopic ();
5755 LOGGER .atTrace ().kv (TOPIC , topic ).log ("Received IoT Core message" );
5856
59- if (messageHandler == null ) {
57+ Consumer <Message > handler = messageHandler ;
58+ if (handler == null ) {
6059 LOGGER .atWarn ().kv (TOPIC , topic ).log ("IoT Core message received but message handler not set" );
6160 } else {
6261 Message msg = new Message (topic , message .getPayload ());
63- messageHandler .accept (msg );
62+ handler .accept (msg );
6463 }
6564 };
6665
66+ @ Getter (AccessLevel .PACKAGE ) // for unit testing
6767 private final MqttClientConnectionEvents connectionCallbacks = new MqttClientConnectionEvents () {
6868 @ Override
6969 public void onConnectionInterrupted (int errorCode ) {
@@ -93,7 +93,8 @@ public void onConnectionResumed(boolean sessionPresent) {
9393 public IoTCoreClient (MqttClient iotMqttClient , ExecutorService executorService ) {
9494 this .iotMqttClient = iotMqttClient ;
9595 this .executorService = executorService ;
96- iotMqttClient .addToCallbackEvents (connectionCallbacks );
96+ // onConnect handler required to handle case when bridge starts offline
97+ iotMqttClient .addToCallbackEvents (connectionCallbacks ::onConnectionResumed , connectionCallbacks );
9798 }
9899
99100 /**
@@ -184,15 +185,16 @@ public boolean supportsTopicFilters() {
184185
185186 @ SuppressWarnings ({"PMD.AvoidCatchingGenericException" , "PMD.PreserveStackTrace" , "PMD.ExceptionAsFlowControl" })
186187 private void subscribeToTopicsWithRetry (Set <String > topics ) {
187- // retry only if client is connected; skip if offline.
188- // topics left here should be subscribed when the client is back online (onConnectionResumed event)
189- topics .forEach (s -> {
188+ for (String topic : topics ) {
190189 try {
191190 RetryUtils .runWithRetry (subscribeRetryConfig , () -> {
192191 try {
192+ // retry only if client is connected; skip if offline.
193+ // topics left here should be subscribed when the client
194+ // is back online (onConnectionResumed event)
193195 if (iotMqttClient .connected ()) {
194- subscribeToIotCore (s );
195- subscribedIotCoreTopics .add (s );
196+ subscribeToIotCore (topic );
197+ subscribedIotCoreTopics .add (topic );
196198 }
197199 // useless return
198200 return null ;
@@ -207,10 +209,11 @@ private void subscribeToTopicsWithRetry(Set<String> topics) {
207209 }, "subscribe-iotcore-topic" , LOGGER );
208210 } catch (InterruptedException e ) {
209211 Thread .currentThread ().interrupt ();
212+ return ;
210213 } catch (Exception e ) {
211- LOGGER .atError ().kv (TOPIC , s ).setCause (e ).log ("Failed to subscribe to IoTCore topic" );
214+ LOGGER .atError ().kv (TOPIC , topic ).setCause (e ).log ("Failed to subscribe to IoTCore topic" );
212215 }
213- });
216+ }
214217 }
215218
216219 private void subscribeToIotCore (String topic ) throws InterruptedException , ExecutionException , TimeoutException {
0 commit comments