diff --git a/java-client/src/main/java/com/cumulocity/sdk/client/notification/NotificationSubscriberProducer.java b/java-client/src/main/java/com/cumulocity/sdk/client/notification/NotificationSubscriberProducer.java index f94f409f1..676dada7c 100644 --- a/java-client/src/main/java/com/cumulocity/sdk/client/notification/NotificationSubscriberProducer.java +++ b/java-client/src/main/java/com/cumulocity/sdk/client/notification/NotificationSubscriberProducer.java @@ -1,15 +1,18 @@ package com.cumulocity.sdk.client.notification; -import java.util.HashMap; - -import org.apache.commons.lang3.tuple.ImmutablePair; +import java.util.Map; import com.cumulocity.model.idtype.GId; import com.cumulocity.sdk.client.PlatformParameters; +import com.cumulocity.rest.representation.AbstractExtensibleRepresentation; +import com.cumulocity.rest.representation.alarm.AlarmRepresentation; +import com.cumulocity.rest.representation.event.EventRepresentation; +import com.cumulocity.rest.representation.inventory.ManagedObjectRepresentation; +import com.cumulocity.rest.representation.measurement.MeasurementRepresentation; import com.cumulocity.rest.representation.notification.NotificationRepresentation; import com.cumulocity.rest.representation.notification.NotificationRepresentation.*; -import com.cumulocity.sdk.client.notification.Subscriber; -import com.cumulocity.sdk.client.notification.SubscriberBuilder; +import com.cumulocity.rest.representation.operation.OperationRepresentation; +import com.google.common.collect.ImmutableMap; /** * Utility class for creating {@linkplain Subscriber subscribers} to the real-time @@ -17,9 +20,8 @@ * * This class is used as follows (example): *
{@code
- * // 'parameters' object of type PlatformParameters must be provided
  * NotificationSubscriberProducer producer = new NotificationSubscriberProducer(parameters);
- * producer.getSubscriber(Endpoint.RealtimeNotifications, AlarmNotificationRepresentation.class)
+ * producer.getSubscriber(Endpoint.RealtimeNotifications, NotificationType.ALARM)
  * .subscribe(new GId("*"), new SubscriptionListener<>() { ... });
  * }
* @@ -35,6 +37,37 @@ */ public class NotificationSubscriberProducer { + /** + * This utility class has a constant for each domain model object type + * that supports notifications. These constants are used as inputs + * to some methods in the context of the enclosing class. + * + * @param the type of domain model object + * @param the type of notification object corresponding to + * the domain model object type + */ + // This could be an Enum, if JEP 301 (enhanced enums with sharper typing) was available. + public static final class NotificationType> { + public static final NotificationType + MANAGED_OBJECT = new NotificationType<>(ManagedObjectRepresentation.class, ManagedObjectNotificationRepresentation.class); + public static final NotificationType + MEASUREMENT = new NotificationType<>(MeasurementRepresentation.class, MeasurementNotificationRepresentation.class); + public static final NotificationType + EVENT = new NotificationType<>(EventRepresentation.class, EventNotificationRepresentation.class); + public static final NotificationType + ALARM = new NotificationType<>(AlarmRepresentation.class, AlarmNotificationRepresentation.class); + public static final NotificationType + OPERATION = new NotificationType<>(OperationRepresentation.class, OperationNotificationRepresentation.class); + + public final Class resourceRepresentation; + public final Class notificationRepresentation; + + private NotificationType(Class resourceRepresentation, Class notificationRepresentation) { + this.resourceRepresentation = resourceRepresentation; + this.notificationRepresentation = notificationRepresentation; + } + } + /** * Enumeration of the available real-time notification endpoints. *
    @@ -44,56 +77,46 @@ public class NotificationSubscriberProducer { */ public enum Endpoint { /** - * Generic real-time notification endpoint. + * Generic real-time notification endpoint “{@code notification/realtime}”. * This endpoint is usable for receiving notifications for any type of * domain model objects (Measurements, Events, etc.) that supports * real-time notifications. */ - RealtimeNotifications("notification/realtime"), + RealtimeNotifications("notification/realtime", + ImmutableMap.of( + NotificationType.MANAGED_OBJECT, "/managedobjects/", + NotificationType.MEASUREMENT, "/measurements/", + NotificationType.EVENT, "/events/", + NotificationType.ALARM, "/alarms/", + NotificationType.OPERATION, "/operations/")), + /** - * Special real-time notification endpoint for Operations. + * Real-time notification endpoint “{@code notification/operations}”. * Use this endpoint for receiving operations for Agents (i. e. * Managed Objects having a {@code com_cumulocity_model_Agent} fragment). * For receiving operations for regular Devices (having a {@code c8y_IsDevice} * fragment), use the {@link #RealtimeNotifications} endpoint instead. */ - OperationNotifications("notification/operations"); + OperationNotifications("notification/operations", + ImmutableMap.of(NotificationType.OPERATION, "/")); /** * The URL path of this endpoint. */ public final String path; - Endpoint(String path) { + /** + * This map provides the prefix of subscription channels (like {@code "/alarms/"}) + * for each supported data type. + */ + public final Map, String> supportedChannelPrefixes; + + Endpoint(String path, Map, String> prefixes) { this.path = path; + this.supportedChannelPrefixes = prefixes; } } - private static final HashMap< - ImmutablePair>>, - String /*subscriptionBase*/> - subscriptionBaseMap = new HashMap<>(); - static { - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.RealtimeNotifications, ManagedObjectNotificationRepresentation.class), - "/managedobjects/"); - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.RealtimeNotifications, MeasurementNotificationRepresentation.class), - "/measurements/"); - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.RealtimeNotifications, EventNotificationRepresentation.class), - "/events/"); - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.RealtimeNotifications, AlarmNotificationRepresentation.class), - "/alarms/"); - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.RealtimeNotifications, OperationNotificationRepresentation.class), - "/operations/"); - subscriptionBaseMap.put( - new ImmutablePair<>(Endpoint.OperationNotifications, OperationNotificationRepresentation.class), - "/"); - } - private final PlatformParameters parameters; /** @@ -107,7 +130,7 @@ public NotificationSubscriberProducer(PlatformParameters parameters) { } /** - * Create a {@link Subscriber} to the given endpoint for receiving real-time + * Creates a subscriber to the given endpoint for receiving real-time * notifications of the given data type. * * The data type depends on the type of domain model objects for which @@ -122,20 +145,20 @@ public NotificationSubscriberProducer(PlatformParameters parameters) { * * @param the desired data type as indicated by the {@code type} parameter * @param endpoint the desired real-time notification endpoint - * @param type the class of the desired data type + * @param type the desired type of notification * @return a subscriber with the specified configuration */ public > - Subscriber getSubscriber(Endpoint endpoint, Class type) { + Subscriber getSubscriber(Endpoint endpoint, NotificationType type) { - String subscriptionBase = subscriptionBaseMap.get(new ImmutablePair<>(endpoint, type)); - if (subscriptionBase == null) + String channelPrefix = endpoint.supportedChannelPrefixes.get(type); + if (channelPrefix == null) throw new IllegalArgumentException("Invalid combination of endpoint and type."); return new SubscriberBuilder() .withParameters(parameters) .withEndpoint(endpoint.path) - .withSubscriptionNameResolver(id -> subscriptionBase + id.getValue()) - .withDataType(type) + .withSubscriptionNameResolver(id -> channelPrefix + id.getValue()) + .withDataType(type.notificationRepresentation) .withMessageDeliveryAcknowlage(true) .build(); }