From fb6548c3932ba2d5f21d41d204ffa9233432c114 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 23 Aug 2021 16:02:10 +0200 Subject: [PATCH] Fix revisionless capabilities NetconfCapabilityMonitoringService seems to indicate it cannot work with modules without a revision due to modeling restrictions. This is not accurate, as we should be using empty string to represent an absent revision. JIRA: NETCONF-808 Change-Id: I2dbcdc0cc0bb7e6560a46986c8c06388b8cc23d6 Signed-off-by: Robert Varga --- .../NetconfCapabilityMonitoringService.java | 66 ++++++++----------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java b/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java index e48ccc8643..2c658a7518 100644 --- a/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java +++ b/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfCapabilityMonitoringService.java @@ -7,11 +7,11 @@ */ package org.opendaylight.netconf.impl.osgi; +import static com.google.common.base.Preconditions.checkState; import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_CANDIDATE_1_0; import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_URL_1_0; import com.google.common.base.Function; -import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; @@ -81,63 +81,54 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos } synchronized String getSchemaForModuleRevision(final String moduleName, final Optional revision) { - - Map revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName); - Preconditions.checkState(revisionMapRequest != null, + final Map revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName); + checkState(revisionMapRequest != null, "Capability for module %s not present, available modules : %s", moduleName, Collections2.transform(capabilities.values(), CAPABILITY_TO_URI)); - if (revision.isPresent()) { - String schema = revisionMapRequest.get(revision.get()); - - Preconditions.checkState(schema != null, - "Capability for module %s:%s not present, available revisions for module: %s", moduleName, - revision.get(), revisionMapRequest.keySet()); - + final String revToLookup = revision.orElse(""); + final String schema = revisionMapRequest.get(revToLookup); + if (schema != null) { + // Exact match found return schema; } - Preconditions.checkState(revisionMapRequest.size() == 1, + // We can recover only if the revision was not specified + checkState(revision.isEmpty(), + "Capability for module %s:%s not present, available revisions for module: %s", moduleName, + revToLookup, revisionMapRequest.keySet()); + + checkState(revisionMapRequest.size() == 1, "Expected 1 capability for module %s, available revisions : %s", moduleName, revisionMapRequest.keySet()); - //Only one revision is present, so return it + // Only one revision is present, so return it return revisionMapRequest.values().iterator().next(); } private void updateCapabilityToSchemaMap(final Set added, final Set removed) { for (final Capability cap : added) { - if (!isValidModuleCapability(cap)) { - continue; + if (isValidModuleCapability(cap)) { + mappedModulesToRevisionToSchema.computeIfAbsent(cap.getModuleName().get(), k -> new HashMap<>()) + .put(cap.getRevision().orElse(""), cap.getCapabilitySchema().get()); } - - final String currentModuleName = cap.getModuleName().get(); - Map revisionMap = - mappedModulesToRevisionToSchema.computeIfAbsent(currentModuleName, k -> new HashMap<>()); - - final String currentRevision = cap.getRevision().get(); - revisionMap.put(currentRevision, cap.getCapabilitySchema().get()); } for (final Capability cap : removed) { - if (!isValidModuleCapability(cap)) { - continue; - } - final Map revisionMap = mappedModulesToRevisionToSchema.get(cap.getModuleName().get()); - if (revisionMap != null) { - revisionMap.remove(cap.getRevision().get()); - if (revisionMap.isEmpty()) { - mappedModulesToRevisionToSchema.remove(cap.getModuleName().get()); + if (isValidModuleCapability(cap)) { + final Map revisionMap = mappedModulesToRevisionToSchema.get(cap.getModuleName().get()); + if (revisionMap != null) { + revisionMap.remove(cap.getRevision().get()); + if (revisionMap.isEmpty()) { + mappedModulesToRevisionToSchema.remove(cap.getModuleName().get()); + } } } } } private static boolean isValidModuleCapability(final Capability cap) { - return cap.getModuleName().isPresent() - && cap.getRevision().isPresent() - && cap.getCapabilitySchema().isPresent(); + return cap.getModuleName().isPresent() && cap.getCapabilitySchema().isPresent(); } - synchronized Capabilities getCapabilities() { return new CapabilitiesBuilder().setCapability(Lists.newArrayList(capabilities.keySet())).build(); } @@ -156,10 +147,9 @@ class NetconfCapabilityMonitoringService implements CapabilityListener, AutoClos private static Schemas transformSchemas(final Set caps) { final Map schemas = Maps.newHashMapWithExpectedSize(caps.size()); for (final Capability cap : caps) { - if (cap.getCapabilitySchema().isPresent()) { - Preconditions.checkState(isValidModuleCapability(cap)); - - final SchemaKey key = new SchemaKey(Yang.class, cap.getModuleName().get(), cap.getRevision().get()); + if (isValidModuleCapability(cap)) { + final SchemaKey key = new SchemaKey(Yang.class, cap.getModuleName().get(), + cap.getRevision().orElse("")); schemas.put(key, new SchemaBuilder() .withKey(key) .setNamespace(new Uri(cap.getModuleNamespace().get())) -- 2.36.6