Improve notificationStreamEntry() 80/107080/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 26 Jul 2023 12:03:15 +0000 (14:03 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 26 Jul 2023 14:41:19 +0000 (16:41 +0200)
Pass down EffectiveModelContext, so that we can locate the notification
more quickly.

Change-Id: I31ac32bae8267cb258ee3ca0dbccf5a3ccbb594d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/monitoring/RestconfStateStreams.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/SubscribeToStreamUtil.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/monitoring/RestconfStateStreamsTest.java

index 763adc1e349be69f13937649c8484b8f86d1bee9..f3de9f01e516b2920e160ed729b6b55b8fd355ff 100644 (file)
@@ -15,7 +15,6 @@ import java.time.Instant;
 import java.time.OffsetDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
-import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
@@ -35,7 +34,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNode
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 
 /**
@@ -74,52 +72,34 @@ public final class RestconfStateStreams {
     /**
      * Map data of yang notification to normalized node according to ietf-restconf-monitoring.
      *
+     * @param context the {@link EffectiveModelContext}
      * @param notifiQName qname of notification from listener
-     * @param notifications list of notifications for find schema of notification by notifiQName
      * @param start start-time query parameter of notification
      * @param outputType output type of notification
      * @param uri location of registered listener for sending data of notification
      * @return mapped data of notification - map entry node if parent exists,
      *         container streams with list and map entry node if not
      */
-    public static MapEntryNode notificationStreamEntry(final QName notifiQName,
-            final Collection<? extends NotificationDefinition> notifications, final Instant start,
-            final String outputType, final URI uri) {
-        for (final NotificationDefinition notificationDefinition : notifications) {
-            if (notificationDefinition.getQName().equals(notifiQName)) {
-                final String streamName = notifiQName.getLocalName();
-                final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
-                    Builders.mapEntryBuilder()
-                        .withNodeIdentifier(NodeIdentifierWithPredicates.of(Stream.QNAME, NAME_QNAME, streamName))
-                        .withChild(ImmutableNodes.leafNode(NAME_QNAME, streamName));
+    public static MapEntryNode notificationStreamEntry(final EffectiveModelContext context, final QName notifiQName,
+            final Instant start, final String outputType, final URI uri) {
+        final var notificationDefinition = context.findNotification(notifiQName)
+            .orElseThrow(() -> new RestconfDocumentedException(notifiQName + " not found"));
 
-                notificationDefinition.getDescription().ifPresent(
-                    desc -> streamEntry.withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, desc)));
-                streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_SUPPORT_QNAME, Boolean.TRUE));
-                if (start != null) {
-                    streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_LOG_CREATION_TIME,
-                        DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
-                            ZoneId.systemDefault()))));
-                }
+        final String streamName = notifiQName.getLocalName();
+        final var streamEntry = Builders.mapEntryBuilder()
+            .withNodeIdentifier(NodeIdentifierWithPredicates.of(Stream.QNAME, NAME_QNAME, streamName))
+            .withChild(ImmutableNodes.leafNode(NAME_QNAME, streamName));
 
-                return streamEntry
-                    .withChild(createAccessList(outputType, uri))
-                    .build();
-            }
+        notificationDefinition.getDescription().ifPresent(
+            desc -> streamEntry.withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, desc)));
+        streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_SUPPORT_QNAME, Boolean.TRUE));
+        if (start != null) {
+            streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_LOG_CREATION_TIME,
+                DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
+                    ZoneId.systemDefault()))));
         }
 
-        throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
-    }
-
-    private static MapNode createAccessList(final String outputType, final URI uriToWebsocketServer) {
-        return Builders.mapBuilder()
-            .withNodeIdentifier(new NodeIdentifier(Access.QNAME))
-            .withChild(Builders.mapEntryBuilder()
-                .withNodeIdentifier(NodeIdentifierWithPredicates.of(Access.QNAME, ENCODING_QNAME, outputType))
-                .withChild(ImmutableNodes.leafNode(ENCODING_QNAME, outputType))
-                .withChild(ImmutableNodes.leafNode(LOCATION_QNAME, uriToWebsocketServer.toString()))
-                .build())
-            .build();
+        return streamEntry.withChild(createAccessList(outputType, uri)).build();
     }
 
     /**
@@ -153,4 +133,15 @@ public final class RestconfStateStreams {
             .withChild(createAccessList(outputType, uri))
             .build();
     }
+
+    private static MapNode createAccessList(final String outputType, final URI uriToWebsocketServer) {
+        return Builders.mapBuilder()
+            .withNodeIdentifier(new NodeIdentifier(Access.QNAME))
+            .withChild(Builders.mapEntryBuilder()
+                .withNodeIdentifier(NodeIdentifierWithPredicates.of(Access.QNAME, ENCODING_QNAME, outputType))
+                .withChild(ImmutableNodes.leafNode(ENCODING_QNAME, outputType))
+                .withChild(ImmutableNodes.leafNode(LOCATION_QNAME, uriToWebsocketServer.toString()))
+                .build())
+            .build();
+    }
 }
index 02ea4a302e40b0c95d43ae9ed57bc049e18f19f7..d78e14482f6313940a28c8316dc528601bdc21df 100644 (file)
@@ -230,9 +230,8 @@ public class RestconfDataServiceImpl implements RestconfDataService {
     private void writeNotificationStreamToDatastore(final EffectiveModelContext schemaContext,
             final UriInfo uriInfo, final DOMDataTreeWriteOperations tx, final NotificationListenerAdapter listener) {
         final URI uri = streamUtils.prepareUriByStreamName(uriInfo, listener.getStreamName());
-        final MapEntryNode mapToStreams = RestconfStateStreams.notificationStreamEntry(
-                listener.getSchemaPath().lastNodeIdentifier(), schemaContext.getNotifications(), null,
-                listener.getOutputType(), uri);
+        final MapEntryNode mapToStreams = RestconfStateStreams.notificationStreamEntry(schemaContext,
+                listener.getSchemaPath().lastNodeIdentifier(), null, listener.getOutputType(), uri);
 
         tx.merge(LogicalDatastoreType.OPERATIONAL,
             RestconfStateStreams.restconfStateStreamPath(mapToStreams.name()), mapToStreams);
index 0dc24039f4bcf8f8d2b1c92b5f82679169ed1767..3c2de9aa41e62b7436ed700807d75614aede6edd 100644 (file)
@@ -136,10 +136,9 @@ abstract class SubscribeToStreamUtil {
         notificationListenerAdapter.listen(handlersHolder.getNotificationServiceHandler());
         final DOMDataBroker dataBroker = handlersHolder.getDataBroker();
         notificationListenerAdapter.setCloseVars(dataBroker, handlersHolder.getDatabindProvider());
-        final MapEntryNode mapToStreams = RestconfStateStreams.notificationStreamEntry(
-                    notificationListenerAdapter.getSchemaPath().lastNodeIdentifier(),
-                    schemaContext.getNotifications(), notificationListenerAdapter.getStart(),
-                    notificationListenerAdapter.getOutputType(), uri);
+        final MapEntryNode mapToStreams = RestconfStateStreams.notificationStreamEntry(schemaContext,
+            notificationListenerAdapter.getSchemaPath().lastNodeIdentifier(), notificationListenerAdapter.getStart(),
+            notificationListenerAdapter.getOutputType(), uri);
 
         // FIXME: how does this correlate with the transaction notificationListenerAdapter.close() will do?
         final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
index c0f4d3eecd4ccc22baa33f5c35bdfc0b2eb0fdf4..f26f40e853be9a0d34f013c0b72294345ad76be2 100644 (file)
@@ -100,9 +100,8 @@ public class RestconfStateStreamsTest {
         final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
         map.put(RestconfStateStreams.DESCRIPTION_QNAME, "Notifi");
 
-        final QName notifiQName = QName.create("urn:nested:module", "2014-06-03", "notifi");
-        final MapEntryNode mappedData = RestconfStateStreams.notificationStreamEntry(notifiQName,
-            schemaContextMonitoring.getNotifications(), start, outputType, uri);
+        final MapEntryNode mappedData = RestconfStateStreams.notificationStreamEntry(schemaContextMonitoring,
+            QName.create("urn:nested:module", "2014-06-03", "notifi"), start, outputType, uri);
         assertMappedData(map, mappedData);
     }