Beispiel #1
0
  private void doConnect() {
    L.info(
        "Connecting to MQTT broker "
            + mqttc.getServerURI()
            + " with CLIENTID="
            + mqttc.getClientId()
            + " and TOPIC PREFIX="
            + topicPrefix);

    MqttConnectOptions copts = new MqttConnectOptions();
    copts.setWill(topicPrefix + "connected", "0".getBytes(), 1, true);
    copts.setCleanSession(true);
    copts.setUserName("emonpi");
    copts.setPassword("emonpimqtt2016".toCharArray());
    try {
      mqttc.connect(copts);
      sendConnectionState();
      L.info("Successfully connected to broker, subscribing to " + topicPrefix + "(set|get)/#");
      try {
        mqttc.subscribe(topicPrefix + "set/#", 1);
        mqttc.subscribe(topicPrefix + "get/#", 1);
        shouldBeConnected = true;
      } catch (MqttException mqe) {
        L.log(Level.WARNING, "Error subscribing to topic hierarchy, check your configuration", mqe);
        throw mqe;
      }
    } catch (MqttException mqe) {
      L.log(
          Level.WARNING,
          "Error while connecting to MQTT broker, will retry: " + mqe.getMessage(),
          mqe);
      queueConnect(); // Attempt reconnect
    }
  }
 @Override
 public MqttConnectOptions getConnectionOptions() {
   MqttConnectOptions options = new MqttConnectOptions();
   if (this.cleanSession != null) {
     options.setCleanSession(this.cleanSession);
   }
   if (this.connectionTimeout != null) {
     options.setConnectionTimeout(this.connectionTimeout);
   }
   if (this.keepAliveInterval != null) {
     options.setKeepAliveInterval(this.keepAliveInterval);
   }
   if (this.password != null) {
     options.setPassword(this.password.toCharArray());
   }
   if (this.socketFactory != null) {
     options.setSocketFactory(this.socketFactory);
   }
   if (this.sslProperties != null) {
     options.setSSLProperties(this.sslProperties);
   }
   if (this.userName != null) {
     options.setUserName(this.userName);
   }
   if (this.will != null) {
     options.setWill(
         this.will.getTopic(), this.will.getPayload(), this.will.getQos(), this.will.isRetained());
   }
   if (this.serverURIs != null) {
     options.setServerURIs(this.serverURIs);
   }
   return options;
 }
 void connectAndSub() {
   String methodName = Utility.getMethodName();
   try {
     mqttClient = clientFactory.createMqttClient(serverURI, ClientId);
     mqttV3Receiver = new MqttV3Receiver(mqttClient, LoggingUtilities.getPrintStream());
     mqttV3Receiver.setReportConnectionLoss(false);
     mqttClient.setCallback(mqttV3Receiver);
     MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
     mqttConnectOptions.setCleanSession(false);
     mqttConnectOptions.setWill("WillTopic", "payload".getBytes(), 2, true);
     log.info("Connecting...(serverURI:" + serverURI + ", ClientId:" + ClientId);
     mqttClient.connect(mqttConnectOptions);
     log.info("Subscribing to..." + FirstSubTopicString);
     mqttClient.subscribe(FirstSubTopicString, 2);
   } catch (Exception exception) {
     log.log(Level.SEVERE, "caugh exception:" + exception);
     setState(FirstClientState.ERROR);
     Assert.fail("Failed ConnectAndSub exception=" + exception);
   }
 }
  private MqttConnectOptions getConnectOptions(
      String userName,
      String password,
      Boolean clearSession,
      Integer connectionTimeout,
      String lwtTopic,
      String lwtMessage,
      Integer lwtQos,
      Boolean lwtRetained) {
    MqttConnectOptions connectOpts = new MqttConnectOptions();

    if (!StringUtility.isNullOrEmpty(userName)) {
      connectOpts.setUserName(userName);

      if (!StringUtility.isNullOrEmpty(password)) {
        connectOpts.setPassword(password.toCharArray());
      }
    }

    if (clearSession != null) {
      connectOpts.setCleanSession(clearSession);
    }

    if (connectionTimeout != null) {
      connectOpts.setConnectionTimeout(connectionTimeout);
    }

    if (!StringUtility.isNullOrEmpty(lwtTopic) && !StringUtility.isNullOrEmpty(lwtMessage)) {
      connectOpts.setWill(
          lwtTopic,
          lwtMessage.getBytes(),
          NumberUtility.nvl(lwtQos, 1),
          BooleanUtility.nvl(lwtRetained, false));
    }

    return connectOpts;
  }
  /**
   * Test that a client actively doing work can be taken over
   *
   * @throws Exception
   */
  @Test
  public void testLiveTakeOver() throws Exception {
    String methodName = Utility.getMethodName();
    LoggingUtilities.banner(log, cclass, methodName);
    log.entering(className, methodName);

    IMqttClient mqttClient = null;
    try {
      FirstClient firstClient = new FirstClient();
      Thread firstClientThread = new Thread(firstClient);
      log.info("Starting the firstClient thread");
      firstClientThread.start();
      log.info("firstClientThread Started");

      firstClient.waitForState(FirstClientState.READY);

      log.fine("telling the 1st client to go and let it publish for 2 seconds");
      // Tell the first client to go and let it publish for a couple of seconds
      firstClient.setState(FirstClientState.RUNNING);
      Thread.sleep(2000);

      log.fine("Client has been run for 2 seconds, now taking over connection");

      // Now lets take over the connection
      // Create a second MQTT client connection with the same clientid. The
      // server should spot this and kick the first client connection off.
      // To do this from the same box the 2nd client needs to use either
      // a different form of persistent store or a different locaiton for
      // the store to the first client.
      // MqttClientPersistence persist = new MemoryPersistence();
      mqttClient = clientFactory.createMqttClient(serverURI, ClientId, null);

      MqttV3Receiver mqttV3Receiver =
          new MqttV3Receiver(mqttClient, LoggingUtilities.getPrintStream());
      mqttClient.setCallback(mqttV3Receiver);
      MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
      mqttConnectOptions.setCleanSession(false);
      mqttConnectOptions.setWill("WillTopic", "payload".getBytes(), 2, true);
      log.info("Connecting...(serverURI:" + serverURI + ", ClientId:" + ClientId);
      mqttClient.connect(mqttConnectOptions);

      // We should have taken over the first Client's subscription...we may have some
      // of his publishes arrive.
      // NOTE: as a different persistence is used for the second client any inflight
      // publications from the client will not be recovered / restarted. This will
      // leave debris on the server.
      log.fine(
          "We should have taken over the first Client's subscription...we may have some of his publishes arrive.");
      // Ignore his publishes that arrive...
      ReceivedMessage oldMsg;
      do {
        oldMsg = mqttV3Receiver.receiveNext(1000);
      } while (oldMsg != null);

      log.fine("Now check we have grabbed his subscription by publishing..");
      // Now check we have grabbed his subscription by publishing..
      byte[] payload =
          ("Message payload from second client " + getClass().getName() + "." + methodName)
              .getBytes();
      MqttTopic mqttTopic = mqttClient.getTopic(FirstSubTopicString);
      log.info("Publishing to..." + FirstSubTopicString);
      mqttTopic.publish(payload, 1, false);
      log.info("Publish sent, checking for receipt...");

      boolean ok = mqttV3Receiver.validateReceipt(FirstSubTopicString, 1, payload);
      if (!ok) {
        throw new Exception("Receive failed");
      }
    } catch (Exception exception) {
      log.throwing(className, methodName, exception);
      throw exception;
    } finally {
      try {
        mqttClient.disconnect();
        log.info("Disconnecting...");
        mqttClient.close();
        log.info("Close...");
      } catch (Exception exception) {
        log.throwing(className, methodName, exception);
        throw exception;
      }
    }

    log.exiting(className, methodName);
  }
  /**
   * Process data from the connect action
   *
   * @param data the {@link Bundle} returned by the {@link NewConnection} Acitivty
   */
  private void connectAction(Bundle data) {
    MqttConnectOptions conOpt = new MqttConnectOptions();
    /*
     * Mutal Auth connections could do something like this
     *
     *
     * SSLContext context = SSLContext.getDefault();
     * context.init({new CustomX509KeyManager()},null,null); //where CustomX509KeyManager proxies calls to keychain api
     * SSLSocketFactory factory = context.getSSLSocketFactory();
     *
     * MqttConnectOptions options = new MqttConnectOptions();
     * options.setSocketFactory(factory);
     *
     * client.connect(options);
     *
     */

    //    public Properties getSSLSettings() {
    //        final Properties properties = new Properties();
    //        properties.setProperty("com.ibm.ssl.keyStore",
    //            "C:/BKSKeystore/mqttclientkeystore.keystore");
    //        properties.setProperty("com.ibm.ssl.keyStoreType", "BKS");
    //        properties.setProperty("com.ibm.ssl.keyStorePassword", "passphrase");
    //        properties.setProperty("com.ibm.ssl.trustStore",
    //            "C:/BKSKeystore/mqttclienttrust.keystore");
    //        properties.setProperty("com.ibm.ssl.trustStoreType", "BKS");
    //        properties.setProperty("com.ibm.ssl.trustStorePassword", "passphrase ");
    //
    //        return properties;
    //    }

    try {

      SSLContext context;
      KeyStore ts = KeyStore.getInstance("BKS");
      ts.load(getResources().openRawResource(R.raw.test), "123456".toCharArray());
      TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
      tmf.init(ts);
      TrustManager[] tm = tmf.getTrustManagers();
      context = SSLContext.getInstance("TLS");
      context.init(null, tm, null);

      // SocketFactory factory= SSLSocketFactory.getDefault();
      // Socket socket =factory.createSocket("localhost", 10000);
      SocketFactory factory = context.getSocketFactory();
      conOpt.setSocketFactory(factory);

    } catch (Exception e) {
      // TODO: handle exception
    }

    // The basic client information
    String server = (String) data.get(ActivityConstants.server);
    String clientId = (String) data.get(ActivityConstants.clientId);
    int port = Integer.parseInt((String) data.get(ActivityConstants.port));
    boolean cleanSession = (Boolean) data.get(ActivityConstants.cleanSession);

    boolean ssl = (Boolean) data.get(ActivityConstants.ssl);
    String uri = null;
    if (ssl) {
      Log.e("SSLConnection", "Doing an SSL Connect");
      uri = "ssl://";

    } else {
      uri = "tcp://";
    }

    uri = uri + server + ":" + port;

    MqttClientAndroidService client;
    client = Connections.getInstance(this).createClient(this, uri, clientId);
    // create a client handle
    String clientHandle = uri + clientId;

    // last will message
    String message = (String) data.get(ActivityConstants.message);
    String topic = (String) data.get(ActivityConstants.topic);
    Integer qos = (Integer) data.get(ActivityConstants.qos);
    Boolean retained = (Boolean) data.get(ActivityConstants.retained);

    // connection options

    String username = (String) data.get(ActivityConstants.username);

    String password = (String) data.get(ActivityConstants.password);

    int timeout = (Integer) data.get(ActivityConstants.timeout);
    int keepalive = (Integer) data.get(ActivityConstants.keepalive);

    Connection connection = new Connection(clientHandle, clientId, server, port, this, client, ssl);
    arrayAdapter.add(connection);

    connection.registerChangeListener(changeListener);
    // connect client

    String[] actionArgs = new String[1];
    actionArgs[0] = clientId;
    connection.changeConnectionStatus(ConnectionStatus.CONNECTING);

    conOpt.setCleanSession(cleanSession);
    conOpt.setConnectionTimeout(timeout);
    conOpt.setKeepAliveInterval(keepalive);
    if (!username.equals(ActivityConstants.empty)) {
      conOpt.setUserName(username);
    }
    if (!password.equals(ActivityConstants.empty)) {
      conOpt.setPassword(password.toCharArray());
    }

    final ActionListener callback =
        new ActionListener(this, ActionListener.Action.CONNECT, clientHandle, actionArgs);

    boolean doConnect = true;

    if ((!message.equals(ActivityConstants.empty)) || (!topic.equals(ActivityConstants.empty))) {
      // need to make a message since last will is set
      try {
        conOpt.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
      } catch (Exception e) {
        doConnect = false;
        callback.onFailure(null, e);
      }
    }
    client.setCallback(new MqttCallbackHandler(this, clientHandle));
    connection.addConnectionOptions(conOpt);
    Connections.getInstance(this).addConnection(connection);
    if (doConnect) {
      try {
        client.connect(conOpt, null, callback);
      } catch (MqttException e) {
        Log.e(this.getClass().getCanonicalName(), "MqttException Occured", e);
      }
    }
  }
  public void publish(String publishClientId, String publishTopic, byte[] payload)
      throws DeviceControllerException {

    if (mqttEnabled) {
      MqttClient client;
      MqttConnectOptions options;

      if (publishClientId.length() > 24) {
        String errorString =
            "No of characters '"
                + publishClientId.length()
                + "' for ClientID: '"
                + publishClientId
                + "' is invalid (should be less than 24, hence please provide a "
                + "simple "
                + "'owner' tag)";
        log.error(errorString);
        throw new DeviceControllerException(errorString);
      } else {
        log.info(
            "No of Characters "
                + publishClientId.length()
                + " for ClientID : '"
                + publishClientId
                + "' is acceptable");
      }

      try {
        client = new MqttClient(mqttEndpoint, publishClientId);
        options = new MqttConnectOptions();
        options.setWill("device/clienterrors", "crashed".getBytes(UTF_8), 2, true);
        client.setCallback(this);
        client.connect(options);

        client.publish(publishTopic, payload, 0, true);

        if (log.isDebugEnabled()) {
          log.debug(
              "MQTT Client successfully published to topic: "
                  + publishTopic
                  + ", with payload - "
                  + payload);
        }
        client.disconnect();
      } catch (MqttException ex) {
        String errorMsg =
            "MQTT Client Error"
                + "\n\tReason:  "
                + ex.getReasonCode()
                + "\n\tMessage: "
                + ex.getMessage()
                + "\n\tLocalMsg: "
                + ex.getLocalizedMessage()
                + "\n\tCause: "
                + ex.getCause()
                + "\n\tException: "
                + ex;

        log.error(errorMsg, ex);
        throw new DeviceControllerException(errorMsg, ex);
      }
    } else {
      log.warn("MQTT <Enabled> set to false in 'device-mgt-config.xml'");
    }
  }