From 11d70e30dbd8a075b3f846b68ee9409c670a7965 Mon Sep 17 00:00:00 2001 From: Tomas Olvecky Date: Tue, 21 Jan 2014 15:26:39 +0100 Subject: [PATCH] Fix bug in hello message: module with more revisions. When yang store discovers new yang files, it should keep all modules provided by the parser. The old behavior was that only only one module instance was chosen. This change results in hello message containing all revisions of all modules. Change-Id: I5f580042303573fb4fd2d592846763d46bbb1d66 Signed-off-by: Tomas Olvecky --- .../yang/store/api/YangStoreSnapshot.java | 37 +++++- .../yang/store/impl/ExtenderYangTracker.java | 80 ------------- .../config/yang/store/impl/MbeParser.java | 64 ++++++---- .../yang/store/impl/YangStoreCache.java | 110 ++++++++++++++++++ .../store/impl/YangStoreSnapshotImpl.java | 52 +++++++-- .../ExtenderYangTrackerCustomizerTest.java | 5 +- .../osgi/NetconfOperationServiceImpl.java | 18 ++- .../netconf/impl/CapabilityProviderImpl.java | 7 +- .../netconf/impl/ConcurrentClientsTest.java | 1 - 9 files changed, 239 insertions(+), 135 deletions(-) create mode 100644 opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java diff --git a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java index da8b5e4ed1..b912b0c7af 100644 --- a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java +++ b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java @@ -7,21 +7,50 @@ */ package org.opendaylight.controller.config.yang.store.api; -import java.util.Map; -import java.util.Map.Entry; - import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; +import java.util.Map; +import java.util.Set; + public interface YangStoreSnapshot extends AutoCloseable { + /** + * @deprecated Use {@link #getQNamesToIdentitiesToModuleMXBeanEntries()} instead. This method return only one + * module representation even if multiple revisions are available. + */ + @Deprecated Map> getModuleMXBeanEntryMap(); - Map> getModuleMap(); + Map> getQNamesToIdentitiesToModuleMXBeanEntries(); + + /** + * Get number of parsed ModuleMXBeanEntry instances. + */ int countModuleMXBeanEntries(); + /** + * Get all modules discovered when this snapshot was created. + * @return all modules discovered. If one module exists with two different revisions, return both. + */ + Set getModules(); + + /** + * Get all modules together with their yang sources. + */ + Map getModulesToSources(); + + /** + * Retrieve source of module as it appeared during creation of this snapshot. + * @param module + * @return yang source of given module + * @throws java.lang.IllegalArgumentException if module does not belong to this snapshot + */ + String getModuleSource(Module module); + @Override void close(); } diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 0d704a8f6a..b5efc51d8b 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -14,12 +14,9 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; import org.opendaylight.controller.config.yang.store.api.YangStoreException; import org.opendaylight.controller.config.yang.store.api.YangStoreService; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; -import org.opendaylight.yangtools.yang.model.api.Module; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; @@ -36,8 +33,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -220,78 +215,3 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt cache.invalidate(); } } - -class YangStoreCache { - private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class); - - @GuardedBy("this") - private Set cachedUrls = null; - @GuardedBy("this") - private Optional cachedYangStoreSnapshot = getInitialSnapshot(); - @GuardedBy("this") - private Collection inconsistentURLsForReporting = Collections.emptySet(); - - synchronized Optional getSnapshotIfPossible(Multimap bundlesToYangURLs) { - Set urls = setFromMultimapValues(bundlesToYangURLs); - - if (cachedUrls==null || cachedUrls.equals(urls)) { - Preconditions.checkState(cachedYangStoreSnapshot.isPresent()); - YangStoreSnapshot freshSnapshot = new YangStoreSnapshotImpl(cachedYangStoreSnapshot.get()); - if (inconsistentURLsForReporting.size() > 0){ - logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting); - } - return Optional.of(freshSnapshot); - } - - return Optional.absent(); - } - - private static Set setFromMultimapValues( - Multimap bundlesToYangURLs) { - Set urls = Sets.newHashSet(bundlesToYangURLs.values()); - Preconditions.checkState(bundlesToYangURLs.size() == urls.size()); - return urls; - } - - synchronized void cacheYangStore(Multimap urls, - YangStoreSnapshot yangStoreSnapshot) { - this.cachedUrls = setFromMultimapValues(urls); - this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot); - } - - synchronized void invalidate() { - cachedUrls.clear(); - if (cachedYangStoreSnapshot.isPresent()){ - cachedYangStoreSnapshot.get().close(); - cachedYangStoreSnapshot = Optional.absent(); - } - } - - public synchronized void setInconsistentURLsForReporting(Collection urls){ - inconsistentURLsForReporting = urls; - } - - private Optional getInitialSnapshot() { - YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() { - @Override - public Map> getModuleMXBeanEntryMap() { - return Collections.emptyMap(); - } - - @Override - public Map> getModuleMap() { - return Collections.emptyMap(); - } - - @Override - public int countModuleMXBeanEntries() { - return 0; - } - - @Override - public void close() { - } - }; - return Optional.of(initialSnapshot); - } -} diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java index d54996dbb7..dd07c5a84f 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java @@ -21,25 +21,27 @@ import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public class MbeParser { + private static final Logger logger = LoggerFactory.getLogger(MbeParser.class); - public YangStoreSnapshotImpl parseYangFiles( - Collection allInput) - throws YangStoreException { + public YangStoreSnapshotImpl parseYangFiles(Collection allInput) throws YangStoreException { YangParserImpl parser = YangParserWrapper.getYangParserInstance(); Map allYangModules = YangParserWrapper.parseYangFiles(parser, allInput); SchemaContext resolveSchemaContext = YangParserWrapper.getSchemaContextFromModules(parser, allYangModules); - + logger.trace("Resolved modules:{}", resolveSchemaContext.getModules()); // JMX generator Map namespaceToPackageMapping = Maps.newHashMap(); @@ -69,35 +71,47 @@ public class MbeParser { } } - Map> retVal = Maps.newHashMap(); - Map> modulesMap = new HashMap<>(); + Map> moduleMXBeanEntryMap = Maps.newHashMap(); + Map modulesToSources = new HashMap<>(); + Map> + qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>(); + for (Entry moduleEntry : allYangModules.entrySet()) { - String packageName = packageTranslator.getPackageName(moduleEntry - .getValue()); + Module module = moduleEntry.getValue(); + String packageName = packageTranslator.getPackageName(module); TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper( new TypeProviderImpl(resolveSchemaContext)); - String yangAsString; - try { - moduleEntry.getKey().reset(); - yangAsString = IOUtils.toString(moduleEntry.getKey()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - modulesMap.put(moduleEntry.getValue().getName(), - Maps.immutableEntry(moduleEntry.getValue(), yangAsString)); - Map namesToMBEs = ModuleMXBeanEntry - .create(moduleEntry.getValue(), qNamesToSIEs, resolveSchemaContext, typeProviderWrapper, - packageName); - retVal.put(moduleEntry.getValue().getNamespace().toString(), - namesToMBEs); + String yangAsString = reReadInputStream(moduleEntry); + + QName qName = new QName(module.getNamespace(), module.getRevision(), module.getName()); + + Map namesToMBEs = + Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext, + typeProviderWrapper, packageName)); + moduleMXBeanEntryMap.put(module.getNamespace().toString(), namesToMBEs); + modulesToSources.put(module, yangAsString); + qNamesToIdentitiesToModuleMXBeanEntries.put(qName, namesToMBEs); } - return new YangStoreSnapshotImpl(retVal, modulesMap); + return new YangStoreSnapshotImpl(moduleMXBeanEntryMap, modulesToSources, qNamesToIdentitiesToModuleMXBeanEntries); + } + + private String reReadInputStream(Entry moduleEntry) { + String yangAsString; + try { + moduleEntry.getKey().reset(); + yangAsString = IOUtils.toString(moduleEntry.getKey()); + } catch (IOException e) { + throw new IllegalStateException("Cannot reread " + moduleEntry.getValue(), e); + } + return yangAsString; } - public Map parseYangFilesToString( - Collection allYangs) { + @Deprecated + public Map parseYangFilesToString(Collection allYangs) { + + logger.error("Using deprecated method that will be removed soon", new UnsupportedOperationException("Deprecated")); YangParserImpl parser = YangParserWrapper.getYangParserInstance(); Map allYangModules = parser diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java new file mode 100644 index 0000000000..321ce3af72 --- /dev/null +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java @@ -0,0 +1,110 @@ +package org.opendaylight.controller.config.yang.store.impl; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.concurrent.GuardedBy; +import java.net.URL; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +class YangStoreCache { + private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class); + + @GuardedBy("this") + private Set cachedUrls = null; + @GuardedBy("this") + private Optional cachedYangStoreSnapshot = getInitialSnapshot(); + @GuardedBy("this") + private Collection inconsistentURLsForReporting = Collections.emptySet(); + + synchronized Optional getSnapshotIfPossible(Multimap bundlesToYangURLs) { + Set urls = setFromMultimapValues(bundlesToYangURLs); + + if (cachedUrls==null || cachedUrls.equals(urls)) { + Preconditions.checkState(cachedYangStoreSnapshot.isPresent()); + YangStoreSnapshot freshSnapshot = YangStoreSnapshotImpl.copy(cachedYangStoreSnapshot.get()); + if (inconsistentURLsForReporting.size() > 0){ + logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting); + } + return Optional.of(freshSnapshot); + } + + return Optional.absent(); + } + + private static Set setFromMultimapValues( + Multimap bundlesToYangURLs) { + Set urls = Sets.newHashSet(bundlesToYangURLs.values()); + Preconditions.checkState(bundlesToYangURLs.size() == urls.size()); + return urls; + } + + synchronized void cacheYangStore(Multimap urls, + YangStoreSnapshot yangStoreSnapshot) { + this.cachedUrls = setFromMultimapValues(urls); + this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot); + } + + synchronized void invalidate() { + cachedUrls.clear(); + if (cachedYangStoreSnapshot.isPresent()){ + cachedYangStoreSnapshot.get().close(); + cachedYangStoreSnapshot = Optional.absent(); + } + } + + public synchronized void setInconsistentURLsForReporting(Collection urls){ + inconsistentURLsForReporting = urls; + } + + private Optional getInitialSnapshot() { + YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() { + @Override + public Map> getModuleMXBeanEntryMap() { + return Collections.emptyMap(); + } + + @Override + public Map> getQNamesToIdentitiesToModuleMXBeanEntries() { + return Collections.emptyMap(); + } + + @Override + public Set getModules() { + return Collections.emptySet(); + } + + @Override + public Map getModulesToSources() { + return Collections.emptyMap(); + } + + @Override + public String getModuleSource(Module module) { + throw new IllegalArgumentException("Cannot get sources in empty snapshot"); + } + + @Override + public int countModuleMXBeanEntries() { + return 0; + } + + @Override + public void close() { + } + }; + return Optional.of(initialSnapshot); + } +} diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java index ea709e1a45..474d754798 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java @@ -9,29 +9,39 @@ package org.opendaylight.controller.config.yang.store.impl; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.Map; -import java.util.Map.Entry; +import java.util.Set; public class YangStoreSnapshotImpl implements YangStoreSnapshot { + private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class); + @Deprecated private final Map> moduleMXBeanEntryMap; - private final Map> moduleMap; + private final Map modulesToSources; + private final Map> qNamesToIdentitiesToModuleMXBeanEntries; + + public YangStoreSnapshotImpl(Map> moduleMXBeanEntryMap, + Map modulesToSources, + Map> qNamesToIdentitiesToModuleMXBeanEntries) { - public YangStoreSnapshotImpl( - Map> moduleMXBeanEntryMap, - Map> moduleMap) { this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap); - this.moduleMap = Collections.unmodifiableMap(moduleMap); + this.modulesToSources = Collections.unmodifiableMap(modulesToSources); + this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries); } - public YangStoreSnapshotImpl(YangStoreSnapshot yangStoreSnapshot) { - this.moduleMXBeanEntryMap = yangStoreSnapshot.getModuleMXBeanEntryMap(); - this.moduleMap = yangStoreSnapshot.getModuleMap(); + public static YangStoreSnapshotImpl copy(YangStoreSnapshot yangStoreSnapshot) { + return new YangStoreSnapshotImpl( + yangStoreSnapshot.getModuleMXBeanEntryMap(), + yangStoreSnapshot.getModulesToSources(), + yangStoreSnapshot.getQNamesToIdentitiesToModuleMXBeanEntries()); } /** @@ -44,8 +54,28 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot { } @Override - public Map> getModuleMap() { - return moduleMap; + public Map> getQNamesToIdentitiesToModuleMXBeanEntries() { + return qNamesToIdentitiesToModuleMXBeanEntries; + } + + @Override + public Set getModules() { + return modulesToSources.keySet(); + } + + @Override + public String getModuleSource(Module module) { + String result = modulesToSources.get(module); + if (result == null) { + logger.trace("Cannot find module {} in {}", module, modulesToSources); + throw new IllegalArgumentException("Module not found in this snapshot:" + module); + } + return result; + } + + @Override + public Map getModulesToSources() { + return modulesToSources; } @Override diff --git a/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java b/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java index b4054c242c..8a7b95ff3e 100644 --- a/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java +++ b/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; -import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyCollectionOf; import static org.mockito.Mockito.doNothing; @@ -82,8 +81,9 @@ public class ExtenderYangTrackerCustomizerTest { doReturn(22).when(yangStoreSnapshot).countModuleMXBeanEntries(); doReturn("mock yang store").when(yangStoreSnapshot).toString(); doNothing().when(yangStoreSnapshot).close(); - doReturn(moduleMap).when(yangStoreSnapshot).getModuleMap(); doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModuleMXBeanEntryMap(); + doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModulesToSources(); + doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getQNamesToIdentitiesToModuleMXBeanEntries(); } @Test @@ -99,7 +99,6 @@ public class ExtenderYangTrackerCustomizerTest { returnedStore = tested.getYangStoreSnapshot(); - assertEquals(yangStoreSnapshot.getModuleMap(), returnedStore.getModuleMap()); tested.removedBundle(bundle, null, null); tested.getYangStoreSnapshot(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java index 7cd43bd79a..6eabbe69c6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java @@ -26,8 +26,8 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.yangtools.yang.model.api.Module; -import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -100,16 +100,15 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { } private static Set setupCapabilities(YangStoreSnapshot yangStoreSnapshot) { - Set capabilities = Sets.newHashSet(); - + Set capabilities = new HashSet<>(); // [RFC6241] 8.3. Candidate Configuration Capability capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0")); // [RFC6241] 8.5. Rollback-on-Error Capability capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0")); - final Collection> modulesAndContents = yangStoreSnapshot.getModuleMap().values(); - for (Map.Entry moduleAndContent : modulesAndContents) { - capabilities.add(new YangStoreCapability(moduleAndContent)); + Set modules = yangStoreSnapshot.getModules(); + for (Module module : modules) { + capabilities.add(new YangStoreCapability(module, yangStoreSnapshot.getModuleSource(module))); } return capabilities; @@ -161,10 +160,9 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { private final String moduleName; private final String moduleNamespace; - public YangStoreCapability(Map.Entry moduleAndContent) { - super(getAsString(moduleAndContent.getKey())); - this.content = moduleAndContent.getValue(); - Module module = moduleAndContent.getKey(); + public YangStoreCapability(Module module, String moduleContent) { + super(getAsString(module)); + this.content = moduleContent; this.moduleName = module.getName(); this.moduleNamespace = module.getNamespace().toString(); this.revision = Util.writeDate(module.getRevision()); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 8dbdb26bff..e0d7e319be 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -18,9 +18,12 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; public class CapabilityProviderImpl implements CapabilityProvider { private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; @@ -31,7 +34,9 @@ public class CapabilityProviderImpl implements CapabilityProvider { public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; Map urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot); - capabilityURIs = Collections.unmodifiableSet(urisToCapabilitiesInternalMap.keySet()); + List capabilityURIs = new ArrayList<>(urisToCapabilitiesInternalMap.keySet()); + Collections.sort(capabilityURIs); + this.capabilityURIs = Collections.unmodifiableSet(new TreeSet<>(capabilityURIs)); } private static Map getCapabilitiesInternal( diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java index 8d3476f4b8..958ac42398 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java @@ -95,7 +95,6 @@ public class ConcurrentClientsTest { final YangStoreSnapshot yStore = mock(YangStoreSnapshot.class); doReturn(yStore).when(this.yangStoreService).getYangStoreSnapshot(); doReturn(Collections.emptyMap()).when(yStore).getModuleMXBeanEntryMap(); - doReturn(Collections.emptyMap()).when(yStore).getModuleMap(); final ConfigTransactionJMXClient mockedTCl = mock(ConfigTransactionJMXClient.class); doReturn(mockedTCl).when(this.jmxClient).getConfigTransactionClient(any(ObjectName.class)); -- 2.36.6