Do not parse data change stream name 98/108798/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 1 Nov 2023 09:09:27 +0000 (10:09 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 1 Nov 2023 09:15:37 +0000 (10:15 +0100)
We have all the information we need available when the adapter is
created, hence we do not need to interpret the stream name.

JIRA: NETCONF-1102
Change-Id: I786fc980bd05a158879d6899898c01582a50c7a3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/SubscribeToStreamUtil.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/ListenerAdapter.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/ListenersBroker.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/ListenerAdapterTest.java

index 7bdb6b9e239308e03434bf2ecef6c81fa41afd35..9a7e97bd19d9c5eaca529f5e534a49477f488edb 100644 (file)
@@ -12,8 +12,6 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.Splitter;
 import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import javax.ws.rs.core.UriInfo;
 import org.eclipse.jdt.annotation.NonNull;
@@ -24,17 +22,13 @@ import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.NotificationQueryParams;
 import org.opendaylight.restconf.nb.rfc8040.URLConstants;
-import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
 import org.opendaylight.restconf.nb.rfc8040.monitoring.RestconfStateStreams;
 import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfStreamsSubscriptionServiceImpl.HandlersHolder;
-import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants;
-import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenerAdapter;
 import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.IdentifierCodec;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -163,24 +157,8 @@ public abstract class SubscribeToStreamUtil {
      */
     final URI subscribeToDataStream(final String identifier, final UriInfo uriInfo,
             final NotificationQueryParams notificationQueryParams, final HandlersHolder handlersHolder) {
-        final Map<String, String> mapOfValues = mapValuesFromUri(identifier);
-
-        final String datastoreParam = mapOfValues.get(RestconfStreamsConstants.DATASTORE_PARAM_NAME);
-        if (isNullOrEmpty(datastoreParam)) {
-            final String message = "Stream name does not contain datastore value (pattern /datastore=)";
-            LOG.debug(message);
-            throw new RestconfDocumentedException(message, ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
-        }
-
-        // FIXME: this is kept only for compatibility, we are not using this parameter
-        if (isNullOrEmpty(mapOfValues.get(RestconfStreamsConstants.SCOPE_PARAM_NAME))) {
-            final String message = "Stream name does not contain scope value (pattern /scope=)";
-            LOG.warn(message);
-            throw new RestconfDocumentedException(message, ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
-        }
-
-        final String streamName = ListenersBroker.createStreamNameFromUri(identifier);
-        final ListenerAdapter listener = listenersBroker.dataChangeListenerFor(streamName);
+        final var streamName = ListenersBroker.createStreamNameFromUri(identifier);
+        final var listener = listenersBroker.dataChangeListenerFor(streamName);
         if (listener == null) {
             throw new RestconfDocumentedException("No listener found for stream " + streamName,
                 ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
@@ -188,18 +166,18 @@ public abstract class SubscribeToStreamUtil {
 
         listener.setQueryParams(notificationQueryParams);
 
-        final DOMDataBroker dataBroker = handlersHolder.getDataBroker();
-        final DatabindProvider schemaHandler = handlersHolder.getDatabindProvider();
+        final var dataBroker = handlersHolder.getDataBroker();
+        final var schemaHandler = handlersHolder.getDatabindProvider();
         listener.setCloseVars(dataBroker, schemaHandler);
-        listener.listen(dataBroker, LogicalDatastoreType.valueOf(datastoreParam));
+        listener.listen(dataBroker);
 
-        final URI uri = prepareUriByStreamName(uriInfo, streamName);
-        final EffectiveModelContext schemaContext = schemaHandler.currentContext().modelContext();
-        final String serializedPath = IdentifierCodec.serialize(listener.getPath(), schemaContext);
+        final var uri = prepareUriByStreamName(uriInfo, streamName);
+        final var schemaContext = schemaHandler.currentContext().modelContext();
+        final var serializedPath = IdentifierCodec.serialize(listener.getPath(), schemaContext);
 
-        final MapEntryNode mapToStreams = RestconfStateStreams.dataChangeStreamEntry(listener.getPath(),
+        final var mapToStreams = RestconfStateStreams.dataChangeStreamEntry(listener.getPath(),
                 listener.getStart(), listener.getOutputType(), uri, schemaContext, serializedPath);
-        final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+        final var writeTransaction = dataBroker.newWriteOnlyTransaction();
         writeDataToDS(writeTransaction, mapToStreams);
         submitData(writeTransaction);
         return uri;
@@ -219,21 +197,4 @@ public abstract class SubscribeToStreamUtil {
             throw new RestconfDocumentedException("Problem while putting data to DS.", e);
         }
     }
-
-    /**
-     * Prepare map of URI parameter-values.
-     *
-     * @param identifier String identification of URI.
-     * @return Map od URI parameters and values.
-     */
-    private static Map<String, String> mapValuesFromUri(final String identifier) {
-        final var result = new HashMap<String, String>();
-        for (final String token : SLASH_SPLITTER.split(identifier)) {
-            final String[] paramToken = token.split("=");
-            if (paramToken.length == 2) {
-                result.put(paramToken[0], paramToken[1]);
-            }
-        }
-        return result;
-    }
 }
index b25cf1c37afa0daefa98873b3ef90d5150444801..ce3df2a2609e680fe5fdc127117f2b98d53f96ee 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
@@ -37,7 +38,8 @@ public class ListenerAdapter extends AbstractCommonSubscriber<Collection<DataTre
     private static final DataTreeCandidateFormatterFactory JSON_FORMATTER_FACTORY =
             JSONDataTreeCandidateFormatter.createFactory(JSONCodecFactorySupplier.RFC7951);
 
-    private final YangInstanceIdentifier path;
+    private final @NonNull LogicalDatastoreType datastore;
+    private final @NonNull YangInstanceIdentifier path;
 
     /**
      * Creates new {@link ListenerAdapter} listener specified by path and stream name and register for subscribing.
@@ -47,9 +49,10 @@ public class ListenerAdapter extends AbstractCommonSubscriber<Collection<DataTre
      * @param outputType Type of output on notification (JSON, XML).
      */
     @VisibleForTesting
-    public ListenerAdapter(final YangInstanceIdentifier path, final String streamName,
-            final NotificationOutputType outputType, final ListenersBroker listenersBroker) {
+    public ListenerAdapter(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
+            final String streamName, final NotificationOutputType outputType, final ListenersBroker listenersBroker) {
         super(streamName, outputType, getFormatterFactory(outputType), listenersBroker);
+        this.datastore = requireNonNull(datastore);
         this.path = requireNonNull(path);
     }
 
@@ -99,18 +102,16 @@ public class ListenerAdapter extends AbstractCommonSubscriber<Collection<DataTre
      * Register data change listener in DOM data broker and set it to listener on stream.
      *
      * @param domDataBroker data broker for register data change listener
-     * @param datastore     {@link LogicalDatastoreType}
      */
-    public final synchronized void listen(final DOMDataBroker domDataBroker, final LogicalDatastoreType datastore) {
+    public final synchronized void listen(final DOMDataBroker domDataBroker) {
         if (!isListening()) {
-            final DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
+            final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
             if (changeService == null) {
                 throw new UnsupportedOperationException("DOMDataBroker does not support the DOMDataTreeChangeService");
             }
 
             setRegistration(changeService.registerDataTreeChangeListener(
-                new DOMDataTreeIdentifier(datastore, getPath()), this));
+                new DOMDataTreeIdentifier(datastore, path), this));
         }
     }
 
index 84088d9612e48c5328d209e6d87ee1422f6d26a4..0e4295a39187c032ffe6bd8550d50a962696096c 100644 (file)
@@ -161,7 +161,7 @@ public final class ListenersBroker {
         final long stamp = dataChangeListenersLock.writeLock();
         try {
             return dataChangeListeners.computeIfAbsent(sb.toString(),
-                streamName -> new ListenerAdapter(path, streamName, outputType, this));
+                streamName -> new ListenerAdapter(datastore, path, streamName, outputType, this));
         } finally {
             dataChangeListenersLock.unlockWrite(stamp);
         }
index f706b32240c015013b33790066635dc4127448b6..f2b16dd6c78d7cbe9854fcdfb8cf13636925a1aa 100644 (file)
@@ -180,7 +180,7 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
                 final NotificationOutputType outputType, final boolean leafNodesOnly,
                 final boolean skipNotificationData, final boolean changedLeafNodesOnly, final boolean childNodesOnly,
                 final ListenersBroker listenersBroker) {
-            super(path, streamName, outputType, listenersBroker);
+            super(LogicalDatastoreType.CONFIGURATION, path, streamName, outputType, listenersBroker);
             setQueryParams(NotificationQueryParams.of(StartTimeParam.forUriValue("1970-01-01T00:00:00Z"), null, null,
                 leafNodesOnly ? LeafNodesOnlyParam.of(true) : null,
                 skipNotificationData ? SkipNotificationDataParam.of(true) : null,
@@ -240,14 +240,12 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
             true, false, false, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
-        final DOMDataTreeIdentifier root =
-                new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
+        final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
 
         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-        final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
+        final var iid = InstanceIdentifier.create(PatchCont.class);
         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
             .addAugmentation(new PatchCont1Builder()
                 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceLeaf").build())
@@ -281,14 +279,12 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
                 false, false, true, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
-        final DOMDataTreeIdentifier root =
-                new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
+        final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
 
         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-        final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
+        final var iid = InstanceIdentifier.create(PatchCont.class);
         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
             .addAugmentation(new PatchCont1Builder()
                 .setPatchChoice2(new PatchCase11Builder()
@@ -330,8 +326,7 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
             NotificationOutputType.JSON, false, false, false, true, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final var changeService = domDataBroker.getExtensions()
-            .getInstance(DOMDataTreeChangeService.class);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
         final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
 
@@ -366,12 +361,11 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
             true, false, false, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
-        DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
+        final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-        final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
+        final var iid = InstanceIdentifier.create(PatchCont.class);
         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
             .addAugmentation(new PatchCont1Builder()
                 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceLeaf").build())
@@ -418,12 +412,11 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
                 false, false, true, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
-        DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
+        final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-        final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
+        final var iid = InstanceIdentifier.create(PatchCont.class);
         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
             .addAugmentation(new PatchCont1Builder()
                 .setPatchChoice2(new PatchCase11Builder()
@@ -478,8 +471,7 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
             NotificationOutputType.XML, false, false, false, true, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final var changeService = domDataBroker.getExtensions()
-            .getInstance(DOMDataTreeChangeService.class);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
         final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
         changeService.registerDataTreeChangeListener(root, adapter);
 
@@ -584,8 +576,7 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
                 NotificationOutputType.JSON, false, skipData, false, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final var changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
         final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, pathYiid);
         changeService.registerDataTreeChangeListener(root, adapter);
 
@@ -615,8 +606,7 @@ public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
                 false, skipData, false, false, listenersBroker);
         adapter.setCloseVars(domDataBroker, databindProvider);
 
-        final var changeService = domDataBroker.getExtensions()
-                .getInstance(DOMDataTreeChangeService.class);
+        final var changeService = domDataBroker.getExtensions().getInstance(DOMDataTreeChangeService.class);
         final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, pathYiid);
         changeService.registerDataTreeChangeListener(root, adapter);