/******************************************************************************* * Copyright (c) 2011, 2016 Eurotech and/or its affiliates * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eurotech *******************************************************************************/ package org.eclipse.kura.cloud; import java.util.List; import org.eclipse.kura.KuraException; import org.eclipse.kura.data.DataService; import org.eclipse.kura.message.KuraPayload; /** * The CloudClient is designed to be used by single application bundles. * CloudClient instances are acquired from the CloudService and they * are released when the work is completed. Generally, a CloudClient * is acquired during the activation phase of a bundle and it is released * during the deactivation phase. * <br> * CloudClient leverages the {@link org.eclipse.kura.data.DataService} * for all interactions with the transport layer and the communication * with the remote server. CloudClient establishes a set of default * subscriptions that allow remote servers or other devices to direct messages * to the application instance. * <br> * If the bundle using the CloudClient relies on custom subscriptions * beyond the default ones, it is responsibility of the application to implement * the {@link CloudClientListener#onConnectionEstablished()} callback method in the * CloudCallbackHandler to restore the subscriptions it needs. * <br> * The <b>CloudClient.release method will unsubscribe</b> all subscriptions * incurred by this client and it will unregister this CloudClient * instance from the list of CloudCallbackHandlers registered. * <br> * There can be more than one instance of CloudClient in the system, * ideally one per ApplicationId but this is not enforced. * The class accepts more than one callback handler; all registered handlers are invoked * when a message is received. It is up to the received to analyze the topic * of the message received and handle it appropriately. * <br> * The CloudClient publishes and receives messages using a topic namespace * following a structure as: [CRTL_PREFIX/]accountName/deviceId/appId/appTopic.<br> * <ul> * <li>CRTL_PREFIX: is an optional prefix to denote topic used for control messages * as opposed to data messages. The framework makes use of control topics to * separate management messages like replies from those used for application data. * <li>accountName: an unique identifier that represents a group of devices and users * <li>deviceId: an unique identifier within an account that represents a single gateway device. * By default, the MAC address of its primary network interface is generally used as the deviceId of the gateway. * In the case of an MQTT transport, for example, deviceId maps to the Client Identifier (Client ID). * <li>appId: an identifier to denote an application running on the gateway device. * We suggest to version the application identifier in order to allow multiple versions of the application * to coexist, e.g. CONF-V1, CONF-V2, etc. * <li>appTopic topic defined and managed by the application. * </ul> * accountName, deviceId, and applicationId are derived based on the configuration parameters * of the system where this instance is deployed while the applicationTopic is controlled * by the application. The following is an example of topic used for publishing where the prefix * used for the control Topics is $EDC. * <ul> * <li>publish: accountName/deviceId/applicationId/appTopic * <li>controlPublish: $EDC/accountName/assetId/applicationId/appTopic * <li>subscribe: accountName/deviceId/applicationId/appTopic * <li>controlSubscribe: $EDC/accountName/deviceId/applicationId/appTopic * <li>default subscriptions: $EDC/accountName/deviceId/applicationId/# * </ul> * Note that the default subscription of a CloudClient allows remote servers * or applications running on other devices to publish messages addressed * to specific applications running on specific devices. */ public interface CloudClient { /** * Returns the applicationId of this CloudClient * * @return applicationId */ public String getApplicationId(); /** * Releases this CloudClient handle. This instance should no longer be used. * Note: CloudClient does not unsubscribes all subscriptions incurred by this client, * this responsibility is left to the application developer */ public void release(); /** * Returns an indication of whether the connection to the remote server is established. * If your application needs to manage the connection directly, it can use the * {@link DataService#connect} and {@link DataService#disconnect} methods. * * @return boolean, whether connection to broker is established. */ public boolean isConnected(); /** * Publishes a message to the remote server using the default priority 5. * Before passing the message the to {@link org.eclipse.kura.data.DataService}, * the CloudClient will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning and device identification. It is also responsible to * encode the {@link KuraPayload} payload into binary format. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. * * @param appTopic * A String specifying the application portion of the topic the message is published on. * @param payload * An KuraPayload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @return The published message's ID. */ public int publish(String appTopic, KuraPayload payload, int qos, boolean retain) throws KuraException; /** * Publishes a message to the remote server. * Before passing the message the to {@link org.eclipse.kura.data.DataService}, * the CloudClient will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning and device identification. It is also responsible to * encode the {@link KuraPayload} payload into binary format. * <br> * The priority argument can be used to control the relative ordering of this * message with other messages that may be currently queued for publishing. * Priority level 0 (highest) should be used sparingly and reserved for * messages that should be sent with the minimum latency. Life-cycle messages * (e.g. device start and stop) are an example of messages that are * published by the framework with priority 0. * Priority 1 messages are used by the framework to publish response messages * in request/response conversations to prevent a timeout at the requester. * Application should consider using priority 5 or higher. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. The limit does not apply to internal messages with the priority less than 2. * These priority levels are reserved to the framework which uses it for life-cycle messages * - birth and death certificates - and replies to request/response flows. * * @param appTopic * A String specifying the application portion of the topic the message is published on. * @param payload * An KuraPayload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @param priority * Relative ordering of this message with other messages that may be currently queued for publishing. * @return The published message's ID. */ public int publish(String appTopic, KuraPayload payload, int qos, boolean retain, int priority) throws KuraException; /** * Publishes a message to the remote server with a raw byte array payload. * This is the lowest level publish API exposed by the CloudClient. * Before passing the message the to {@link org.eclipse.kura.data.DataService}, * the CloudClient will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning and device identification. * <br> * The priority argument can be used to control the relative ordering of this * message with other messages that may be currently queued for publishing. * Priority level 0 (highest) should be used sparingly and reserved for * messages that should be sent with the minimum latency. Life-cycle messages * (e.g. device start and stop) are an example of messages that are * published by the framework with priority 0. * Priority 1 messages are used by the framework to publish response messages * in request/response conversations to prevent a timeout at the requester. * Application should consider using priority 5 or higher. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. The limit does not apply to internal messages with the priority less than 2. * These priority levels are reserved to the framework which uses it for life-cycle messages * - birth and death certificates - and replies to request/response flows. * * @param appTopic * A String specifying the application portion of the topic the message is published on. * @param payload * Binary payload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @param priority * Relative ordering of this message with other messages that may be currently queued for publishing. * @return The published message's ID. */ public int publish(String appTopic, byte[] payload, int qos, boolean retain, int priority) throws KuraException; /** * Publishes a control message to the remote server. Control messages are qualified with an * additional prefix appended at the beginning of the target topic. The * prefix is configured as a property of the {@link CloudService} and it appended * automatically by this controlPublish method. Just as {@link #publish}, the * controlPublish method will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning including device identification and encode * the {@link KuraPayload} payload into binary format. * <br> * The priority argument can be used to control the relative ordering of this * message with other messages that may be currently queued for publishing. * Priority level 0 (highest) should be used sparingly and reserved for * messages that should be sent with the minimum latency. Life-cycle messages * (e.g. device start and stop) are an example of messages that are * published by the framework with priority 0. * Priority 1 messages are used by the framework to publish response messages * in request/response conversations to prevent a timeout at the requester. * Application should consider using priority 5 or higher. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. The limit does not apply to internal messages with the priority less than 2. * These priority levels are reserved to the framework which uses it for life-cycle messages * - birth and death certificates - and replies to request/response flows. * * @param appTopic * A String specifying the application topic the message is published on. * @param payload * An KuraPayload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @param priority * Relative ordering of this message with other messages that may be currently queued for publishing. * @return The published message's ID. */ public int controlPublish(String appTopic, KuraPayload payload, int qos, boolean retain, int priority) throws KuraException; /** * Publishes a control message to the remote server addressing it to another device. * Control messages are qualified with an additional prefix appended at the beginning of the target topic. * The prefix is configured as a property of the {@link CloudService} and it appended * automatically by this controlPublish method. Just as {@link #publish}, the * controlPublish method will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning including device identification and encode * the {@link KuraPayload} payload into binary format. * <br> * The priority argument can be used to control the relative ordering of this * message with other messages that may be currently queued for publishing. * Priority level 0 (highest) should be used sparingly and reserved for * messages that should be sent with the minimum latency. Life-cycle messages * (e.g. device start and stop) are an example of messages that are * published by the framework with priority 0. * Priority 1 messages are used by the framework to publish response messages * in request/response conversations to prevent a timeout at the requester. * Application should consider using priority 5 or higher. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. The limit does not apply to internal messages with the priority less than 2. * These priority levels are reserved to the framework which uses it for life-cycle messages * - birth and death certificates - and replies to request/response flows. * * @param deviceId * A String specifying the asset ID. * @param appTopic * A String specifying the application topic the message is published on. * @param payload * An KuraPayload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @param priority * Relative ordering of this message with other messages that may be currently queued for publishing. * @return The published message's ID. */ public int controlPublish(String deviceId, String appTopic, KuraPayload payload, int qos, boolean retain, int priority) throws KuraException; /** * Publishes a control message to the remote server addressing it to another device * with a raw byte array payload. * Control messages are qualified with an additional prefix appended at the beginning of the target topic. * The prefix is configured as a property of the {@link CloudService} and it appended * automatically by this controlPublish method. Just as {@link #publish}, the * controlPublish method will manipulate the provided topic by appending the necessary parts * to achieve topic partitioning including device identification. * <br> * The priority argument can be used to control the relative ordering of this * message with other messages that may be currently queued for publishing. * Priority level 0 (highest) should be used sparingly and reserved for * messages that should be sent with the minimum latency. Life-cycle messages * (e.g. device start and stop) are an example of messages that are * published by the framework with priority 0. * Priority 1 messages are used by the framework to publish response messages * in request/response conversations to prevent a timeout at the requester. * Application should consider using priority 5 or higher. * <br> * The KuraStoreCapacityReachedException is thrown if the database buffer * has reached its capacity for messages that are not yet published or * they are still in transit. The limit does not apply to internal messages with the priority less than 2. * These priority levels are reserved to the framework which uses it for life-cycle messages * - birth and death certificates - and replies to request/response flows. * * @param deviceId * A String specifying the asset ID. * @param appTopic * A String specifying the application topic the message is published on. * @param payload * Binary payload representing the message to be published * @param qos * An integer specifying the quality of service the message was published on. * @param retain * Whether or not the broker should retain the message * @param priority * Relative ordering of this message with other messages that may be currently queued for publishing. * @return The published message's ID. */ public int controlPublish(String deviceId, String appTopic, byte[] payload, int qos, boolean retain, int priority) throws KuraException; /** * Subscribes to a topic with the remote server. The topic is specified as a String * object and the QoS is specified as an integer. The CloudClient will manipulate the * provided topic by appending the necessary parts to achieve topic partitioning and * device identification.<br> * This is a synchronous call. If the subscribe fails, an exception will be thrown * that will contain information about the cause of the failure. * * @param appTopic * A String object containing the application topic. * @param qos * An int containing the Quality of Service. */ public void subscribe(String appTopic, int qos) throws KuraException; /** * Subscribes to a control topic with the remote server. The topic is specified as a String * object and the QoS is specified as an integer. The CloudClient will manipulate the * provided topic by appending the necessary parts to achieve topic partitioning and * including control prefix and device identification.<br> * This is a synchronous call. If the subscribe fails, an exception will be thrown * that will contain information about the cause of the failure. * * @param appTopic * A String object containing the application topic. * @param qos * An int containing the Quality of Service. */ public void controlSubscribe(String appTopic, int qos) throws KuraException; /** * Unubscribes to a topic with the remote server. The topic is specified as a String * object and the QoS is specified as an integer. The CloudClient will manipulate the * provided topic by appending the necessary parts to achieve topic partitioning and * device identification.<br> * This is a synchronous call. If the unsubscribe fails, an exception will be thrown * that will contain information about the cause of the failure. * * @param appTopic * A String object containing the application topic. */ public void unsubscribe(String appTopic) throws KuraException; /** * Unsubscribes to a control topic with the remote server. The topic is specified as a String * object and the QoS is specified as an integer. The CloudClient will manipulate the * provided topic by appending the necessary parts to achieve topic partitioning and * including control prefix and device identification.<br> * This is a synchronous call. If the unsubscribe fails, an exception will be thrown * that will contain information about the cause of the failure. * * @param appTopic * A String object containing the application topic. */ public void controlUnsubscribe(String appTopic) throws KuraException; /** * Adds a CloudCallbackHandler with this CloudClient. This handler * will receive events when a client publication has arrived, and * when a publish has been fully acknowledged by the remote server. * * @param cloudClientListener * An implementation of the CloudCallbackHandler interface. */ public void addCloudClientListener(CloudClientListener cloudClientListener); /** * Removes a CloudCallbackHandler from this CloudClient. * The provided CloudCallbackHandler will no longer receive the events * when a published message is received. */ public void removeCloudClientListener(CloudClientListener cloudClientListener); /** * Gets the list of identifiers of messages that have not been published yet. * * @return * @throws KuraException */ List<Integer> getUnpublishedMessageIds() throws KuraException; /** * Finds the list of identifiers of messages that are still in-flight * (messages published but not confirmed yet). * This only applies to messages published with QoS > 0. * * @return * @throws KuraException */ List<Integer> getInFlightMessageIds() throws KuraException; /** * Finds the list of identifiers of in-flight messages that have been dropped. * This only applies to messages published with QoS > 0. * On the establishment of a new connection, the service can be configured * either to republish or drop in-flight messages. * The former option can be used if service users tolerate publishing message * duplicates. * The latter option can be used it service users tolerate losing messages. * * @return * @throws KuraException */ List<Integer> getDroppedInFlightMessageIds() throws KuraException; }