com.arm.mbed.cloud.sdk.connect.subscription.ResourceSubscriber Maven / Gradle / Ivy
package com.arm.mbed.cloud.sdk.connect.subscription;
import java.util.List;
import io.reactivex.BackpressureStrategy;
import io.reactivex.functions.Consumer;
import com.arm.mbed.cloud.sdk.annotations.Preamble;
import com.arm.mbed.cloud.sdk.common.AbstractModule;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.common.listing.FilterOptions;
import com.arm.mbed.cloud.sdk.common.listing.Paginator;
import com.arm.mbed.cloud.sdk.connect.adapters.PresubscriptionAdapter;
import com.arm.mbed.cloud.sdk.connect.model.Presubscription;
import com.arm.mbed.cloud.sdk.connect.model.Resource;
import com.arm.mbed.cloud.sdk.devicedirectory.adapters.DeviceAdapter;
import com.arm.mbed.cloud.sdk.devicedirectory.model.Device;
import com.arm.mbed.cloud.sdk.subscribe.model.AsynchronousResponseNotification;
import com.arm.mbed.cloud.sdk.subscribe.model.AsynchronousResponseObserver;
import com.arm.mbed.cloud.sdk.subscribe.model.FirstValue;
import com.arm.mbed.cloud.sdk.subscribe.model.SubscriptionFilterOptions;
@Preamble(description = "Object in charge of performing all necessary actions which need to take place when subscribing to a resource")
public class ResourceSubscriber extends AbstractSubscriptionAction {
public ResourceSubscriber(AbstractModule module, FirstValue mode) {
super(module, mode);
}
@Override
public void execute(FilterOptions arg) throws MbedCloudException {
if (!hasCloudConnection()) {
return;
}
final SubscriptionFilterOptions filters = (SubscriptionFilterOptions) arg;
// Setting pre-subscriptions
final List correspondingPresubscriptions = PresubscriptionAdapter.mapSubscriptionFilter(filters);
module.addSomePresubscriptions(correspondingPresubscriptions);
// Subscribe to currently connected devices
if (mode == FirstValue.ON_VALUE_UPDATE || mode == FirstValue.IMMEDIATELY) {
final Paginator iterator = module.listAllConnectedDevices(DeviceAdapter.mapSubscriptionOptions(filters));
while (iterator.hasNext()) {
final List resourcesToObserve = filters.getVerifiedResources(module.listObservableResources(iterator.next()));
module.addResourcesSubscription(resourcesToObserve);
if (mode == FirstValue.IMMEDIATELY) {
for (final Resource resourceToObserve : resourcesToObserve) {
requestCurrentResourceValue(resourceToObserve);
}
}
}
}
}
private void requestCurrentResourceValue(final Resource resourceToObserve) {
try {
final AsynchronousResponseObserver observer = module.createCurrentResourceValueObserver(resourceToObserve,
BackpressureStrategy.BUFFER);
observer.singleNotification(null).doOnError(new Consumer() {
@Override
public void accept(Throwable exception) throws Exception {
module.getLogger().logError("Could not fetch the current value of " + resourceToObserve, exception);
}
}).subscribe(new Consumer() {
@Override
public void accept(AsynchronousResponseNotification notification) throws Exception {
module.getLogger().logDebug("The following asynchronous response was received: " + notification);
observer.unsubscribe();
}
});
} catch (MbedCloudException exception) {
module.getLogger().logError("Could not fetch the current value of " + resourceToObserve, exception);
}
}
@Override
public ResourceSubscriber clone() {
return new ResourceSubscriber(module, mode);
}
}