use of org.springframework.integration.mqtt.event.MqttSubscribedEvent in project spring-integration by spring-projects.
the class MqttAdapterTests method testInboundOptionsApplied.
@Test
public void testInboundOptionsApplied() throws Exception {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setCleanSession(false);
factory.setConnectionTimeout(23);
factory.setKeepAliveInterval(45);
factory.setPassword("pass");
MemoryPersistence persistence = new MemoryPersistence();
factory.setPersistence(persistence);
final SocketFactory socketFactory = mock(SocketFactory.class);
factory.setSocketFactory(socketFactory);
final Properties props = new Properties();
factory.setSslProperties(props);
factory.setUserName("user");
Will will = new Will("foo", "bar".getBytes(), 2, true);
factory.setWill(will);
factory = spy(factory);
final IMqttClient client = mock(IMqttClient.class);
willAnswer(invocation -> client).given(factory).getClientInstance(anyString(), anyString());
final AtomicBoolean connectCalled = new AtomicBoolean();
final AtomicBoolean failConnection = new AtomicBoolean();
final CountDownLatch waitToFail = new CountDownLatch(1);
final CountDownLatch failInProcess = new CountDownLatch(1);
final CountDownLatch goodConnection = new CountDownLatch(2);
final MqttException reconnectException = new MqttException(MqttException.REASON_CODE_SERVER_CONNECT_ERROR);
willAnswer(invocation -> {
if (failConnection.get()) {
failInProcess.countDown();
waitToFail.await(10, TimeUnit.SECONDS);
throw reconnectException;
}
MqttConnectOptions options = invocation.getArgument(0);
assertEquals(23, options.getConnectionTimeout());
assertEquals(45, options.getKeepAliveInterval());
assertEquals("pass", new String(options.getPassword()));
assertSame(socketFactory, options.getSocketFactory());
assertSame(props, options.getSSLProperties());
assertEquals("user", options.getUserName());
assertEquals("foo", options.getWillDestination());
assertEquals("bar", new String(options.getWillMessage().getPayload()));
assertEquals(2, options.getWillMessage().getQos());
connectCalled.set(true);
goodConnection.countDown();
return null;
}).given(client).connect(any(MqttConnectOptions.class));
final AtomicReference<MqttCallback> callback = new AtomicReference<MqttCallback>();
willAnswer(invocation -> {
callback.set(invocation.getArgument(0));
return null;
}).given(client).setCallback(any(MqttCallback.class));
given(client.isConnected()).willReturn(true);
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter("foo", "bar", factory, "baz", "fix");
QueueChannel outputChannel = new QueueChannel();
adapter.setOutputChannel(outputChannel);
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.initialize();
adapter.setTaskScheduler(taskScheduler);
adapter.setBeanFactory(mock(BeanFactory.class));
ApplicationEventPublisher applicationEventPublisher = mock(ApplicationEventPublisher.class);
final BlockingQueue<MqttIntegrationEvent> events = new LinkedBlockingQueue<MqttIntegrationEvent>();
willAnswer(invocation -> {
events.add(invocation.getArgument(0));
return null;
}).given(applicationEventPublisher).publishEvent(any(MqttIntegrationEvent.class));
adapter.setApplicationEventPublisher(applicationEventPublisher);
adapter.setRecoveryInterval(500);
adapter.afterPropertiesSet();
adapter.start();
verify(client, times(1)).connect(any(MqttConnectOptions.class));
assertTrue(connectCalled.get());
MqttMessage message = new MqttMessage("qux".getBytes());
callback.get().messageArrived("baz", message);
Message<?> outMessage = outputChannel.receive(0);
assertNotNull(outMessage);
assertEquals("qux", outMessage.getPayload());
MqttIntegrationEvent event = events.poll(10, TimeUnit.SECONDS);
assertThat(event, instanceOf(MqttSubscribedEvent.class));
assertEquals("Connected and subscribed to [baz, fix]", ((MqttSubscribedEvent) event).getMessage());
// lose connection and make first reconnect fail
failConnection.set(true);
RuntimeException e = new RuntimeException("foo");
adapter.connectionLost(e);
event = events.poll(10, TimeUnit.SECONDS);
assertThat(event, instanceOf(MqttConnectionFailedEvent.class));
assertSame(event.getCause(), e);
assertTrue(failInProcess.await(10, TimeUnit.SECONDS));
waitToFail.countDown();
failConnection.set(false);
event = events.poll(10, TimeUnit.SECONDS);
assertThat(event, instanceOf(MqttConnectionFailedEvent.class));
assertSame(event.getCause(), reconnectException);
// reconnect can now succeed; however, we might have other failures on a slow server (500ms retry).
assertTrue(goodConnection.await(10, TimeUnit.SECONDS));
int n = 0;
while (!(event instanceof MqttSubscribedEvent) && n++ < 20) {
event = events.poll(10, TimeUnit.SECONDS);
}
assertThat(event, instanceOf(MqttSubscribedEvent.class));
assertEquals("Connected and subscribed to [baz, fix]", ((MqttSubscribedEvent) event).getMessage());
taskScheduler.destroy();
}
use of org.springframework.integration.mqtt.event.MqttSubscribedEvent in project spring-integration by spring-projects.
the class MqttPahoMessageDrivenChannelAdapter method connectAndSubscribe.
private synchronized void connectAndSubscribe() throws MqttException {
MqttConnectOptions connectionOptions = this.clientFactory.getConnectionOptions();
this.cleanSession = connectionOptions.isCleanSession();
this.consumerStopAction = this.clientFactory.getConsumerStopAction();
if (this.consumerStopAction == null) {
this.consumerStopAction = ConsumerStopAction.UNSUBSCRIBE_CLEAN;
}
Assert.state(getUrl() != null || connectionOptions.getServerURIs() != null, "If no 'url' provided, connectionOptions.getServerURIs() must not be null");
this.client = this.clientFactory.getClientInstance(getUrl(), getClientId());
this.client.setCallback(this);
if (this.client instanceof MqttClient) {
((MqttClient) this.client).setTimeToWait(this.completionTimeout);
}
this.topicLock.lock();
String[] topics = getTopic();
try {
this.client.connect(connectionOptions);
int[] requestedQos = getQos();
int[] grantedQos = Arrays.copyOf(requestedQos, requestedQos.length);
this.client.subscribe(topics, grantedQos);
for (int i = 0; i < requestedQos.length; i++) {
if (grantedQos[i] != requestedQos[i]) {
if (logger.isWarnEnabled()) {
logger.warn("Granted QOS different to Requested QOS; topics: " + Arrays.toString(topics) + " requested: " + Arrays.toString(requestedQos) + " granted: " + Arrays.toString(grantedQos));
}
break;
}
}
} catch (MqttException e) {
if (this.applicationEventPublisher != null) {
this.applicationEventPublisher.publishEvent(new MqttConnectionFailedEvent(this, e));
}
logger.error("Error connecting or subscribing to " + Arrays.toString(topics), e);
this.client.disconnectForcibly(this.completionTimeout);
throw e;
} finally {
this.topicLock.unlock();
}
if (this.client.isConnected()) {
this.connected = true;
String message = "Connected and subscribed to " + Arrays.toString(topics);
if (logger.isDebugEnabled()) {
logger.debug(message);
}
if (this.applicationEventPublisher != null) {
this.applicationEventPublisher.publishEvent(new MqttSubscribedEvent(this, message));
}
}
}
Aggregations