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); }
public void onCommandAck(AWSIotMessage response) { if (response == null || response.getTopic() == null) { return; } AwsIotDeviceCommand command = getPendingCommand(response); if (command == null) { LOGGER.warning("Unknown command received from topic " + response.getTopic()); return; } boolean success = response.getTopic().endsWith(COMMAND_ACK_PATHS.get(CommandAck.ACCEPTED)); if (!success && (Command.DELETE.equals(command.getCommand()) && AWSIotDeviceErrorCode.NOT_FOUND.equals(command .getErrorCode()))) { // Ignore empty document error (NOT_FOUND) for delete command success = true; } if (success) { command.setResponse(response); command.onSuccess(); } else { command.onFailure(); } }
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); } }
@Override public void onFailure(IMqttToken token, Throwable cause) { final AWSIotMessage message = (AWSIotMessage) token.getUserContext(); if (message == null) { LOGGER.warning("Request failed: " + token.getException()); return; } LOGGER.warning("Request failed for topic " + message.getTopic() + ": " + token.getException()); client.scheduleTask(new Runnable() { @Override public void run() { message.onFailure(); } }); }
@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); } } }
private MqttConnectOptions buildMqttConnectOptions(AbstractAwsIotClient client, SocketFactory socketFactory) { MqttConnectOptions options = new MqttConnectOptions(); options.setSocketFactory(socketFactory); options.setCleanSession(true); options.setConnectionTimeout(client.getConnectionTimeout() / 1000); options.setKeepAliveInterval(client.getKeepAliveInterval() / 1000); Set<String> serverUris = getServerUris(); if (serverUris != null && !serverUris.isEmpty()) { String[] uriArray = new String[serverUris.size()]; serverUris.toArray(uriArray); options.setServerURIs(uriArray); } if (client.getWillMessage() != null) { AWSIotMessage message = client.getWillMessage(); options.setWill(message.getTopic(), message.getPayload(), message.getQos().getValue(), false); } return options; }
public void dispatch(final AWSIotMessage message) { boolean matches = false; for (String topicFilter : subscriptions.keySet()) { if (topicFilterMatch(topicFilter, message.getTopic())) { final AWSIotTopic topic = subscriptions.get(topicFilter); scheduleTask(new Runnable() { @Override public void run() { topic.onMessage(message); } }); matches = true; } } if (!matches) { LOGGER.warning("Unexpected message received from topic " + message.getTopic()); } }
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); } }
@Override public void onMessage(AWSIotMessage message) { String messageId = UUID.randomUUID().toString(); MessageNode node = new MessageNode(messagesNode, messageId, message.getPayload()); messagesNode.addChildren(node); }
public AwsIotDeviceCommand(AwsIotDeviceCommandManager commandManager, Command command, String commandId, AWSIotMessage request, long commandTimeout, boolean isAsync) { super(request, commandTimeout, isAsync); this.commandManager = commandManager; this.command = command; this.commandId = commandId; this.requestSent = false; }
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); } }
private AwsIotDeviceCommand getPendingCommand(AWSIotMessage message) { String payload = message.getStringPayload(); if (payload == null) { return null; } try { JsonNode jsonNode = objectMapper.readTree(payload); if (!jsonNode.isObject()) { return null; } JsonNode node = jsonNode.get(COMMAND_ID_FIELD); if (node == null) { return null; } String commandId = node.textValue(); AwsIotDeviceCommand command = pendingCommands.remove(commandId); if (command == null) { return null; } node = jsonNode.get(ERROR_CODE_FIELD); if (node != null) { command.setErrorCode(AWSIotDeviceErrorCode.valueOf(node.longValue())); } node = jsonNode.get(ERROR_MESSAGE_FIELD); if (node != null) { command.setErrorMessage(node.textValue()); } return command; } catch (IOException e) { return null; } }
@Override public void onSuccess(IMqttToken token) { final AWSIotMessage message = (AWSIotMessage) token.getUserContext(); if (message == null) { return; } boolean forceFailure = false; if (token.getResponse() instanceof MqttSuback) { MqttSuback subAck = (MqttSuback) token.getResponse(); int qos[] = subAck.getGrantedQos(); for (int i = 0; i < qos.length; i++) { if (qos[i] == SUB_ACK_RETURN_CODE_FAILURE) { LOGGER.warning("Request failed: likely due to too many subscriptions or policy violations"); forceFailure = true; break; } } } final boolean isSuccess = !forceFailure; client.scheduleTask(new Runnable() { @Override public void run() { if (isSuccess) { message.onSuccess(); } else { message.onFailure(); } } }); }
@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); } } }
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); } }
/** * The actual publish method exposed by this class. * * @param message * the message to be published * @throws AWSIotException * this exception is thrown when the underneath failed to * process the request */ public void publish(AWSIotMessage message) throws AWSIotException { try { publishMessage(message); } catch (AwsIotRetryableException e) { if (client.getMaxOfflineQueueSize() > 0 && publishQueue.size() < client.getMaxOfflineQueueSize()) { publishQueue.add(message); } else { LOGGER.info("Failed to publish message to " + message.getTopic()); throw new AWSIotException(e); } } }
/** * The actual subscribe method exposed by this class. * * @param message * the topic to be subscribed to * @throws AWSIotException * this exception is thrown when the underneath failed to * process the request */ public void subscribe(AWSIotMessage message) throws AWSIotException { try { subscribeTopic(message); } catch (AwsIotRetryableException e) { if (client.getMaxOfflineQueueSize() > 0 && subscribeQueue.size() < client.getMaxOfflineQueueSize()) { subscribeQueue.add(message); } else { LOGGER.info("Failed to subscribe to " + message.getTopic()); throw new AWSIotException(e); } } }
/** * The actual unsubscribe method exposed by this class. * * @param message * the topic to be unsubscribed to * @throws AWSIotException * this exception is thrown when the underneath failed to * process the request */ public void unsubscribe(AWSIotMessage message) throws AWSIotException { try { unsubscribeTopic(message); } catch (AwsIotRetryableException e) { if (client.getMaxOfflineQueueSize() > 0 && unsubscribeQueue.size() < client.getMaxOfflineQueueSize()) { unsubscribeQueue.add(message); } else { LOGGER.info("Failed to unsubscribe to " + message.getTopic()); throw new AWSIotException(e); } } }
@Override public void onMessage(AWSIotMessage message) { LOGGER.info(System.currentTimeMillis() + ": ClientId: " + clientId + ": subscribe success for: " + this.topic + " >>> " + message.getStringPayload()); receive(message.getPayload()); }
@Override public void onMessage(AWSIotMessage message) { device.onCommandAck(message); }
protected String get() throws AWSIotException { AWSIotMessage message = new AWSIotMessage(null, methodQos); return commandManager.runCommandSync(Command.GET, message); }
protected String get(long timeout) throws AWSIotException, AWSIotTimeoutException { AWSIotMessage message = new AWSIotMessage(null, methodQos); return commandManager.runCommandSync(Command.GET, message, timeout); }
protected void get(AWSIotMessage message, long timeout) throws AWSIotException { commandManager.runCommand(Command.GET, message, timeout); }
protected void update(String jsonState) throws AWSIotException { AWSIotMessage message = new AWSIotMessage(null, methodQos, jsonState); commandManager.runCommandSync(Command.UPDATE, message); }
protected void update(String jsonState, long timeout) throws AWSIotException, AWSIotTimeoutException { AWSIotMessage message = new AWSIotMessage(null, methodQos, jsonState); commandManager.runCommandSync(Command.UPDATE, message, timeout); }
protected void update(AWSIotMessage message, long timeout) throws AWSIotException { commandManager.runCommand(Command.UPDATE, message, timeout); }
protected void delete() throws AWSIotException { AWSIotMessage message = new AWSIotMessage(null, methodQos); commandManager.runCommandSync(Command.DELETE, message); }
protected void delete(long timeout) throws AWSIotException, AWSIotTimeoutException { AWSIotMessage message = new AWSIotMessage(null, methodQos); commandManager.runCommandSync(Command.DELETE, message, timeout); }
protected void delete(AWSIotMessage message, long timeout) throws AWSIotException { commandManager.runCommand(Command.DELETE, message, timeout); }
public void onCommandAck(AWSIotMessage message) { commandManager.onCommandAck(message); }
public String runCommandSync(Command command, AWSIotMessage request, long commandTimeout) throws AWSIotException, AWSIotTimeoutException { return runCommand(command, request, commandTimeout, false); }
@Override public void messageArrived(String topic, MqttMessage arg1) throws Exception { AWSIotMessage message = new AWSIotMessage(topic, AWSIotQos.valueOf(arg1.getQos()), arg1.getPayload()); client.dispatch(message); }
public void publish(AWSIotMessage message) throws AWSIotException { publish(message, 0); }
@Override public void onMessage(AWSIotMessage message) { System.out.println(System.currentTimeMillis() + ": <<< " + message.getStringPayload()); }
/** * Instantiates a new completion object either synchronous or asynchronous * request based on the <code>isAsync</code> argument. Callback functions * are provided through the <code>req</code> argument. * * @param req * the request containing request topic, QoS, payload, and * callback functions for asynchronous requests. * @param timeout * the timeout in milliseconds for the request. If timeout is 0 * or less, the request will never be timed out. * @param isAsync * whether or not the request is asynchronous */ public AwsIotCompletion(AWSIotMessage req, long timeout, boolean isAsync) { super(req.getTopic(), req.getQos(), req.getPayload()); this.request = req; this.timeout = timeout; this.isAsync = isAsync; }
/** * Abstract method which is called to publish a message. * * @param message * the message to be published * @throws AWSIotException * this exception is thrown when there's an unrecoverable error * happened while processing the request * @throws AwsIotRetryableException * this exception is thrown when the request is failed to be * sent, which will be queued and retried */ protected abstract void publishMessage(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException;
/** * Abstract method which is called to subscribe to a topic. * * @param message * the topic to be subscribed to * @throws AWSIotException * this exception is thrown when there's an unrecoverable error * happened while processing the request * @throws AwsIotRetryableException * this exception is thrown when the request is failed to be * sent, which will be queued and retried */ protected abstract void subscribeTopic(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException;
/** * Abstract method which is called to unsubscribe to a topic. * * @param message * the topic to be unsubscribed to * @throws AWSIotException * this exception is thrown when there's an unrecoverable error * happened while processing the request * @throws AwsIotRetryableException * this exception is thrown when the request is failed to be * sent, which will be queued and retried */ protected abstract void unsubscribeTopic(AWSIotMessage message) throws AWSIotException, AwsIotRetryableException;