Use parameters in StreamSubscriptionServiceImpl 00/98100/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 24 Oct 2021 11:31:39 +0000 (13:31 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 24 Oct 2021 12:05:00 +0000 (14:05 +0200)
We have proper definitions fo parameters pertaining to streams,
use them to tie things together.

JIRA: NETCONF-773
Change-Id: I26a2e346bb61e13ec3a8a9e39892cd0952186671
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/SubscribeToStreamUtil.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/AbstractQueryParams.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/NotificationListenerAdapter.java

index 9e31cfba3c9e088224dc7ed9ac80227d0f4b7cd8..e2d95d9fabd3d740af8a3b5ebfd90b56e658d4e8 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
 
 import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
 
 import java.net.URI;
 import java.time.Instant;
@@ -22,10 +23,14 @@ import java.util.Optional;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.UriInfo;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMNotificationService;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.FilterParameter;
+import org.opendaylight.restconf.nb.rfc8040.StartTimeParameter;
+import org.opendaylight.restconf.nb.rfc8040.StopTimeParameter;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
@@ -172,72 +177,74 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
                 .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
                 .appendOffset("+HH:MM", "Z").toFormatter();
 
-        private final Instant start;
-        private final Instant stop;
+        private final @NonNull Instant startTime;
+        private final Instant stopTime;
         private final String filter;
         private final boolean skipNotificationData;
 
-        private NotificationQueryParams(final Instant start, final Instant stop, final String filter,
+        private NotificationQueryParams(final Instant startTime, final Instant stopTime, final String filter,
                 final boolean skipNotificationData) {
-            this.start = start == null ? Instant.now() : start;
-            this.stop = stop;
+            this.startTime = requireNonNull(startTime);
+            this.stopTime = stopTime;
             this.filter = filter;
             this.skipNotificationData = skipNotificationData;
         }
 
         static NotificationQueryParams fromUriInfo(final UriInfo uriInfo) {
-            Instant start = null;
-            boolean startTimeUsed = false;
-            Instant stop = null;
-            boolean stopTimeUsed = false;
+            Instant startTime = null;
+            Instant stopTime = null;
             String filter = null;
-            boolean filterUsed = false;
-            boolean skipNotificationDataUsed = false;
             boolean skipNotificationData = false;
 
             for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
-                switch (entry.getKey()) {
-                    case "start-time":
-                        if (!startTimeUsed) {
-                            startTimeUsed = true;
-                            start = parseDateFromQueryParam(entry);
-                        } else {
+                final String paramName = entry.getKey();
+                final List<String> paramValues = entry.getValue();
+                if (paramName.equals(StartTimeParameter.uriName())) {
+                    switch (paramValues.size()) {
+                        case 0:
+                            break;
+                        case 1:
+                            startTime = parseDateFromQueryParam(paramValues.get(0));
+                            break;
+                        default:
                             throw new RestconfDocumentedException("Start-time parameter can be used only once.");
-                        }
-                        break;
-                    case "stop-time":
-                        if (!stopTimeUsed) {
-                            stopTimeUsed = true;
-                            stop = parseDateFromQueryParam(entry);
-                        } else {
+                    }
+                } else if (paramName.equals(StopTimeParameter.uriName())) {
+                    switch (paramValues.size()) {
+                        case 0:
+                            break;
+                        case 1:
+                            stopTime = parseDateFromQueryParam(paramValues.get(0));
+                            break;
+                        default:
                             throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
-                        }
-                        break;
-                    case "filter":
-                        if (!filterUsed) {
-                            filterUsed = true;
-                            filter = entry.getValue().iterator().next();
-                        }
-                        break;
-                    case "odl-skip-notification-data":
-                        if (!skipNotificationDataUsed) {
-                            skipNotificationDataUsed = true;
-                            skipNotificationData = Boolean.parseBoolean(entry.getValue().iterator().next());
-                        } else {
+                    }
+                } else if (paramName.equals(FilterParameter.uriName())) {
+                    if (!paramValues.isEmpty()) {
+                        // FIXME: use FilterParameter
+                        filter = paramValues.get(0);
+                    }
+                } else if (paramName.equals("odl-skip-notification-data")) {
+                    switch (paramValues.size()) {
+                        case 0:
+                            break;
+                        case 1:
+                            skipNotificationData = Boolean.parseBoolean(paramValues.get(0));
+                            break;
+                        default:
                             throw new RestconfDocumentedException(
-                                    "Odl-skip-notification-data parameter can be used only once.");
-                        }
-                        break;
-                    default:
-                        throw new RestconfDocumentedException(
-                                "Bad parameter used with notifications: " + entry.getKey());
+                                "Odl-skip-notification-data parameter can be used only once.");
+                    }
+                } else {
+                    throw new RestconfDocumentedException("Bad parameter used with notifications: " + paramName);
                 }
             }
-            if (!startTimeUsed && stopTimeUsed) {
+            if (startTime == null && stopTime != null) {
                 throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
             }
 
-            return new NotificationQueryParams(start, stop, filter, skipNotificationData);
+            return new NotificationQueryParams(startTime == null ? Instant.now() : startTime, stopTime, filter,
+                skipNotificationData);
         }
 
 
@@ -245,17 +252,15 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
          * Parse input of query parameters - start-time or stop-time - from {@link DateAndTime} format
          * to {@link Instant} format.
          *
-         * @param entry Start-time or stop-time as string in {@link DateAndTime} format.
+         * @param uriValue Start-time or stop-time as string in {@link DateAndTime} format.
          * @return Parsed {@link Instant} by entry.
          */
-        private static Instant parseDateFromQueryParam(final Entry<String, List<String>> entry) {
-            final DateAndTime event = new DateAndTime(entry.getValue().iterator().next());
-            final String value = event.getValue();
+        private static @NonNull Instant parseDateFromQueryParam(final String uriValue) {
             final TemporalAccessor accessor;
             try {
-                accessor = FORMATTER.parse(value);
-            } catch (final DateTimeParseException e) {
-                throw new RestconfDocumentedException("Cannot parse of value in date: " + value, e);
+                accessor = FORMATTER.parse(new DateAndTime(uriValue).getValue());
+            } catch (final DateTimeParseException | IllegalArgumentException e) {
+                throw new RestconfDocumentedException("Cannot parse of value in date: " + uriValue, e);
             }
             return Instant.from(accessor);
         }
@@ -265,8 +270,8 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
          *
          * @return start-time
          */
-        public @NonNull Instant getStart() {
-            return start;
+        public @NonNull Instant startTime() {
+            return startTime;
         }
 
         /**
@@ -274,8 +279,8 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
          *
          * @return stop-time
          */
-        public Optional<Instant> getStop() {
-            return Optional.ofNullable(stop);
+        public @Nullable Instant stopTime() {
+            return stopTime;
         }
 
         /**
@@ -283,8 +288,8 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
          *
          * @return filter
          */
-        public Optional<String> getFilter() {
-            return Optional.ofNullable(filter);
+        public @Nullable String filter() {
+            return filter;
         }
 
         /**
index d841061ea74521638093f37b62b3ad393a9ba513..e9ac883752a3fbf64d36c76c724e000405a372b9 100644 (file)
@@ -132,15 +132,15 @@ abstract class SubscribeToStreamUtil {
         final URI uri = prepareUriByStreamName(uriInfo, streamName);
         notificationListenerAdapter.listen(handlersHolder.getNotificationServiceHandler());
         notificationListenerAdapter.setQueryParams(
-                notificationQueryParams.getStart(),
-                notificationQueryParams.getStop().orElse(null),
-                notificationQueryParams.getFilter().orElse(null),
+                notificationQueryParams.startTime(),
+                notificationQueryParams.stopTime(),
+                notificationQueryParams.filter(),
                 false, notificationQueryParams.isSkipNotificationData());
         final DOMDataBroker dataBroker = handlersHolder.getDataBroker();
         notificationListenerAdapter.setCloseVars(dataBroker, handlersHolder.getSchemaHandler());
         final MapEntryNode mapToStreams = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(
                     notificationListenerAdapter.getSchemaPath().lastNodeIdentifier(),
-                    schemaContext.getNotifications(), notificationQueryParams.getStart(),
+                    schemaContext.getNotifications(), notificationQueryParams.startTime(),
                     notificationListenerAdapter.getOutputType(), uri);
 
         // FIXME: how does this correlate with the transaction notificationListenerAdapter.close() will do?
@@ -184,9 +184,9 @@ abstract class SubscribeToStreamUtil {
                 ErrorType.APPLICATION, ErrorTag.DATA_MISSING));
 
         listener.setQueryParams(
-                notificationQueryParams.getStart(),
-                notificationQueryParams.getStop().orElse(null),
-                notificationQueryParams.getFilter().orElse(null),
+                notificationQueryParams.startTime(),
+                notificationQueryParams.stopTime(),
+                notificationQueryParams.filter(),
                 false, notificationQueryParams.isSkipNotificationData());
 
         final DOMDataBroker dataBroker = handlersHolder.getDataBroker();
@@ -200,7 +200,7 @@ abstract class SubscribeToStreamUtil {
 
         final MapEntryNode mapToStreams =
             RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(listener.getPath(),
-                notificationQueryParams.getStart(), listener.getOutputType(), uri, schemaContext, serializedPath);
+                notificationQueryParams.startTime(), listener.getOutputType(), uri, schemaContext, serializedPath);
         final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
         writeDataToDS(writeTransaction, mapToStreams);
         submitData(writeTransaction);
index 9df8cb8e0c4d926a2c16134f44f621786bcd7281..ab644b406f9dc885b1c7abcbdf83a7d17a3d25ff 100644 (file)
@@ -48,30 +48,30 @@ abstract class AbstractQueryParams extends AbstractNotificationsData {
     }
 
     // FIXME: these should be final
-    private Instant start = null;
-    private Instant stop = null;
+    private Instant startTime = null;
+    private Instant stopTime = null;
     private String filter = null;
     private boolean leafNodesOnly = false;
     private boolean skipNotificationData = false;
 
     @VisibleForTesting
     public final Instant getStart() {
-        return start;
+        return startTime;
     }
 
     /**
      * Set query parameters for listener.
      *
-     * @param start         Start-time of getting notification.
-     * @param stop          Stop-time of getting notification.
+     * @param startTime     Start-time of getting notification.
+     * @param stopTime      Stop-time of getting notification.
      * @param filter        Indicates which subset of all possible events are of interest.
      * @param leafNodesOnly If TRUE, notifications will contain changes of leaf nodes only.
      */
     @SuppressWarnings("checkstyle:hiddenField")
-    public void setQueryParams(final Instant start, final Instant stop, final String filter,
+    public void setQueryParams(final Instant startTime, final Instant stopTime, final String filter,
             final boolean leafNodesOnly, final boolean skipNotificationData) {
-        this.start = requireNonNull(start);
-        this.stop = stop;
+        this.startTime = requireNonNull(startTime);
+        this.stopTime = stopTime;
         this.filter = filter;
         this.leafNodesOnly = leafNodesOnly;
         this.skipNotificationData = skipNotificationData;
@@ -97,20 +97,20 @@ abstract class AbstractQueryParams extends AbstractNotificationsData {
 
     @SuppressWarnings("checkstyle:IllegalCatch")
     <T extends BaseListenerInterface> boolean checkStartStop(final Instant now, final T listener) {
-        if (this.stop != null) {
-            if (this.start.compareTo(now) < 0 && this.stop.compareTo(now) > 0) {
+        if (stopTime != null) {
+            if (startTime.compareTo(now) < 0 && stopTime.compareTo(now) > 0) {
                 return true;
             }
-            if (this.stop.compareTo(now) < 0) {
+            if (stopTime.compareTo(now) < 0) {
                 try {
                     listener.close();
                 } catch (final Exception e) {
                     throw new RestconfDocumentedException("Problem with unregister listener." + e);
                 }
             }
-        } else if (this.start != null) {
-            if (this.start.compareTo(now) < 0) {
-                this.start = null;
+        } else if (startTime != null) {
+            if (startTime.compareTo(now) < 0) {
+                startTime = null;
                 return true;
             }
         } else {
@@ -125,8 +125,9 @@ abstract class AbstractQueryParams extends AbstractNotificationsData {
      * @param xml XML data of notification.
      */
     @SuppressWarnings("checkstyle:IllegalCatch")
+    // FIXME: this method is never called, have we lost functionality compared to bierman02?
     boolean checkFilter(final String xml) {
-        if (this.filter == null) {
+        if (filter == null) {
             return true;
         }
         try {
@@ -146,6 +147,6 @@ abstract class AbstractQueryParams extends AbstractNotificationsData {
         final Document docOfXml = DBF.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
         final XPath xPath = XPathFactory.newInstance().newXPath();
         // FIXME: BUG-7956: xPath.setNamespaceContext(nsContext);
-        return (boolean) xPath.compile(this.filter).evaluate(docOfXml, XPathConstants.BOOLEAN);
+        return (boolean) xPath.compile(filter).evaluate(docOfXml, XPathConstants.BOOLEAN);
     }
 }
index c7c0963d3ad62ec20bdf24e2539268dfc9941ee5..806ee31d47970175836729938f0b9a6c68114bd8 100644 (file)
@@ -80,9 +80,9 @@ public class NotificationListenerAdapter extends AbstractCommonSubscriber implem
     }
 
     @Override
-    public void setQueryParams(final Instant start, final Instant stop, final String filter,
+    public void setQueryParams(final Instant startTime, final Instant stopTime, final String filter,
                                final boolean leafNodesOnly, final boolean skipNotificationData) {
-        super.setQueryParams(start, stop, filter, leafNodesOnly, skipNotificationData);
+        super.setQueryParams(startTime, stopTime, filter, leafNodesOnly, skipNotificationData);
         try {
             this.formatter = getFormatter(filter);
         } catch (XPathExpressionException e) {