private static <T> T exec(Future<T> future) throws IOException {
   try {
     return future.await();
   } catch (Exception e) {
     throw new IOException();
   }
 }
 @Override
 public void run() {
   LOGGER.info("Started MQTT subscription processing thread.");
   while (true) {
     try {
       Future<Message> future = connection.receive();
       Message message = future.await();
       message.ack();
       EventProcessingLogic.processRawPayload(
           MqttInboundEventReceiver.this, message.getPayload(), null);
     } catch (InterruptedException e) {
       break;
     } catch (Throwable e) {
       LOGGER.error(e);
     }
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see
   * com.sitewhere.device.communication.mqtt.MqttLifecycleComponent#start(com.
   * sitewhere.spi.server.lifecycle.ILifecycleProgressMonitor)
   */
  @Override
  public void start(ILifecycleProgressMonitor monitor) throws SiteWhereException {
    super.start(monitor);

    this.executor = Executors.newSingleThreadExecutor(new SubscribersThreadFactory());
    LOGGER.info("Receiver connecting to MQTT broker at '" + getBrokerInfo() + "'...");
    connection = getConnection();
    LOGGER.info("Receiver connected to MQTT broker.");

    // Subscribe to chosen topic.
    Topic[] topics = {new Topic(getTopic(), QoS.AT_LEAST_ONCE)};
    try {
      Future<byte[]> future = connection.subscribe(topics);
      future.await();

      LOGGER.info("Subscribed to events on MQTT topic: " + getTopic());
    } catch (Exception e) {
      throw new SiteWhereException(
          "Exception while attempting to subscribe to MQTT topic: " + getTopic(), e);
    }

    // Handle message processing in separate thread.
    executor.execute(new MqttSubscriptionProcessor());
  }