All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arm.mbed.cloud.sdk.Connect Maven / Gradle / Ivy

package com.arm.mbed.cloud.sdk;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicReference;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.functions.Function;

import com.arm.mbed.cloud.sdk.annotations.API;
import com.arm.mbed.cloud.sdk.annotations.Daemon;
import com.arm.mbed.cloud.sdk.annotations.DefaultValue;
import com.arm.mbed.cloud.sdk.annotations.Internal;
import com.arm.mbed.cloud.sdk.annotations.Module;
import com.arm.mbed.cloud.sdk.annotations.NonNull;
import com.arm.mbed.cloud.sdk.annotations.Nullable;
import com.arm.mbed.cloud.sdk.annotations.Preamble;
import com.arm.mbed.cloud.sdk.common.AbstractModule;
import com.arm.mbed.cloud.sdk.common.ApiUtils;
import com.arm.mbed.cloud.sdk.common.Callback;
import com.arm.mbed.cloud.sdk.common.CloudCaller;
import com.arm.mbed.cloud.sdk.common.CloudRequest.CloudCall;
import com.arm.mbed.cloud.sdk.common.ConnectionOptions;
import com.arm.mbed.cloud.sdk.common.DeliveryMethod;
import com.arm.mbed.cloud.sdk.common.GenericAdapter;
import com.arm.mbed.cloud.sdk.common.GenericAdapter.Mapper;
import com.arm.mbed.cloud.sdk.common.JsonSerialiser;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.common.SdkContext;
import com.arm.mbed.cloud.sdk.common.SynchronousMethod;
import com.arm.mbed.cloud.sdk.common.SynchronousMethod.AsynchronousMethod;
import com.arm.mbed.cloud.sdk.common.TimePeriod;
import com.arm.mbed.cloud.sdk.common.TranslationUtils;
import com.arm.mbed.cloud.sdk.common.UuidGenerator;
import com.arm.mbed.cloud.sdk.common.listing.ListOptions;
import com.arm.mbed.cloud.sdk.common.listing.ListResponse;
import com.arm.mbed.cloud.sdk.common.listing.PageRequester;
import com.arm.mbed.cloud.sdk.common.listing.Paginator;
import com.arm.mbed.cloud.sdk.common.listing.filtering.Filter;
import com.arm.mbed.cloud.sdk.common.listing.filtering.FilterOperator;
import com.arm.mbed.cloud.sdk.connect.adapters.MetricAdapter;
import com.arm.mbed.cloud.sdk.connect.adapters.PresubscriptionAdapter;
import com.arm.mbed.cloud.sdk.connect.adapters.ResourceAdapter;
import com.arm.mbed.cloud.sdk.connect.adapters.WebhookAdapter;
import com.arm.mbed.cloud.sdk.connect.model.AbstractMetricsListOptions;
import com.arm.mbed.cloud.sdk.connect.model.EndPoints;
import com.arm.mbed.cloud.sdk.connect.model.Metric;
import com.arm.mbed.cloud.sdk.connect.model.MetricsPeriodListOptions;
import com.arm.mbed.cloud.sdk.connect.model.MetricsStartEndListOptions;
import com.arm.mbed.cloud.sdk.connect.model.Presubscription;
import com.arm.mbed.cloud.sdk.connect.model.Resource;
import com.arm.mbed.cloud.sdk.connect.model.Subscription;
import com.arm.mbed.cloud.sdk.connect.model.Webhook;
import com.arm.mbed.cloud.sdk.connect.subscription.NotificationHandlersStore;
import com.arm.mbed.cloud.sdk.connect.subscription.ResourceAction;
import com.arm.mbed.cloud.sdk.connect.subscription.ResourceActionParameters;
import com.arm.mbed.cloud.sdk.connect.subscription.ResourceValueType;
import com.arm.mbed.cloud.sdk.connect.subscription.adapters.ResourceActionAdapter;
import com.arm.mbed.cloud.sdk.devicedirectory.adapters.DeviceAdapter;
import com.arm.mbed.cloud.sdk.devicedirectory.model.DeviceListOptions;
import com.arm.mbed.cloud.sdk.devicedirectory.model.DeviceState;
import com.arm.mbed.cloud.sdk.devices.model.Device;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListDao;
import com.arm.mbed.cloud.sdk.lowlevel.pelionclouddevicemanagement.model.DeviceRequest;
import com.arm.mbed.cloud.sdk.lowlevel.pelionclouddevicemanagement.model.NotificationMessage;
import com.arm.mbed.cloud.sdk.lowlevel.pelionclouddevicemanagement.model.PresubscriptionArray;
import com.arm.mbed.cloud.sdk.lowlevel.pelionclouddevicemanagement.model.SuccessfulResponse;
import com.arm.mbed.cloud.sdk.subscribe.CloudSubscriptionManager;
import com.arm.mbed.cloud.sdk.subscribe.NotificationMessageValue;
import com.arm.mbed.cloud.sdk.subscribe.Observer;
import com.arm.mbed.cloud.sdk.subscribe.model.AsynchronousResponseNotification;
import com.arm.mbed.cloud.sdk.subscribe.model.AsynchronousResponseObserver;

import retrofit2.Call;

@Preamble(description = "Specifies Connect API")
@Module
/**
 * API exposing functionality for doing a range of device related actions:
 * 

* 1) Listing connected devices *

* 2) Exploring and managing resources and resource values on said devices *

* 3) Setup resource subscriptions and webhooks for resource monitoring */ public class Connect extends AbstractModule { private static final String BUFFER = "BUFFER"; private static final String TAG_VALUE_TYPE = "valueType"; private static final String TAG_PRESUBSCRIPTION = "presubscription"; private static final String TAG_ON_NOTIFICATION_CALLBACK = "on notification callback"; private static final String TAG_WEBHOOK = "webhook"; private static final Filter CONNECTED_DEVICES_FILTER = new Filter("state", FilterOperator.EQUAL, DeviceState.getIsConnectedState().getString()); private static final String TAG_RESOURCE = "resource"; private static final String FALSE = "false"; private static final String TAG_RESOURCE_PATH = "resource path"; private static final String TAG_METRIC_OPTIONS = "Metric options"; private static final String TAG_DEVICE_ID = "Device Id"; private static final String TAG_DEVICE = "Device"; private final EndPoints endpoint; private final DeviceDirectory deviceDirectory; protected final NotificationHandlersStore handlersStore; protected final AtomicReference deliveryMethod; private final Object presubscriptionLock = new Object(); private final Object webhookLock = new Object(); @Internal protected Connect() { this(new ConnectionOptions()); } /** * Connect module constructor. *

* This module spawns threads for retrieving notifications when daemon is started @see * {@link #startNotifications()}. *

* By default, the executor services in charge are defined and managed internally. It is however possible to specify * your own executors @see #Connect(ConnectionOptions, ExecutorService, ExecutorService). * * @param options * connection options @see {@link ConnectionOptions}. */ public Connect(@NonNull ConnectionOptions options) { this(options, null, null); } /** * Constructor. * * @param context * SDK context */ public Connect(SdkContext context) { this(context == null ? null : context.getConnectionOption()); } /** * Connect module constructor. *

* As opposed to {@link #Connect(ConnectionOptions)} which uses default thread pools for retrieving notifications, * this constructor lets you the possibility to specify the executor services to use. * * @param options * connection options @see {@link ConnectionOptions}. * * @param notificationHandlingThreadPool * Threads in charge of retrieving notifications for a specific resource. If null, a default thread pool * will be created internally. * @param notificationPullingThreadPool * Threads in charge of listening to notifications. The pool can either be a scheduled thread pool or a * fixed thread pool depending on what best suits your system. If null, an internal timer will be created * internally. */ public Connect(@NonNull ConnectionOptions options, @Nullable ExecutorService notificationHandlingThreadPool, @Nullable ExecutorService notificationPullingThreadPool) { super(options); deliveryMethod = new AtomicReference(DeliveryMethod.UNDEFINED); endpoint = new EndPoints(this.serviceRegistry); deviceDirectory = new DeviceDirectory(options); deviceDirectory.shareNetworkLayer(this); this.handlersStore = new NotificationHandlersStore(this, (notificationPullingThreadPool == null) ? createDefaultDaemonThreadPool() : notificationPullingThreadPool, notificationHandlingThreadPool, endpoint); } @SuppressWarnings("resource") @Override public Connect clone() { return new Connect(this).setDeliveryMethod(deliveryMethod.get()); } /** * Creates a default thread pool in case none was specified. * * @return thread pool */ private static ScheduledExecutorService createDefaultDaemonThreadPool() { return Executors.newScheduledThreadPool(1, new ThreadFactory() { @Override public Thread newThread(Runnable runable) { final Thread thread = new Thread(runable); thread.setDaemon(true); return thread; } }); } /** * Starts notification pull. *

* If an external callback is not set up (using `update_webhook`) then calling this function is mandatory to get or * set resources. Unless {@link ConnectionOptions#setAutostartDaemon(boolean)} has been set to true or left as * default. * * @throws MbedCloudException * if a problem occurred during the process. */ @API @Daemon(task = "Listen to notification", start = true) public void startNotifications() throws MbedCloudException { logger.logInfo(getModuleName() + ": startNotifications()"); if (handlersStore.isPullingActive()) { logger.logInfo("Notification listening daemon thread is already started"); return; } setDeliveryMethod(true); checkConfiguration(getConnectionOption()); if (deliveryMethod.get() == DeliveryMethod.SERVER_INITIATED) { logger.throwSdkException("The SDK has been set up to use a server initiated delivery method. No daemon thread listening to notifications can be started in this mode."); } if (isForceClear()) { logger.logWarn("Clearing any existing notification channel"); clearAllNotificationChannels(); } // TODO use delivery method check instead when available Webhook webhook = null; try { webhook = getWebhook(); } catch (@SuppressWarnings("unused") MbedCloudException exception) { // Nothing to do } if (webhook != null) { logger.throwSdkException("A webhook is currently set up [" + webhook + "]. Client-initiated delivery method cannot be used at the same time. Please remove the webhook if you want to use this mechanism instead."); } handlersStore.startNotificationListener(); } protected void autostartDaemonIfNeeded() throws MbedCloudException { setDeliveryMethod(true); checkConfiguration(getConnectionOption()); if (deliveryMethod.get() != DeliveryMethod.CLIENT_INITIATED) { return; } if (!handlersStore.isPullingActive() && isAutostartDaemon()) { startNotifications(); } } /** * Stops notification pull for notifications. *

* * @throws MbedCloudException * if a problem occurred during the process. */ @API @Daemon(task = "Notification pull", stop = true) public void stopNotifications() throws MbedCloudException { logger.logInfo(getModuleName() + ": stopNotifications()"); if (deliveryMethod.get() == DeliveryMethod.CLIENT_INITIATED) { logger.logInfo("Delivery method was set to [" + deliveryMethod.get() + "]. Stopping daemon notification listening threads."); handlersStore.stopNotificationListener(); } if (isSkipCleanup()) { logger.logWarn("Notification channel and subscriptions are not cleaned up as skipCleanup mode was requested."); } else { clearAllNotificationChannels(); } } private void deleteLongPollingChannel() throws MbedCloudException { CloudCaller.call(this, "clearLongPollingNotificationChannel()", null, new CloudCall() { @Override public Call call() { return endpoint.getNotifications().deleteLongPollChannel(); } }); } /** * Shuts down all daemon services. */ @API @Daemon(task = "Notification pull", shutdown = true) public void shutdownConnectService() { logger.logInfo(getModuleName() + ": shutdownConnectService()"); handlersStore.shutdown(); } @Override @API public void close() { super.close(); try { stopNotifications(); } catch (@SuppressWarnings("unused") MbedCloudException exception) { // Nothing to do } shutdownConnectService(); } /** * Lists connected devices (One page). *

* * @deprecated Use {@link DeviceListDao} instead * @param options * filter options * @return the list of connected devices (One page). * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable ListResponse listConnectedDevices(DeviceListOptions options) throws MbedCloudException { return deviceDirectory.listDevicesWithExtraFilters("listConnectedDevices()", options, CONNECTED_DEVICES_FILTER); } /** * Gets an iterator over all connected devices according to filter options. *

* * @deprecated Use {@link DeviceListDao} instead * @param options * filter options. * @return paginator @see {@link Paginator} for the list of devices corresponding to filter options. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Paginator listAllConnectedDevices(@Nullable DeviceListOptions options) throws MbedCloudException { return new Paginator<>((options == null) ? new DeviceListOptions() : options, new PageRequester() { @Override public ListResponse requestNewPage(ListOptions opt) throws MbedCloudException { return listConnectedDevices((DeviceListOptions) opt); } }); } /** * Lists device's resources. *

* * @deprecated use {@link #listResources(Device)} instead. * @param device * Device. * @return list of resources present on a device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable List listResources(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device) throws MbedCloudException { return listResources(DeviceAdapter.mapToFoundation(device)); } /** * Lists device's resources. *

* * @param device * Device. * @return list of resources present on a device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable List listResources(@NonNull Device device) throws MbedCloudException { checkNotNull(device, TAG_DEVICE); checkNotNull(device.getId(), TAG_DEVICE_ID); final String finalDeviceId = device.getId(); return CloudCaller.call(this, "listResources()", ResourceAdapter.getListMapper(finalDeviceId), new CloudCall>() { @Override public Call> call() { return endpoint.getEndpoints().getEndpointResources(finalDeviceId); } }); } /** * Lists device's observable resources. * * @deprecated use {@link #listObservableResources(Device)} instead * @see Resource#isObservable() *

* * @param device * Device. * @return list of observable resources present on a device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable List listObservableResources(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device) throws MbedCloudException { return listObservableResources(DeviceAdapter.mapToFoundation(device)); } /** * Lists device's observable resources. * * @see Resource#isObservable() *

* * @param device * Device. * @return list of observable resources present on a device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable List listObservableResources(@NonNull Device device) throws MbedCloudException { final List resources = listResources(device); if (resources == null || resources.isEmpty()) { return null; } final List observableResources = new LinkedList<>(); for (final Resource resource : resources) { if (resource.isObservable()) { observableResources.add(resource); } } return observableResources.isEmpty() ? null : observableResources; } /** * Gets device's resource. *

* * @deprecated use {@link #getResource(Device, String)} instead. * * @param device * Device. * @param resourcePath * Path of the resource to get * @return resource present on the device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Resource getResource(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device, @NonNull String resourcePath) throws MbedCloudException { return getResource(DeviceAdapter.mapToFoundation(device), resourcePath); } /** * Gets device's resource. *

* * @param device * Device. * @param resourcePath * Path of the resource to get * @return resource present on the device. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Resource getResource(@NonNull Device device, @NonNull String resourcePath) throws MbedCloudException { checkNotNull(device, TAG_DEVICE); checkNotNull(device.getId(), TAG_DEVICE_ID); checkNotNull(resourcePath, TAG_RESOURCE_PATH); final List resources = listResources(device); if (resources == null || resources.isEmpty()) { return null; } for (final Resource resource : resources) { if (ApiUtils.comparePaths(resourcePath, resource.getPath())) { return resource; } } return null; } /** * Lists a device's subscriptions. *

* * @deprecated use {@link #listDeviceSubscriptions(Device)} instead. * @param device * Device. * @return list of subscriptions * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable List listDeviceSubscriptions(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device) throws MbedCloudException { return listDeviceSubscriptions(DeviceAdapter.mapToFoundation(device)); } /** * Lists a device's subscriptions. *

* * @param device * Device. * @return list of subscriptions * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable List listDeviceSubscriptions(@NonNull Device device) throws MbedCloudException { checkNotNull(device, TAG_DEVICE); checkNotNull(device.getId(), TAG_DEVICE_ID); final String finalDeviceId = device.getId(); return CloudCaller.call(this, "listDeviceSubscriptions()", PresubscriptionAdapter.getResourcePathListMapper(), new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions().getEndpointSubscriptions(finalDeviceId); } }); } /** * Gets the subscribe module. * * @return subscribe module. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public CloudSubscriptionManager subscribe() throws MbedCloudException { autostartDaemonIfNeeded(); return this.handlersStore.getSubscriptionManager(); } /** * Lists metrics. *

* * @param options * metrics options. * @param * Type of metrics list options * @return list of metrics for the corresponding options. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable ListResponse listMetrics(@NonNull T options) throws MbedCloudException { checkNotNull(options, TAG_METRIC_OPTIONS); final T finalOptions = options; final Date finalStart = options instanceof MetricsStartEndListOptions ? ((MetricsStartEndListOptions) options).getStart() : null; final Date finalEnd = options instanceof MetricsStartEndListOptions ? ((MetricsStartEndListOptions) options).getEnd() : null; final String finalPeriod = options instanceof MetricsPeriodListOptions ? ((MetricsPeriodListOptions) options).getPeriod() .toString() : null; return CloudCaller.call(this, "listMetrics()", MetricAdapter.getListMapper(), new CloudCall() { @Override public Call call() { return endpoint.getStatistic() .getMetrics(MetricAdapter.mapIncludes(finalOptions.getInclude()), finalOptions.getInterval().toString(), TranslationUtils.toLocalDate(finalStart), TranslationUtils.toLocalDate(finalEnd), finalPeriod, finalOptions.getPageSize(), finalOptions.getAfter(), finalOptions.getOrder().toString()); } }); } /** * Gets an iterator over all metrics according to filter options. *

* * @param options * filter options. * @param * Type of metrics list options * @return paginator @see {@link Paginator} for the list of metrics corresponding to filter options. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Paginator listAllMetrics(@NonNull T options) throws MbedCloudException { checkNotNull(options, TAG_METRIC_OPTIONS); return new Paginator<>(options, new PageRequester() { @SuppressWarnings("unchecked") @Override public ListResponse requestNewPage(ListOptions opt) throws MbedCloudException { return listMetrics((T) opt); } }); } /** * Creates a observer to obtain resource current value. *

* See {@link Observer} * * @param resource * resource of interest. * @param strategy * backpressure strategy. * @return corresponding observer. * @throws MbedCloudException * if a problem occurred during request processing. */ public @Nullable AsynchronousResponseObserver createCurrentResourceValueObserver(@NonNull Resource resource, @Nullable @DefaultValue(BUFFER) BackpressureStrategy strategy) throws MbedCloudException { return createResourceActionObserver(createResourceAction("getResourceValueAsync()", ResourceActionAdapter.getGetResourceValueMapper()), resource, strategy, null, null, true); } /** * Creates a observer to set a resource value. *

* See {@link Observer} * * @param resource * resource of interest. * @param strategy * backpressure strategy. * @param value * value to set. * @param valueType * type of the value to set. * @return corresponding observer. * @throws MbedCloudException * if a problem occurred during request processing. */ public @Nullable AsynchronousResponseObserver createSetResourceValueObserver(@NonNull Resource resource, @Nullable @DefaultValue(BUFFER) BackpressureStrategy strategy, @Nullable Object value, @NonNull ResourceValueType valueType) throws MbedCloudException { return createResourceActionObserver(createResourceAction("setResourceValueAsync()", ResourceActionAdapter.getSetResourceValueMapper()), resource, strategy, value, valueType, true); } /** * Creates a observer to execute a resource. *

* See {@link Observer} * * @param resource * resource of interest. * @param strategy * backpressure strategy. * @param value * value to set. * @param valueType * type of the value to set. * @return corresponding observer. * @throws MbedCloudException * if a problem occurred during request processing. */ public @Nullable AsynchronousResponseObserver createExecuteResourceValueObserver(@NonNull Resource resource, @Nullable @DefaultValue(BUFFER) BackpressureStrategy strategy, @Nullable Object value, @NonNull ResourceValueType valueType) throws MbedCloudException { return createResourceActionObserver(createResourceAction("executeResourceAsync()", ResourceActionAdapter.getExecuteResourceValueMapper()), resource, strategy, value, valueType, false); } @SuppressWarnings("resource") protected ResourceAction createResourceAction(String functionName, Mapper requestMapper) { final AbstractModule module = this; final String function = functionName; final Mapper finalMapper = requestMapper; return new ResourceAction() { @Override public void execute(ResourceActionParameters arg) throws MbedCloudException { final ResourceActionParameters finalArgs = arg; CloudCaller.call(module, function, null, new CloudCall() { @Override public Call call() { return endpoint.getAsync().createAsyncRequest(finalArgs.getResource().getDeviceId(), finalArgs.getAsyncId(), finalMapper.map(finalArgs)); } }); } }; } protected AsynchronousResponseObserver createResourceActionObserver(ResourceAction action, Resource resource, BackpressureStrategy strategy, Object value, ResourceValueType type, boolean notifyOtherObservers) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); autostartDaemonIfNeeded(); final ResourceActionParameters parameters = new ResourceActionParameters(UuidGenerator.generate(), resource, value, type); final BackpressureStrategy finalStrategy = (strategy == null) ? BackpressureStrategy.BUFFER : strategy; final AsynchronousResponseObserver observer = handlersStore.createAsyncResponseObserver(parameters.getResource(), parameters.getAsyncId(), finalStrategy, notifyOtherObservers); try { action.execute(parameters); } catch (MbedCloudException exception) { observer.unsubscribe(); throw exception; } return observer; } protected Future convertObserverToFuture(AsynchronousResponseObserver observer) throws MbedCloudException { try { final Flowable newFlow = observer.flow() .map(new Function() { @Override public Object apply(AsynchronousResponseNotification notification) throws Exception { if (notification.reportsFailure()) { return notification.toError(); } return notification.getPayload(); } }).take(1); return newFlow.toFuture(); } catch (Exception exception) { throw new MbedCloudException(exception); } } /** * Gets a resource value for a given device id and resource path. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Future futureLedPattern = connectApi.getResourceValueAsync(deviceId, resourcePath, false, false);
     *     String ledPattern = (String)futureLedPattern.get();
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param deviceId
     *            The name/id of the device.
     * @param resourcePath
     *            The resource path to get.
     * @param cacheOnly
     *            If true, the response will come only from the cache.
     * @param noResponse
     *            If true, Pelion Device Connector will not wait for a response.
     * @return A Future from which it is possible to obtain resource value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    @Deprecated
    public @Nullable Future
           getResourceValueAsync(@NonNull String deviceId, @NonNull String resourcePath,
                                 @DefaultValue(value = FALSE) boolean cacheOnly,
                                 @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        return getResourceValueAsync(deviceId, resourcePath);
    }

    /**
     * Gets a resource value for a given device id and resource path.
     * 

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Future futureLedPattern = connectApi.getResourceValueAsync(deviceId, resourcePath);
     *     String ledPattern = (String)futureLedPattern.get();
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param deviceId
     *            The name/id of the device.
     * @param resourcePath
     *            The resource path to get.
     * @return A Future from which it is possible to obtain resource value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public @Nullable Future getResourceValueAsync(@NonNull String deviceId,
                                                          @NonNull String resourcePath) throws MbedCloudException {
        checkNotNull(deviceId, TAG_DEVICE_ID);
        checkNotNull(resourcePath, TAG_RESOURCE_PATH);
        return getResourceValueAsync(new Resource(deviceId, resourcePath));
    }

    /**
     * Gets a resource value for a given device id and resource path.
     * 

* Example: * *

     * {@code
     * try {
     *     Device device = new Device();
     *     device.setId("015f4ac587f500000000000100100249");
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = connectApi.getResource(device, resourcePath);
    
     *     Future futureLedPattern = connectApi.getResourceValueAsync(resource, false, false);
     *     String ledPattern = (String)futureLedPattern.get();
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param resource
     *            The resource to get the value of.
     * @param cacheOnly
     *            If true, the response will come only from the cache.
     * @param noResponse
     *            If true, Pelion Device Connector will not wait for a response.
     * @return A Future from which it is possible to obtain resource value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    @Deprecated
    public @Nullable Future
           getResourceValueAsync(@NonNull Resource resource, @DefaultValue(value = FALSE) boolean cacheOnly,
                                 @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        return getResourceValueAsync(resource);

    }

    /**
     * Gets a resource value for a given device id and resource path.
     * 

* Example: * *

     * {@code
     * try {
     *     Device device = new Device();
     *     device.setId("015f4ac587f500000000000100100249");
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = connectApi.getResource(device, resourcePath);
    
     *     Future futureLedPattern = connectApi.getResourceValueAsync(resource);
     *     String ledPattern = (String)futureLedPattern.get();
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param resource
     *            The resource to get the value of.
     * @return A Future from which it is possible to obtain resource value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public @Nullable Future getResourceValueAsync(@NonNull Resource resource) throws MbedCloudException {
        checkNotNull(resource, TAG_RESOURCE);
        checkModelValidity(resource, TAG_RESOURCE);
        return convertObserverToFuture(createCurrentResourceValueObserver(resource, BackpressureStrategy.BUFFER));

    }

    /**
     * Gets a resource value for a given device id and resource path.
     * 

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String ledPattern = String.valueOf(connectApi.getResourceValue(deviceId, resourcePath, false, false, new TimePeriod(5)));
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param cacheOnly * If true, the response will come only from the cache. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return resource value. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Object getResourceValue(@NonNull String deviceId, @NonNull String resourcePath, @DefaultValue(value = FALSE) boolean cacheOnly, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return getResourceValue(deviceId, resourcePath, timeout); } /** * Gets a resource value for a given device id and resource path. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String ledPattern = String.valueOf(connectApi.getResourceValue(deviceId, resourcePath,  new TimePeriod(5)));
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param timeout * Timeout for the request. * @return resource value. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object getResourceValue(@NonNull String deviceId, @NonNull String resourcePath, @Nullable TimePeriod timeout) throws MbedCloudException { checkNotNull(deviceId, TAG_DEVICE_ID); checkNotNull(resourcePath, TAG_RESOURCE_PATH); return getResourceValue(new Resource(deviceId, resourcePath), timeout); } /** * Gets a resource value for a given device id and resource path. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String ledPattern = String.valueOf(connectApi.getResourceValue(resource, false, false, new TimePeriod(5)));
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * The resource to get the value of. * @param cacheOnly * If true, the response will come only from the cache. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return resource value. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Object getResourceValue(@NonNull Resource resource, @DefaultValue(value = FALSE) boolean cacheOnly, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return getResourceValue(resource, timeout); } /** * Gets a resource value for a given device id and resource path. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String ledPattern = String.valueOf(connectApi.getResourceValue(resource, new TimePeriod(5)));
     *     System.out.println("LED pattern from device: " + ledPattern);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * * @param resource * The resource path to get the value of. * @param timeout * Timeout for the request. * @return resource value. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object getResourceValue(@NonNull Resource resource, @Nullable TimePeriod timeout) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResource = resource; try { return SynchronousMethod.waitForCompletion(this, "getResourceValue()", new AsynchronousMethod() { @Override public Future submit() throws MbedCloudException { return getResourceValueAsync(finalResource); } }, timeout); } catch (MbedCloudException exception) { logger.throwSdkException(exception); } return null; } /** * Sets the value of a resource. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String resourceValue = "500:500:500";
     *
     *     Future futureLedPattern = connectApi.setResourceValueAsync(deviceId, resourcePath, resourceValue, false);
     *     String setValue = (String)futureLedPattern.get();
     *     assert setValue == resourceValue;
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param deviceId
     *            The name/id of the device.
     * @param resourcePath
     *            The resource path to get.
     * @param resourceValue
     *            value to set.
     * @param noResponse
     *            If true, Pelion Device Connector will not wait for a response.
     * @return A Future from which it is possible to set the value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    @Deprecated
    public @Nullable Future
           setResourceValueAsync(@NonNull String deviceId, @NonNull String resourcePath, @Nullable String resourceValue,
                                 @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        return setResourceValueAsync(deviceId, resourcePath, resourceValue, ResourceValueType.STRING);
    }

    /**
     * Sets the value of a resource.
     * 
     * @param deviceId
     *            The name/id of the device.
     * @param resourcePath
     *            The resource path to get.
     * @param resourceValue
     *            value to set.
     * @param valueType
     *            type of the value to set.
     * @return A Future from which it is possible to set the value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public @Nullable Future
           setResourceValueAsync(@NonNull String deviceId, @NonNull String resourcePath, @Nullable Object resourceValue,
                                 @NonNull ResourceValueType valueType) throws MbedCloudException {
        checkNotNull(deviceId, TAG_DEVICE_ID);
        checkNotNull(resourcePath, TAG_RESOURCE_PATH);
        return setResourceValueAsync(new Resource(deviceId, resourcePath), resourceValue, valueType);
    }

    /**
     * Sets the value of a resource.
     * 

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String resourceValue = "500:500:500";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     Future futureLedPattern = connectApi.setResourceValueAsync(resource, resourceValue, false);
     *     String setValue = (String)futureLedPattern.get();
     *     assert setValue == resourceValue;
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param resource
     *            The resource to set the value of.
     * @param resourceValue
     *            value to set.
     * @param noResponse
     *            If true, Pelion Cloud will not wait for a response.
     * 
     * @return A Future from which it is possible to set the value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @Deprecated
    @API
    public @Nullable Future
           setResourceValueAsync(@NonNull Resource resource, @Nullable String resourceValue,
                                 @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        return setResourceValueAsync(resource, resourceValue, ResourceValueType.STRING);
    }

    /**
     * Sets the value of a resource.
     * 
     * @param resource
     *            The resource to set the value of.
     * @param resourceValue
     *            value to set.
     * @param valueType
     *            type of the value to set.
     * @return A Future from which it is possible to set the value.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public @Nullable Future
           setResourceValueAsync(@NonNull Resource resource, @Nullable Object resourceValue,
                                 @NonNull ResourceValueType valueType) throws MbedCloudException {
        checkNotNull(resource, TAG_RESOURCE);
        checkModelValidity(resource, TAG_RESOURCE);
        checkNotNull(valueType, TAG_VALUE_TYPE);
        return convertObserverToFuture(createSetResourceValueObserver(resource, BackpressureStrategy.BUFFER,
                                                                      resourceValue, valueType));
    }

    /**
     * Sets the value of a resource.
     * 

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String resourceValue = "500:500:500";
     *
     *     Object resultObject = connectApi.setResourceValue(deviceId, resourcePath, resourceValue, false, new TimePeriod(5));
     *     String setValue = (String)resultObject;
     *     assert setValue == resourceValue;
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param resourceValue * value to set. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Object setResourceValue(@NonNull String deviceId, @NonNull String resourcePath, @Nullable String resourceValue, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return setResourceValue(deviceId, resourcePath, resourceValue, ResourceValueType.STRING, timeout); } /** * Sets the value of a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. * * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param resourceValue * value to set. * @param valueType * type of the value to set. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object setResourceValue(@NonNull String deviceId, @NonNull String resourcePath, @Nullable Object resourceValue, @NonNull ResourceValueType valueType, @Nullable TimePeriod timeout) throws MbedCloudException { checkNotNull(deviceId, TAG_DEVICE_ID); checkNotNull(resourcePath, TAG_RESOURCE_PATH); return setResourceValue(new Resource(deviceId, resourcePath), resourceValue, valueType, timeout); } /** * Sets the value of a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. * * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param resourceValue * value to set. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object setResourceValue(@NonNull String deviceId, @NonNull String resourcePath, @Nullable String resourceValue, @Nullable TimePeriod timeout) throws MbedCloudException { return setResourceValue(deviceId, resourcePath, resourceValue, ResourceValueType.STRING, timeout); } /** * Sets the value of a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String resourceValue = "500:500:500";
     *
     *     Object resultObject = connectApi.setResourceValue(resource, resourceValue, new TimePeriod(5));
     *     String setValue = (String)resultObject;
     *     assert setValue == resourceValue;
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * The resource to set the value of. * @param resourceValue * value to set. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @Deprecated @API public @Nullable Object setResourceValue(@NonNull Resource resource, @Nullable String resourceValue, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return setResourceValue(resource, resourceValue, ResourceValueType.STRING, timeout); } /** * Sets the value of a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. * * @param resource * The resource to set the value of. * @param resourceValue * value to set. * @param valueType * type of the value to set. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object setResourceValue(@NonNull Resource resource, @Nullable Object resourceValue, @NonNull ResourceValueType valueType, @Nullable TimePeriod timeout) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResouce = resource; final Object value = resourceValue; final ResourceValueType type = valueType; try { return SynchronousMethod.waitForCompletion(this, "setResourceValue()", new AsynchronousMethod() { @Override public Future submit() throws MbedCloudException { return setResourceValueAsync(finalResouce, value, type); } }, timeout); } catch (MbedCloudException exception) { logger.throwSdkException(exception); } return null; } /** * Sets the value of a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String resourceValue = "500:500:500";
     *
     *     Object resultObject = connectApi.setResourceValue(resource, resourceValue, new TimePeriod(5));
     *     String setValue = (String)resultObject;
     *     assert setValue == resourceValue;
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * The resource to set the value of. * @param resourceValue * value to set. * @param timeout * Timeout for the request. * @return The value of the new resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object setResourceValue(@NonNull Resource resource, @Nullable String resourceValue, @Nullable TimePeriod timeout) throws MbedCloudException { return setResourceValue(resource, resourceValue, ResourceValueType.STRING, timeout); } /** * Executes a function on a resource. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String functionName = null;
     *
     *     Future resultObject = connectApi.executeResourceAsync(deviceId, resourcePath, functionName, false);
     *     String resultValue = (String)resultObject.get();
     *     System.out.println("Result from the function executed: " + resultValue);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param deviceId
     *            The name/id of the device.
     * @param resourcePath
     *            The resource path to get.
     * @param functionName
     *            The function to trigger.
     * @param noResponse
     *            If true, Pelion Device Connector will not wait for a response.
     * @return A Future from which it is possible to get the value returned from the function executed on the resource.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @Deprecated
    @API
    public @Nullable Future
           executeResourceAsync(@NonNull String deviceId, @NonNull String resourcePath, @Nullable String functionName,
                                @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        checkNotNull(deviceId, TAG_DEVICE_ID);
        checkNotNull(resourcePath, TAG_RESOURCE_PATH);
        return executeResourceAsync(new Resource(deviceId, resourcePath), functionName);
    }

    /**
     * Executes a function on a resource.
     * 

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String functionName = null;
     *
     *     Future resultObject = connectApi.executeResourceAsync(resource, functionName, false);
     *     String resultValue = (String)resultObject.get();
     *     System.out.println("Result from the function executed: " + resultValue);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param resource
     *            The resource to execute the function on.
     * @param functionName
     *            The function to trigger.
     * @param noResponse
     *            If true, Pelion Device Connector will not wait for a response.
     * @return A Future from which it is possible to get the value returned from the function executed on the resource.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @Deprecated
    @API
    public @Nullable Future
           executeResourceAsync(@NonNull Resource resource, @Nullable String functionName,
                                @DefaultValue(value = FALSE) boolean noResponse) throws MbedCloudException {
        return executeResourceAsync(resource, functionName);
    }

    /**
     * Executes a function on a resource.
     * 
     * @param resource
     *            The resource to execute the function on.
     * @param functionName
     *            The function to trigger.
     * @return A Future from which it is possible to get the value returned from the function executed on the resource.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public @Nullable Future executeResourceAsync(@NonNull Resource resource,
                                                         @Nullable String functionName) throws MbedCloudException {
        checkNotNull(resource, TAG_RESOURCE);
        checkModelValidity(resource, TAG_RESOURCE);
        return convertObserverToFuture(createExecuteResourceValueObserver(resource, BackpressureStrategy.BUFFER,
                                                                          functionName, ResourceValueType.STRING));
    }

    /**
     * Executes a function on a resource.
     * 

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     String functionName = null;
     *
     *     Object resultObject = connectApi.executeResource(deviceId, resourcePath, functionName, false, new TimePeriod(5));
     *     System.out.println("Result from the function executed: " + (String)resultObject);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param deviceId * The name/id of the device. * @param resourcePath * The resource path to get. * @param functionName * The function to trigger. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return the value returned from the function executed on the resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @Deprecated @API public @Nullable Object executeResource(@NonNull String deviceId, @NonNull String resourcePath, @Nullable String functionName, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return executeResource(new Resource(deviceId, resourcePath), functionName, timeout); } /** * Executes a function on a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3201/0/5853";
     *     Resource resource = new Resource(deviceId, resourcePath);
     *     String functionName = null;
     *
     *     Object resultObject = connectApi.executeResource(resource, functionName, false, new TimePeriod(5));
     *     System.out.println("Result from the function executed: " + (String)resultObject);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * The resource path to execute the function on. * @param functionName * The function to trigger. * @param noResponse * If true, Pelion Device Connector will not wait for a response. * @param timeout * Timeout for the request. * @return the value returned from the function executed on the resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public @Nullable Object executeResource(@NonNull Resource resource, @Nullable String functionName, @DefaultValue(value = FALSE) boolean noResponse, @Nullable TimePeriod timeout) throws MbedCloudException { return executeResource(resource, functionName, timeout); } /** * Executes a function on a resource. *

* Note: Waits if necessary for the computation to complete, and then retrieves its result. * * @param resource * The resource path to execute the function on. * @param functionName * The function to trigger. * @param timeout * Timeout for the request. * @return the value returned from the function executed on the resource. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Object executeResource(@NonNull Resource resource, @Nullable String functionName, @Nullable TimePeriod timeout) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResource = resource; final String function = functionName; try { return SynchronousMethod.waitForCompletion(this, "executeResource()", new AsynchronousMethod() { @Override public Future submit() throws MbedCloudException { return executeResourceAsync(finalResource, function); } }, timeout); } catch (MbedCloudException exception) { logger.throwSdkException(exception); } return null; } protected GenericAdapter.MappedObjectRegistry getCurrentPresubscriptionRegistry(String methodName) throws MbedCloudException { return CloudCaller.call(this, methodName, PresubscriptionAdapter.getListToRegistryMapper(), new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions().getPreSubscriptions(); } }); } /** * Lists pre-subscription data. *

* Example: * *

     * {@code
     * try {
     *     List presubscriptions = connectApi.listPresubscriptions();
     *     for (Presubscription presub : presubscriptions) {
     *         System.out.println("Device (" + presub.getDeviceId() + ") has subscriptions to resources: ");
     *         for (String resource : presub.getResourcePaths()) {
     *             System.out.println(resource);
     *         }
     *     }
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @return the list of pre-subscription data. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable List listPresubscriptions() throws MbedCloudException { final GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("listPresubscriptions()"); return (presubscriptionRegistry == null) ? null : presubscriptionRegistry.getEntries(); } /** * Updates all pre-subscription data. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *
     *     Presubscription presub1 = new Presubscription();
     *     presub1.setDeviceType("default");
     *     List resourceList1 = Arrays.asList("/3201/0/5850", "/3201/0/5853");
     *     presub1.setResourcePaths(resourceList1);
     *
     *     Presubscription presub2 = new Presubscription();
     *     presub2.setDeviceId(deviceId);
     *     List resourceList2 = Arrays.asList("/3200/0/5501");
     *     presub2.setResourcePaths(resourceList2);
     *
     *     List presubscriptions = Arrays.asList(presub1, presub2);
     *     connectApi.updatePresubscriptions(presubscriptions);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param presubscriptions * The pre-subscription list to update. *

* If you send an empty/null array, the pre-subscription data will be removed @see * {@link #deletePresubscriptions()} for similar action. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void updatePresubscriptions(@Nullable List presubscriptions) throws MbedCloudException { final PresubscriptionArray array = PresubscriptionAdapter.reverseMapList(presubscriptions); synchronized (presubscriptionLock) { CloudCaller.call(this, "updatePresubscriptions()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions().updatePreSubscriptions(array); } }); } } /** * Adds a pre-subscription. *

* Note: for more information about pre-subscriptions, have a look at @link {@link Presubscription} or * corresponding Pelion Cloud * documentation * * @param presubscription * pre-subscription to add * @throws MbedCloudException * if an error happened during the process */ @API public void addPresubscription(@Nullable Presubscription presubscription) throws MbedCloudException { if (presubscription == null) { return; } checkModelValidity(presubscription, TAG_PRESUBSCRIPTION); synchronized (presubscriptionLock) { GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("addPresubscription()"); if (presubscriptionRegistry != null && presubscriptionRegistry.contains(presubscription)) { return; } if (presubscriptionRegistry == null) { presubscriptionRegistry = new GenericAdapter.MappedObjectRegistry<>(); } presubscriptionRegistry.addNewEnty(presubscription); updatePresubscriptions(presubscriptionRegistry.getEntries()); } } /** * Adds some pre-subscriptions. *

* Note: for more information about pre-subscriptions, have a look at @link {@link Presubscription} or * corresponding Pelion Cloud * documentation * * @param presubscriptions * pre-subscriptions to add * @throws MbedCloudException * if an error happened during the process */ @API public void addSomePresubscriptions(@Nullable List presubscriptions) throws MbedCloudException { if (presubscriptions == null) { return; } synchronized (presubscriptionLock) { GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("addSomePresubscriptions()"); if (presubscriptionRegistry == null) { presubscriptionRegistry = new GenericAdapter.MappedObjectRegistry<>(); } boolean requireAddition = false; for (final Presubscription presubscription : presubscriptions) { checkModelValidity(presubscription, TAG_PRESUBSCRIPTION); if (!presubscriptionRegistry.contains(presubscription)) { requireAddition = true; presubscriptionRegistry.addNewEnty(presubscription); } } if (requireAddition) { updatePresubscriptions(presubscriptionRegistry.getEntries()); } } } /** * Gets a pre-subscription. * * @param presubscriptionId * pre-subscription id * @return corresponding pre-subscription * @throws MbedCloudException * if a problem occurred during the process. */ @API public @Nullable Presubscription getPresubscription(@Nullable String presubscriptionId) throws MbedCloudException { if (presubscriptionId == null) { return null; } final GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("getPresubscription()"); return presubscriptionRegistry == null || presubscriptionRegistry.isEmpty() ? null : presubscriptionRegistry.getEntry(presubscriptionId); } /** * Deletes a pre-subscription. * * @param presubscriptionId * pre-subscription id of the pre-subscription to delete * @throws MbedCloudException * if a problem occurred during the process. */ @API public void deletePresubscription(@Nullable String presubscriptionId) throws MbedCloudException { if (presubscriptionId == null) { return; } synchronized (presubscriptionLock) { final GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("deletePresubscription()"); if (presubscriptionRegistry == null || presubscriptionRegistry.isEmpty() || !presubscriptionRegistry.contains(presubscriptionId)) { return; } presubscriptionRegistry.removeEntry(presubscriptionId); updatePresubscriptions(presubscriptionRegistry.getEntries()); } } /** * Deletes a pre-subscription. * * @param presubscription * pre-subscription to delete * @throws MbedCloudException * if a problem occurred during the process. */ @API public void deletePresubscription(@Nullable Presubscription presubscription) throws MbedCloudException { if (presubscription == null) { return; } deletePresubscription(presubscription.getId()); } /** * Deletes some pre-subscriptions. * * @param presubscriptions * pre-subscriptions to delete * @throws MbedCloudException * if a problem occurred during the process. */ @API public void deleteSomePresubscriptions(@Nullable List presubscriptions) throws MbedCloudException { if (presubscriptions == null) { return; } synchronized (presubscriptionLock) { final GenericAdapter.MappedObjectRegistry presubscriptionRegistry = getCurrentPresubscriptionRegistry("deleteSomePresubscriptions()"); if (presubscriptionRegistry == null || presubscriptionRegistry.isEmpty()) { return; } boolean requireDeletion = false; for (final Presubscription presubscription : presubscriptions) { if (presubscriptionRegistry.contains(presubscription.getId())) { requireDeletion = true; } presubscriptionRegistry.removeEntry(presubscription.getId()); } if (requireDeletion) { updatePresubscriptions(presubscriptionRegistry.getEntries()); } } } /** * Deletes all pre-subscription data. *

* Note: this method will deregister all subscription callbacks or observers if any. *

* Example: * *

     * {@code
     * try {
     *     connectApi.deletePresubscriptions();
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void deletePresubscriptions() throws MbedCloudException { CloudCaller.call(this, "deletePresubscriptions()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions().updatePreSubscriptions(PresubscriptionAdapter.reverseMapList(null)); } }); deregisterAllResourceSubscriptionObserversOrCallbacks(); } /** * Removes all subscriptions. *

* Note: this method will deregister all subscription callbacks or observers if any. *

* Warning: Please note that this operation is potentially really expensive and hence, use wisely. *

* It could be slow for large numbers of connected devices. If possible, explicitly delete subscriptions known to * have been created. * * * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void deleteSubscriptions() throws MbedCloudException { // The following is a workaround until there is a Pelion Cloud endpoint providing such an action. logger.logWarn("deleteSubscriptions() could be slow for large numbers of connected devices. " + "If possible, explicitly delete subscriptions known to have been created."); final Paginator connectedDevices = listAllConnectedDevices(null); if (connectedDevices != null) { for (final com.arm.mbed.cloud.sdk.devicedirectory.model.Device connectedDevice : connectedDevices) { deleteDeviceSubscriptions(connectedDevice); } } // When such an endpoint is created, use some code similar to below. // CloudCaller.call(this, "deleteSubscriptions()", null, new CloudCall() { // // @Override // public Call call() { // return endpoint.getSubscriptions().v2SubscriptionsDelete(); // } // }); // deregisterAllResourceSubscriptionObserversOrCallbacks(); } /** * Removes all subscriptions. *

* * @deprecated use {@link #deleteSubscriptions()} instead. * * * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public void deleteSubscribers() throws MbedCloudException { deleteSubscriptions(); } /** * Lists all subscriptions. *

* Warning: Please note that this operation is potentially really expensive and hence, use wisely. *

* It could be slow for large numbers of connected devices. *

* * @return list of subscriptions * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable List listSubscriptions() throws MbedCloudException { logger.logWarn("listSubscriptions() could be slow for large numbers of connected devices."); final List subscriptions = new LinkedList<>(); // The following is a workaround until there is a Pelion Cloud endpoint providing such an action. final Paginator connectedDevices = listAllConnectedDevices(null); if (connectedDevices != null) { for (final com.arm.mbed.cloud.sdk.devicedirectory.model.Device connectedDevice : connectedDevices) { final List deviceSubscriptions = listDeviceSubscriptions(connectedDevice); if (deviceSubscriptions != null) { subscriptions.add(new Subscription(connectedDevice.getId(), deviceSubscriptions)); } } } return subscriptions.isEmpty() ? null : subscriptions; } /** * Deletes a device's subscriptions. *

* Note: this method will deregister all subscription callbacks or observers for this device if any. *

* * @deprecated use {@link #deleteDeviceSubscriptions(Device)} instead. * * @param device * Device to consider. * @throws MbedCloudException * if a problem occurred during request processing. */ @API @Deprecated public void deleteDeviceSubscriptions(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device) throws MbedCloudException { deleteDeviceSubscriptions(DeviceAdapter.mapToFoundation(device)); } /** * Deletes a device's subscriptions. *

* Note: this method will deregister all subscription callbacks or observers for this device if any. *

* * @param device * Device to consider. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void deleteDeviceSubscriptions(@NonNull Device device) throws MbedCloudException { checkNotNull(device, TAG_DEVICE); checkNotNull(device.getId(), TAG_DEVICE_ID); final String finalDeviceId = device.getId(); CloudCaller.call(this, "deleteDeviceSubscriptions()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions().deleteEndpointSubscriptions(finalDeviceId); } }); deregisterAllResourceSubscriptionObserversOrCallbacks(device); } /** * Gets the status of a resource's subscription. *

* * @param resource * resource * @return true if resource is subscribed. false otherwise. * @throws MbedCloudException * if a parameter is incorrect * * */ @API public boolean getResourceSubscription(@NonNull Resource resource) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResource = resource; try { CloudCaller.call(this, "getResourceSubscription()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions() .checkResourceSubscription(finalResource.getDeviceId(), ApiUtils.normalisePath(finalResource.getPath())); } }, true); return true; } catch (@SuppressWarnings("unused") MbedCloudException exception) { return false; } } /** * Allows notifications (received from a Webhook) to be injected into the notifications system. * * @param data * The notification data to inject */ @API public void notify(@Nullable NotificationMessage data) { handlersStore.notify(data); } /** * Allows notifications expressed as a JSON string to be injected into the notifications system. *

* * @param dataAsJson * The notification data to inject as JSON String. */ @API public void notify(@Nullable String dataAsJson) { notify(null, dataAsJson); } /** * Allows a notification to be injected into the notifications system. *

* * @param deserialiser * JSON deserialiser to use. * @param dataAsJson * The notification data to inject as JSON String. */ @API public void notify(@Nullable JsonSerialiser deserialiser, @Nullable String dataAsJson) { final JsonSerialiser jsonEngine = (deserialiser == null) ? new JsonSerialiser() : deserialiser; notify(jsonEngine.fromJson(dataAsJson, NotificationMessage.class)); } /** * Subscribes to a list of resources. * * * @param resources * resources to subscribe to. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void addResourcesSubscription(@Nullable List resources) throws MbedCloudException { if (resources == null) { return; } for (final Resource resource : resources) { addResourceSubscription(resource); } } /** * Subscribes to a resource. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3200/0/5501";
     *     Resource buttonResource = new Resource(deviceId, resourcePath);
     *
     *     connectApi.addResourceSubscription(buttonResource);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * resource to subscribe to. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void addResourceSubscription(@NonNull Resource resource) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResource = resource; CloudCaller.call(this, "addResourceSubscription()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions() .addResourceSubscription(finalResource.getDeviceId(), ApiUtils.normalisePath(finalResource.getPath())); } }); } /** * Subscribes to a resource and associates callbacks. *

* Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3200/0/5501";
     *     Resource buttonResource = new Resource(deviceId, resourcePath);
     *     Callback callback = new Callback() {
     *
     *         @Override
     *         public void execute(Object arg) {
     *             System.out.println("Just received a notification from " + device.getId() + " regarding " + path
     *                     + ": " + String.valueOf(arg));
     *
     *         }
     *     };
     *     connectApi.addResourceSubscription(resource,callback, null);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
     *
     * @param resource
     *            resource to subscribe to.
     * @param onNotification
     *            callback to execute on notification.
     * @param onFailure
     *            callback to execute on error.
     * @throws MbedCloudException
     *             if a problem occurred during request processing.
     */
    @API
    public void addResourceSubscription(@NonNull Resource resource, @NonNull Callback onNotification,
                                        @Nullable Callback onFailure) throws MbedCloudException {
        registerResourceSubscriptionCallback(resource, onNotification, onFailure);
        addResourceSubscription(resource);
    }

    /**
     * Subscribes to a resource and creates a related observer.
     * 

* Note: for more information about observers @see Reactive X or * RxJava * *

* Example: * *

     * {
     * {@code String resourcePath = "/3200/0/5501";
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     Resource resource = new Resource(deviceId, path);
     *     connectApi.addResourceSubscription(resource, BackpressureStrategy.BUFFER)
     *                   .subscribe(System.out::println);
     * }
     * 
* * @param resource * resource to subscribe to. * @param strategy * backpressure strategy to apply @see {@link BackpressureStrategy} * @return Observable which can be subscribed to. @see {@link Flowable} * @throws MbedCloudException * if a problem occurred during request processing. */ @API public @Nullable Flowable addResourceSubscription(@NonNull Resource resource, @Nullable @DefaultValue(BUFFER) BackpressureStrategy strategy) throws MbedCloudException { try { final Flowable observer = createResourceSubscriptionObserver(resource, strategy); addResourceSubscription(resource); return observer; } catch (MbedCloudException exception) { handlersStore.removeResourceSubscriptionObserver(resource); throw exception; } } /** * Registers a subscription callback for a resource. *

* Example: * *

     * {
     * {@code String resourcePath = "/3200/0/5501";
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     Resource resource = new Resource(deviceId, path);
     *     Callback callback = new Callback() {
     *
     *         @Override
     *         public void execute(Object arg) {
     *             System.out.println("Just received a notification from " + device.getId() + " regarding " + path
     *                     + ": " + String.valueOf(arg));
     *
     *         }
     *     };
     *     connectApi.registerResourceSubscriptionCallback(resource, callback, null);
     *     connectApi.addResourceSubscription(resource);
     * }
     * 
     *
     * @param resource
     *            resource to register the callback for.
     * @param onNotification
     *            callback to execute on notification.
     * @param onFailure
     *            callback to execute on error.
     * @throws MbedCloudException
     *             if an error occurred in the process.
     */
    @API
    public void
           registerResourceSubscriptionCallback(@NonNull Resource resource, @NonNull Callback onNotification,
                                                @Nullable Callback onFailure) throws MbedCloudException {
        checkNotNull(resource, TAG_RESOURCE);
        checkModelValidity(resource, TAG_RESOURCE);
        checkNotNull(onNotification, TAG_ON_NOTIFICATION_CALLBACK);
        handlersStore.registerSubscriptionCallback(resource, onNotification, onFailure);
    }

    /**
     * Deregisters the subscription callback of a resource.
     * 

* Example: * *

     *
     * {
     *     @code
     *     String resourcePath = "/3200/0/5501";
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     Resource resource = new Resource(deviceId, path);
     *     connectApi.deregisterResourceSubscriptionCallback(resource);
     * }
     * 
* * @param resource * resource to consider. * @throws MbedCloudException * if an error occurred in the process. */ @API public void deregisterResourceSubscriptionCallback(@NonNull Resource resource) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); handlersStore.deregisterNotificationSubscriptionCallback(resource); } /** * Creates an observer for resource subscriptions. *

* Note: for more information about observers @see Reactive X or * RxJava * *

* Example: * *

     * {
     * {@code String resourcePath = "/3200/0/5501";
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     Resource resource = new Resource(deviceId, path);
     *     connectApi.createResourceSubscriptionObserver(resource, BackpressureStrategy.BUFFER)
     *                   .subscribe(System.out::println);
     *     connectApi.addResourceSubscription(resource);
     * }
     * 
* * @param resource * resource to subscribe to. * @param strategy * backpressure strategy to apply @see {@link BackpressureStrategy} * @return Observable which can be subscribed to. @see {@link Flowable} * @throws MbedCloudException * if an error occurred in the process. */ @API public @Nullable Flowable createResourceSubscriptionObserver(@NonNull Resource resource, @Nullable @DefaultValue(BUFFER) BackpressureStrategy strategy) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final BackpressureStrategy finalStrategy = (strategy == null) ? BackpressureStrategy.BUFFER : strategy; return handlersStore.createResourceSubscriptionObserver(resource, finalStrategy); } /** * Removes the subscription observer of a resource. *

* * @param resource * resource to consider. * @throws MbedCloudException * if an error occurred in the process. */ @API public void removeResourceSubscriptionObserver(@NonNull Resource resource) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); handlersStore.removeResourceSubscriptionObserver(resource); } /** * Deregisters all subscription observers or callbacks for a device. *

* * @deprecated use {@link #deregisterAllResourceSubscriptionObserversOrCallbacks()} * @param device * device to consider. * @throws MbedCloudException * if an error occurred in the process. */ @API @Deprecated public void deregisterAllResourceSubscriptionObserversOrCallbacks(@NonNull com.arm.mbed.cloud.sdk.devicedirectory.model.Device device) throws MbedCloudException { deregisterAllResourceSubscriptionObserversOrCallbacks(DeviceAdapter.mapToFoundation(device)); } /** * Deregisters all subscription observers or callbacks for a device. *

* * * @param device * device to consider. * @throws MbedCloudException * if an error occurred in the process. */ @API public void deregisterAllResourceSubscriptionObserversOrCallbacks(@NonNull Device device) throws MbedCloudException { checkNotNull(device, TAG_DEVICE); checkNotNull(device.getId(), TAG_DEVICE_ID); handlersStore.deregisterAllResourceSubscriptionObserversOrCallbacks(device.getId()); } /** * Deregisters all subscription observers or callbacks. *

* Example: * *

     *
     * {@code
     *     connectApi.deregisterAllResourceSubscriptionObserversOrCallbacks();
     * }
     * 
*/ @API public void deregisterAllResourceSubscriptionObserversOrCallbacks() { handlersStore.deregisterAllResourceSubscriptionObserversOrCallbacks(); } /** * Deletes a resource's subscription. *

* Note: this method will deregister all subscription callbacks or observers for this resource if any. *

* * Example: * *

     * {@code
     * try {
     *     String deviceId = "015f4ac587f500000000000100100249";
     *     String resourcePath = "/3200/0/5501";
     *     Resource buttonResource = new Resource(deviceId, resourcePath);
     *
     *     connectApi.deleteResourceSubscription(buttonResource);
     * } catch (MbedCloudException e) {
     *     e.printStackTrace();
     * }
     * }
     * 
* * @param resource * resource to subscribe to. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void deleteResourceSubscription(@NonNull Resource resource) throws MbedCloudException { checkNotNull(resource, TAG_RESOURCE); checkModelValidity(resource, TAG_RESOURCE); final Resource finalResource = resource; CloudCaller.call(this, "deleteResourceSubscription()", null, new CloudCall() { @Override public Call call() { return endpoint.getSubscriptions() .deleteResourceSubscription(finalResource.getDeviceId(), ApiUtils.normalisePath(finalResource.getPath())); } }); deregisterResourceSubscriptionCallback(finalResource); removeResourceSubscriptionObserver(finalResource); } /** * Gets the current callback URL if it exists. * * @return the webhook. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public Webhook getWebhook() throws MbedCloudException { return CloudCaller.call(this, "getWebhook()", WebhookAdapter.getMapper(), new CloudCall() { @Override public Call call() { return endpoint.getNotifications().getWebhook(); } }); } /** * Registers new webhook for incoming subscriptions. * * @param webhook * Webhook to set. * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void updateWebhook(@NonNull Webhook webhook) throws MbedCloudException { setDeliveryMethod(false); checkConfiguration(getConnectionOption()); if (deliveryMethod.get() == DeliveryMethod.CLIENT_INITIATED) { logger.throwSdkException("This SDK instance has been set up to use the client-initiated notification mode. The server-initiated notification mode that this method requires cannot be used at the same time."); } checkNotNull(webhook, TAG_WEBHOOK); checkModelValidity(webhook, TAG_WEBHOOK); synchronized (webhookLock) { try { final Webhook alreadySetupWebhook = getWebhook(); if (webhook.equals(alreadySetupWebhook)) { logger.logInfo("The webhook is alread set up: " + alreadySetupWebhook); return; } } catch (@SuppressWarnings("unused") MbedCloudException exception) { // Nothing to do } if (isForceClear()) { logger.logWarn("Clearing any existing notification channel"); clearAllNotificationChannels(); } final Webhook finalWebhook = webhook; CloudCaller.call(this, "updateWebhook()", null, new CloudCall() { @Override public Call call() { return endpoint.getNotifications().registerWebhook(WebhookAdapter.reverseMap(finalWebhook)); } }); } } /** * Deletes the callback data (effectively stopping Arm Pelion Cloud Connect from putting notifications). *

* If no webhook is registered, an exception (404) will be raised. *

* Note that every registered subscription will be deleted as part of deregistering a webhook. * * @throws MbedCloudException * if a problem occurred during request processing. */ @API public void deleteWebhook() throws MbedCloudException { CloudCaller.call(this, "deleteWebhook()", null, new CloudCall() { @Override public Call call() { return endpoint.getNotifications().deregisterWebhook(); } }); } /** * Deletes any notification channel currently in use. * */ @API public void clearAllNotificationChannels() { try { deleteWebhook(); } catch (MbedCloudException exception) { logger.logWarn("Clearing webhook", exception); } try { deleteLongPollingChannel(); } catch (MbedCloudException exception) { logger.logWarn("Clearing long polling channel", exception); } } /** * States whether any existing notification channel should be cleared before a new one is created. *

* Note: for more information, see {@link ConnectionOptions#isForceClear()} * * @return True if the channel will be cleared. False otherwise. */ public boolean isForceClear() { final ConnectionOptions config = getConnectionOption(); return config == null ? false : config.isForceClear(); } /** * States whether any existing notification channel and subscriptions will not be cleared on SDK exit. *

* Note: for more information, see {@link ConnectionOptions#isSkipCleanup()} * * @return True if the clean-up will be skipped. False otherwise. */ public boolean isSkipCleanup() { final ConnectionOptions config = getConnectionOption(); return config == null ? false : config.isSkipCleanup(); } /** * Sets whether any existing notification channel should be cleared before a new one is created. *

* Note: use {@link ConnectionOptions#setForceClear(boolean)} instead. * * @param isForceClear * force clear mode on. */ @Deprecated public void setForceClear(boolean isForceClear) { final ConnectionOptions config = getConnectionOption(); if (config == null) { return; } config.setForceClear(true); } /** * States whether notification daemon will start automatically when needed. *

* Note: to change this behaviour, use {@link ConnectionOptions#setAutostartDaemon(boolean)} when initialising this * API. * * @return true if daemon will be started automatically. False otherwise. */ public boolean isAutostartDaemon() { final ConnectionOptions config = getConnectionOption(); return config == null ? true : config.isAutostartDaemon(); } /** * Retrieves module name. * * @return module name. */ @Override public String getModuleName() { return "Connect"; } private void checkConfiguration(ConnectionOptions options) throws MbedCloudException { if (options == null) { return; } if (options.isAutostartDaemon() && deliveryMethod.get() == DeliveryMethod.SERVER_INITIATED) { logger.throwSdkException("The delivery method has been set to " + deliveryMethod.get() + ", which is not compatible with the autostartDaemon mode. This mode is only available for " + DeliveryMethod.CLIENT_INITIATED + " delivery method."); } } private Connect setDeliveryMethod(DeliveryMethod deliveryMethod2) { deliveryMethod.set(deliveryMethod2); return this; } private void setDeliveryMethod(boolean isClient) { if (deliveryMethod.get() == DeliveryMethod.UNDEFINED) { deliveryMethod.compareAndSet(DeliveryMethod.UNDEFINED, isClient ? DeliveryMethod.CLIENT_INITIATED : DeliveryMethod.SERVER_INITIATED); logger.logInfo("Setting notification delivery method to [" + deliveryMethod.get() + "]"); } } }