public AwsIot(Node root, String region, String accessKeyId, String secretAccessKey, KeyStore keyStore, String keyPassword) { AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey); this.client = new AWSIotClient(awsCredentials); this.client.withRegion(Regions.fromName(region)); String endpoint = getEndpoint(); String clientId = UUID.randomUUID().toString(); if (keyStore != null && keyPassword != null) { this.mqttClient = new AWSIotMqttClient(endpoint, clientId, keyStore, keyPassword); } else { this.mqttClient = new AWSIotMqttClient(endpoint, clientId, accessKeyId, secretAccessKey); } try { this.mqttClient.connect(); } catch (AWSIotException e) { throw new RuntimeException("Failed to connect to AWS IoT service", e); } this.root = root; }
public void activate() throws AWSIotException { stopSync(); for (String topic : getDeviceTopics()) { AWSIotTopic awsIotTopic; if (commandManager.isDeltaTopic(topic)) { awsIotTopic = new AwsIotDeviceDeltaListener(topic, shadowUpdateQos, this); } else { awsIotTopic = new AwsIotDeviceCommandAckListener(topic, methodAckQos, this); } client.subscribe(awsIotTopic, client.getServerAckTimeout()); } startSync(); }
public String runCommand(Command command, AWSIotMessage request, long commandTimeout, boolean isAsync) throws AWSIotException, AWSIotTimeoutException { String commandId = newCommandId(); appendCommandId(request, commandId); request.setTopic(getTopic(command, null)); AwsIotDeviceCommand deviceCommand = new AwsIotDeviceCommand(this, command, commandId, request, commandTimeout, isAsync); pendingCommands.put(commandId, deviceCommand); LOGGER.fine("Number of pending commands: " + pendingCommands.size()); try { deviceCommand.put(device); } catch (AWSIotException e) { // if exception happens during publish, we remove the command // from the pending list as we'll never get ack for it. pendingCommands.remove(commandId); throw e; } return deviceCommand.get(device); }
private void appendCommandId(AWSIotMessage message, String commandId) throws AWSIotException { String payload = message.getStringPayload(); if (payload == null) { payload = "{}"; } try { JsonNode jsonNode = objectMapper.readTree(payload); if (!jsonNode.isObject()) { throw new AWSIotException("Invalid Json string in payload"); } ((ObjectNode) jsonNode).put(COMMAND_ID_FIELD, commandId); message.setStringPayload(jsonNode.toString()); } catch (IOException e) { throw new AWSIotException(e); } }
public AwsIotMqttConnection(AbstractAwsIotClient client, SocketFactory socketFactory, String serverUri) throws AWSIotException { super(client); this.socketFactory = socketFactory; messageListener = new AwsIotMqttMessageListener(client); clientListener = new AwsIotMqttClientListener(client); try { mqttClient = new MqttAsyncClient(serverUri, client.getClientId(), new MemoryPersistence()); mqttClient.setCallback(clientListener); } catch (MqttException e) { throw new AWSIotException(e); } }
@Override public void publishMessage(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException { String topic = message.getTopic(); MqttMessage mqttMessage = new MqttMessage(message.getPayload()); mqttMessage.setQos(message.getQos().getValue()); try { mqttClient.publish(topic, mqttMessage, message, messageListener); } catch (MqttException e) { if (e.getReasonCode() == MqttException.REASON_CODE_CLIENT_NOT_CONNECTED) { throw new AwsIotRetryableException(e); } else { throw new AWSIotException(e); } } }
@Override public void onConnectionSuccess() { LOGGER.info("Client connection active: " + clientId); try { // resubscribe all the subscriptions for (AWSIotTopic topic : subscriptions.values()) { subscribe(topic, serverAckTimeout); } // start device sync for (AbstractAwsIotDevice device : devices.values()) { device.activate(); } } catch (AWSIotException e) { // connection couldn't be fully recovered, disconnecting LOGGER.warning("Failed to complete subscriptions while client is active, will disconnect"); try { connection.disconnect(null); } catch (AWSIotException de) { // ignore disconnect errors } } }
@Override public void onConnectionClosed() { LOGGER.info("Client connection closed: " + clientId); // stop device sync for (AbstractAwsIotDevice device : devices.values()) { try { device.deactivate(); } catch (AWSIotException e) { // ignore errors from deactivate() as the connection is lost LOGGER.warning("Failed to deactive all the devices, ignoring the error"); } } subscriptions.clear(); devices.clear(); executionService.shutdown(); }
/** * Schedule retry task so the connection can be retried after the timeout */ private void retryConnection() { if (retryTask != null) { LOGGER.warning("Connection retry already in progress"); // retry task already scheduled, do nothing return; } retryTask = client.scheduleTimeoutTask(new Runnable() { @Override public void run() { LOGGER.info("Connection is being retried"); connectionStatus = AWSIotConnectionStatus.RECONNECTING; retryTimes++; try { openConnection(null); } catch (AWSIotException e) { // permanent failure, notify the client and no more retries client.onConnectionClosed(); } } }, getRetryDelay()); }
public static void main(String args[]) throws InterruptedException, AWSIotException, AWSIotTimeoutException { CommandArguments arguments = CommandArguments.parse(args); initClient(arguments); awsIotClient.connect(); AWSIotTopic topic = new TestTopicListener(TestTopic, TestTopicQos); awsIotClient.subscribe(topic, true); Thread blockingPublishThread = new Thread(new BlockingPublisher(awsIotClient)); Thread nonBlockingPublishThread = new Thread(new NonBlockingPublisher(awsIotClient)); blockingPublishThread.start(); nonBlockingPublishThread.start(); blockingPublishThread.join(); nonBlockingPublishThread.join(); }
public static void main(String args[]) throws InterruptedException, AWSIotException { CommandArguments arguments = CommandArguments.parse(args); initClient(arguments); awsIotClient.setWillMessage(new AWSIotMessage("client/disconnect", AWSIotQos.QOS0, awsIotClient.getClientId())); String thingName = arguments.getNotNull("thingName", SampleUtil.getConfig("thingName")); ConnectedWindow connectedWindow = new ConnectedWindow(thingName); awsIotClient.attach(connectedWindow); awsIotClient.connect(); // Delete existing document if any connectedWindow.delete(); AWSIotConnectionStatus status = AWSIotConnectionStatus.DISCONNECTED; while (true) { AWSIotConnectionStatus newStatus = awsIotClient.getConnectionStatus(); if (!status.equals(newStatus)) { System.out.println(System.currentTimeMillis() + " Connection status changed to " + newStatus); status = newStatus; } Thread.sleep(1000); } }
public void subscribe(Node parent, String topic) { MessageListener listener = new MessageListener(topic, parent); try { mqttClient.subscribe(listener, true); } catch (AWSIotException e) { // TODO: log error message; } }
public void publish(String topic, byte[] data) { try { mqttClient.publish(topic, data); } catch (AWSIotException e) { // TODO: log error message; } }
private void connectToAwsEventHub() throws AWSIotException { applyProperties(); if (propertiesNeedUpdating) { cleanup(); propertiesNeedUpdating = false; } // iot service type - IOT_TOPIC | IOT_DEVICE isEventHubType = AwsIoTServiceType.IOT_TOPIC.toString().equals(iotServiceType); // get KeyStore credentials KeyStorePasswordPair pair = AwsIoTHubUtil.getKeyStorePasswordPair(x509Certificate, privateKey, null); // create AwsClient clientId = String.format("%s-%s", thingName, new BigInteger(128, new SecureRandom()).toString(32)); awsClient = new AWSIotMqttClient(clientEndpoint, clientId, pair.keyStore, pair.keyPassword); // attach device if (!isEventHubType) { // IoT Device attach geIoTDevice = new AwsIoTHubDevice(thingName); LOGGER.info(System.currentTimeMillis() + ": ClientId: " + clientId + ": Attaching device:" + geIoTDevice.getThingName()); awsClient.attach(geIoTDevice); } // connect to Aws IoT Hub LOGGER.info(System.currentTimeMillis() + ": ClientId: " + clientId + ": Connecting"); awsClient.connect(); LOGGER.info(System.currentTimeMillis() + ": ClientId: " + clientId + ": Connected"); // geIoTDevice.delete(10000); // delete shadow }
public void put(AbstractAwsIotDevice device) throws AWSIotException { if (device.isCommandReady(command)) { _put(device); } else { LOGGER.info("Request is pending: " + command.name() + "/" + commandId); } }
public boolean onReady(AbstractAwsIotDevice device) { try { LOGGER.info("Request is resumed: " + command.name() + "/" + commandId); _put(device); return true; } catch (AWSIotException e) { return false; } }
private void _put(AbstractAwsIotDevice device) throws AWSIotException { synchronized (this) { if (requestSent) { LOGGER.warning("Request was already sent: " + command.name() + "/" + commandId); return; } else { requestSent = true; } } device.getClient().publish(this, timeout); }
public void deactivate() throws AWSIotException { stopSync(); commandManager.onDeactivate(); for (String topic : getDeviceTopics()) { deviceSubscriptions.put(topic, false); AWSIotTopic awsIotTopic = new AWSIotTopic(topic); client.unsubscribe(awsIotTopic, client.getServerAckTimeout()); } }
public String runCommandSync(Command command, AWSIotMessage request) throws AWSIotException { try { return runCommand(command, request, 0, false); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public String runCommand(Command command, AWSIotMessage request, long commandTimeout) throws AWSIotException { try { return runCommand(command, request, commandTimeout, true); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because it's asynchronous call throw new AwsIotRuntimeException(e); } }
/** * The SigV4 signing key is made up by consecutively hashing a number of * unique pieces of data. * * @param dateStamp * the current date in short date format. * @return byte array containing the SigV4 signing key. * @throws AWSIotException */ private byte[] getSigningKey(String dateStamp) throws AWSIotException { if (signingSecretMac == null) { throw new AWSIotException("Signing credentials not provided"); } // AWS4 uses a series of derived keys, formed by hashing different // pieces of data byte[] signingDate = sign(dateStamp, signingSecretMac); byte[] signingRegion = sign(regionName, signingDate); byte[] signingService = sign(ServiceName, signingRegion); return sign(TERMINATOR, signingService); }
public AwsIotTlsSocketFactory(KeyStore keyStore, String keyPassword) throws AWSIotException { try { SSLContext context = SSLContext.getInstance(TLS_V_1_2); KeyManagerFactory managerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); managerFactory.init(keyStore, keyPassword.toCharArray()); context.init(managerFactory.getKeyManagers(), null, null); sslSocketFactory = context.getSocketFactory(); } catch (NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException | KeyManagementException e) { throw new AWSIotException(e); } }
public void openConnection(AwsIotMessageCallback callback) throws AWSIotException { try { AwsIotMqttConnectionListener connectionListener = new AwsIotMqttConnectionListener(client, true, callback); MqttConnectOptions options = buildMqttConnectOptions(client, socketFactory); mqttClient.connect(options, null, connectionListener); } catch (MqttException e) { throw new AWSIotException(e); } }
public void closeConnection(AwsIotMessageCallback callback) throws AWSIotException { try { AwsIotMqttConnectionListener connectionListener = new AwsIotMqttConnectionListener(client, false, callback); mqttClient.disconnect(0, null, connectionListener); } catch (MqttException e) { throw new AWSIotException(e); } }
@Override public void subscribeTopic(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException { try { mqttClient.subscribe(message.getTopic(), message.getQos().getValue(), message, messageListener); } catch (MqttException e) { if (e.getReasonCode() == MqttException.REASON_CODE_CLIENT_NOT_CONNECTED) { throw new AwsIotRetryableException(e); } else { throw new AWSIotException(e); } } }
@Override public void unsubscribeTopic(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException { try { mqttClient.unsubscribe(message.getTopic(), message, messageListener); } catch (MqttException e) { if (e.getReasonCode() == MqttException.REASON_CODE_CLIENT_NOT_CONNECTED) { throw new AwsIotRetryableException(e); } else { throw new AWSIotException(e); } } }
protected AbstractAwsIotClient(String clientEndpoint, String clientId, KeyStore keyStore, String keyPassword) { this.clientEndpoint = clientEndpoint; this.clientId = clientId; this.connectionType = AwsIotConnectionType.MQTT_OVER_TLS; try { connection = new AwsIotTlsConnection(this, keyStore, keyPassword); } catch (AWSIotException e) { throw new AwsIotRuntimeException(e); } }
protected AbstractAwsIotClient(String clientEndpoint, String clientId, String awsAccessKeyId, String awsSecretAccessKey, String sessionToken) { this.clientEndpoint = clientEndpoint; this.clientId = clientId; this.connectionType = AwsIotConnectionType.MQTT_OVER_WEBSOCKET; try { connection = new AwsIotWebsocketConnection(this, awsAccessKeyId, awsSecretAccessKey, sessionToken); } catch (AWSIotException e) { throw new AwsIotRuntimeException(e); } }
public void connect() throws AWSIotException { try { connect(0, true); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void connect(long timeout, boolean blocking) throws AWSIotException, AWSIotTimeoutException { synchronized (this) { if (executionService == null) { executionService = Executors.newScheduledThreadPool(numOfClientThreads); } } AwsIotCompletion completion = new AwsIotCompletion(timeout, !blocking); connection.connect(completion); completion.get(this); }
public void disconnect() throws AWSIotException { try { disconnect(0, true); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void publish(String topic, AWSIotQos qos, String payload) throws AWSIotException { try { publish(topic, qos, payload, 0); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void publish(String topic, AWSIotQos qos, byte[] payload) throws AWSIotException { try { publish(topic, qos, payload, 0); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void publish(AWSIotMessage message, long timeout) throws AWSIotException { AwsIotCompletion completion = new AwsIotCompletion(message, timeout, true); connection.publish(completion); try { completion.get(this); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because it's asynchronous call throw new AwsIotRuntimeException(e); } }
public void subscribe(AWSIotTopic topic, boolean blocking) throws AWSIotException { try { _subscribe(topic, 0, !blocking); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void subscribe(AWSIotTopic topic, long timeout) throws AWSIotException { try { _subscribe(topic, timeout, true); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because it's asynchronous call throw new AwsIotRuntimeException(e); } }
private void _subscribe(AWSIotTopic topic, long timeout, boolean async) throws AWSIotException, AWSIotTimeoutException { AwsIotCompletion completion = new AwsIotCompletion(topic, timeout, async); connection.subscribe(completion); completion.get(this); subscriptions.put(topic.getTopic(), topic); }
public void unsubscribe(String topic) throws AWSIotException { try { unsubscribe(topic, 0); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because timeout is 0 throw new AwsIotRuntimeException(e); } }
public void unsubscribe(String topic, long timeout) throws AWSIotException, AWSIotTimeoutException { if (subscriptions.remove(topic) == null) { return; } AwsIotCompletion completion = new AwsIotCompletion(topic, AWSIotQos.QOS0, timeout); connection.unsubscribe(completion); completion.get(this); }
public void unsubscribe(AWSIotTopic topic, long timeout) throws AWSIotException { if (subscriptions.remove(topic.getTopic()) == null) { return; } AwsIotCompletion completion = new AwsIotCompletion(topic, timeout, true); connection.unsubscribe(completion); try { completion.get(this); } catch (AWSIotTimeoutException e) { // We shouldn't get timeout exception because it's asynchronous call throw new AwsIotRuntimeException(e); } }