Simplify OperationsContext with yangtools 7.0.9+ 89/103689/1
authorOleksandrZharov <Oleksandr.Zharov@pantheon.tech>
Wed, 14 Dec 2022 16:18:23 +0000 (17:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 15 Dec 2022 18:43:53 +0000 (19:43 +0100)
Simplified the logic in OperationsContent class with usage of
features available in yangtools 7.0.9.

Now we use EffectiveModelContext#findModuleStatements to find module
statements already sorted by revision.

JIRA: NETCONF-927
Change-Id: I5f0d3e310ac6cf499cb93c6e47e7142cf8653962
Signed-off-by: OleksandrZharov <Oleksandr.Zharov@pantheon.tech>
Signed-off-by: Ivan Hrasko <ivan.hrasko@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 45a89bde4d8159468a6a1211b78cb421aab5fbc4)

restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/OperationsContent.java

index 3dee0dc19980db30e0bdedb3ab0e39f92cc04d0e..725e3766d1116858a05a8d5e140ddeea64f66d32 100644 (file)
@@ -9,17 +9,11 @@ package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
 
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.collect.HashBasedTable;
-import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
@@ -107,46 +101,34 @@ enum OperationsContent {
      */
     public final @NonNull String bodyFor(final @Nullable EffectiveModelContext context) {
         if (context == null) {
+            // Defensive, return empty content
             return emptyBody;
         }
         final var modules = context.getModuleStatements();
         if (modules.isEmpty()) {
+            // No modules, return empty content
             return emptyBody;
         }
 
-        // Index into prefix -> revision -> module table
-        final var prefixRevModule = HashBasedTable.<String, Optional<Revision>, ModuleEffectiveStatement>create();
-        for (var module : modules.values()) {
-            prefixRevModule.put(prefix(module), module.localQNameModule().getRevision(), module);
-        }
-
-        // Now extract RPC names for each module with highest revision. This needed so we expose the right set of RPCs,
-        // as we always pick the latest revision to resolve prefix (or module name)
-        // TODO: Simplify this once we have yangtools-7.0.9+
-        final var moduleRpcs = new ArrayList<Entry<String, List<String>>>();
-        for (var moduleEntry : prefixRevModule.rowMap().entrySet()) {
-            final var revisions = new ArrayList<>(moduleEntry.getValue().keySet());
-            revisions.sort(Revision::compare);
-            final var selectedRevision = revisions.get(revisions.size() - 1);
-
-            final var rpcNames = moduleEntry.getValue().get(selectedRevision)
-                .streamEffectiveSubstatements(RpcEffectiveStatement.class)
+        final var moduleRpcs = modules.values().stream()
+            // Extract XMLNamespaces
+            .map(module -> module.localQNameModule().getNamespace())
+            // Make sure each is XMLNamespace unique
+            .distinct()
+            // Find the most recent module with that namespace. This needed so we expose the right set of RPCs,
+            // as we always pick the latest revision to resolve prefix (or module name).
+            .map(namespace -> context.findModuleStatements(namespace).iterator().next())
+            // Convert to module prefix + List<String> with RPC names
+            .map(module -> Map.entry(prefix(module), module.streamEffectiveSubstatements(RpcEffectiveStatement.class)
                 .map(rpc -> rpc.argument().getLocalName())
-                .collect(Collectors.toUnmodifiableList());
-            if (!rpcNames.isEmpty()) {
-                moduleRpcs.add(Map.entry(moduleEntry.getKey(), rpcNames));
-            }
-        }
-
-        if (moduleRpcs.isEmpty()) {
-            // No RPCs, return empty content
-            return emptyBody;
-        }
-
-        // Ensure stability: sort by prefix
-        moduleRpcs.sort(Comparator.comparing(Entry::getKey));
-
-        return modules.isEmpty() ? emptyBody : createBody(moduleRpcs);
+                .toList()))
+            // Skip prefixes which do not have any RPCs
+            .filter(entry -> !entry.getValue().isEmpty())
+            // Ensure stability: sort by prefix
+            .sorted(Entry.comparingByKey())
+            .toList();
+
+        return moduleRpcs.isEmpty() ? emptyBody : createBody(moduleRpcs);
     }
 
     abstract @NonNull String createBody(List<Entry<String, List<String>>> rpcsByPrefix);