From 4b66c069b5bd80e18c3c038186d44c52bb689a7b Mon Sep 17 00:00:00 2001 From: Tomas Olvecky Date: Tue, 19 Nov 2013 18:13:07 +0100 Subject: [PATCH] Add blacklist capability to yang-store-impl. Add blacklist to overcome yuma problems when parsing buggy yang files in md-sal. Change-Id: Iaf222ac627317a48619beadaebb2a16073edac9d Signed-off-by: Tomas Olvecky --- opendaylight/config/yang-store-api/pom.xml | 3 +- .../api/YangStoreListenerRegistration.java | 14 -- .../yang/store/api/YangStoreService.java | 8 - .../yang/store/spi/YangStoreListener.java | 23 -- opendaylight/config/yang-store-impl/pom.xml | 14 +- ...stomizer.java => ExtenderYangTracker.java} | 199 ++++++++---------- .../config/yang/store/impl/MbeParser.java | 28 ++- .../yang/store/impl/YangStoreActivator.java | 50 ++--- .../store/impl/YangStoreSnapshotImpl.java | 27 ++- .../ExtenderYangTrackerCustomizerTest.java | 25 ++- .../store/impl/HardcodedYangStoreService.java | 17 +- .../main/resources/configuration/config.ini | 1 + 12 files changed, 169 insertions(+), 240 deletions(-) delete mode 100644 opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreListenerRegistration.java delete mode 100644 opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/spi/YangStoreListener.java rename opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/{ExtenderYangTrackerCustomizer.java => ExtenderYangTracker.java} (51%) diff --git a/opendaylight/config/yang-store-api/pom.xml b/opendaylight/config/yang-store-api/pom.xml index 9b103df8d7..382dced3e7 100644 --- a/opendaylight/config/yang-store-api/pom.xml +++ b/opendaylight/config/yang-store-api/pom.xml @@ -13,7 +13,7 @@ - org.opendaylight.controller + ${project.groupId} yang-jmx-generator @@ -31,7 +31,6 @@ org.opendaylight.controller.config.yang.store.api, - org.opendaylight.controller.config.yang.store.spi diff --git a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreListenerRegistration.java b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreListenerRegistration.java deleted file mode 100644 index 81015953b4..0000000000 --- a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreListenerRegistration.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yang.store.api; - -public interface YangStoreListenerRegistration extends AutoCloseable { - - @Override - void close(); -} diff --git a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreService.java b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreService.java index 3ac4b84fdb..15619a88cc 100644 --- a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreService.java +++ b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreService.java @@ -7,8 +7,6 @@ */ package org.opendaylight.controller.config.yang.store.api; -import org.opendaylight.controller.config.yang.store.spi.YangStoreListener; - /** * Yang store OSGi service */ @@ -21,10 +19,4 @@ public interface YangStoreService { */ YangStoreSnapshot getYangStoreSnapshot() throws YangStoreException; - - /** - * Allows for registering for change notifications. - */ - YangStoreListenerRegistration registerListener(YangStoreListener listener); - } diff --git a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/spi/YangStoreListener.java b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/spi/YangStoreListener.java deleted file mode 100644 index 72c3d347c8..0000000000 --- a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/spi/YangStoreListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yang.store.spi; - -import java.net.URL; -import java.util.Collection; - -/** - * Implementation of this interface gets notified when bundle containing yang files in META-INF/yang has been - * added or removed. One notification is sent per one bundle. - */ -public interface YangStoreListener { - - void onAddedYangURL(Collection url); - - void onRemovedYangURL(Collection url); - -} diff --git a/opendaylight/config/yang-store-impl/pom.xml b/opendaylight/config/yang-store-impl/pom.xml index ae59dde26c..7b79c831f8 100644 --- a/opendaylight/config/yang-store-impl/pom.xml +++ b/opendaylight/config/yang-store-impl/pom.xml @@ -45,6 +45,10 @@ mockito-configuration test + + com.google.code.findbugs + jsr305 + @@ -54,15 +58,9 @@ maven-bundle-plugin - org.opendaylight.controller.config.yang.store.impl.YangStoreActivator - - - org.opendaylight.controller.config.yang.store.impl, - - + org.opendaylight.controller.config.yang.store.impl.YangStoreActivator org.opendaylight.controller.config.yang.store.api, - org.opendaylight.controller.config.yang.store.spi, org.opendaylight.controller.config.yangjmxgenerator, com.google.common.base, com.google.common.collect, @@ -76,7 +74,7 @@ org.opendaylight.yangtools.yang.common, org.opendaylight.yangtools.yang.model.api, org.opendaylight.yangtools.sal.binding.generator.spi, - org.opendaylight.yangtools.yang.parser.impl + org.opendaylight.yangtools.yang.parser.impl, diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizer.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java similarity index 51% rename from opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizer.java rename to opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 278ae961e2..2ead596d05 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizer.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -16,24 +16,27 @@ 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.YangStoreListenerRegistration; import org.opendaylight.controller.config.yang.store.api.YangStoreService; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.config.yang.store.spi.YangStoreListener; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; -import org.osgi.util.tracker.BundleTrackerCustomizer; +import org.osgi.util.tracker.BundleTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.concurrent.GuardedBy; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Note on consistency: @@ -41,10 +44,9 @@ import java.util.Set; * is not preserved. We thus maintain two maps, one containing consistent snapshot, other inconsistent. The * container should eventually send all events and thus making the inconsistent map redundant. */ -public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer, YangStoreService { +public class ExtenderYangTracker extends BundleTracker implements YangStoreService, AutoCloseable { - private static final Logger logger = LoggerFactory - .getLogger(ExtenderYangTrackerCustomizer.class); + private static final Logger logger = LoggerFactory.getLogger(ExtenderYangTracker.class); private final Multimap consistentBundlesToYangURLs = HashMultimap.create(); @@ -55,20 +57,25 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer listeners = new ArrayList<>(); - public ExtenderYangTrackerCustomizer() { - this(new MbeParser()); + public ExtenderYangTracker(Optional maybeBlacklist, BundleContext bundleContext) { + this(new MbeParser(), maybeBlacklist, bundleContext); } + @GuardedBy("this") + private Optional maybeBlacklist; + @VisibleForTesting - ExtenderYangTrackerCustomizer(MbeParser mbeParser) { + ExtenderYangTracker(MbeParser mbeParser, Optional maybeBlacklist, BundleContext bundleContext) { + super(bundleContext, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, null); this.mbeParser = mbeParser; + this.maybeBlacklist = maybeBlacklist; + open(); } @Override - public Object addingBundle(Bundle bundle, BundleEvent event) { + public synchronized Object addingBundle(Bundle bundle, BundleEvent event) { // Ignore system bundle: // system bundle might have config-api on classpath && @@ -77,6 +84,14 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer enumeration = bundle.findEntries("META-INF/yang", "*.yang", false); if (enumeration != null && enumeration.hasMoreElements()) { synchronized (this) { @@ -90,8 +105,32 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer proposedNewState = HashMultimap.create(consistentBundlesToYangURLs); proposedNewState.putAll(inconsistentBundlesToYangURLs); proposedNewState.putAll(bundle, addedURLs); - boolean adding = true; - if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) { + + Preconditions.checkArgument(addedURLs.size() > 0, "No change can occur when no URLs are changed"); + boolean success; + String failureReason = null; + try(YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, proposedNewState)) { + updateCache(snapshot); + success = true; + } catch(YangStoreException e) { + failureReason = e.toString(); + success = false; + } + if (success){ + // consistent state + // merge into + consistentBundlesToYangURLs.clear(); + consistentBundlesToYangURLs.putAll(proposedNewState); + inconsistentBundlesToYangURLs.clear(); + + logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size()); + logger.trace("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs); + } else { + // inconsistent state + logger.debug("Yang store is falling back on last consistent state containing {}, inconsistent yang files {}, reason {}", + consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason); + logger.warn("Yang store is falling back on last consistent state containing {} files, inconsistent yang files size is {}, reason {}", + consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason); inconsistentBundlesToYangURLs.putAll(bundle, addedURLs); } } @@ -99,30 +138,7 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer changedURLs, Multimap proposedNewState, boolean adding) { - Preconditions.checkArgument(changedURLs.size() > 0, "No change can occur when no URLs are changed"); - try(YangStoreSnapshot snapshot = createSnapshot(mbeParser, proposedNewState)) { - // consistent state - // merge into - consistentBundlesToYangURLs.clear(); - consistentBundlesToYangURLs.putAll(proposedNewState); - inconsistentBundlesToYangURLs.clear(); - // update cache - updateCache(snapshot); - logger.info("Yang store updated to new consistent state"); - logger.trace("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs); - - notifyListeners(changedURLs, adding); - return true; - } catch(YangStoreException e) { - // inconsistent state - logger.debug("Yang store is falling back on last consistent state containing {}, inconsistent yang files {}, reason {}", - consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e.toString()); - return false; - } - } - - private void updateCache(YangStoreSnapshot snapshot) { + private void updateCache(YangStoreSnapshotImpl snapshot) { cache.cacheYangStore(consistentBundlesToYangURLs, snapshot); } @@ -131,31 +147,6 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer changedURLs, boolean adding) { - Preconditions.checkArgument(changedURLs.size() > 0, "Cannot notify when no URLs changed"); - if (changedURLs.size() > 0) { - RuntimeException potential = new RuntimeException("Error while notifying listeners"); - for (YangStoreListener listener : listeners) { - try { - if (adding) { - listener.onAddedYangURL(changedURLs); - } else { - listener.onRemovedYangURL(changedURLs); - } - } catch(RuntimeException e) { - potential.addSuppressed(e); - } - } - if (potential.getSuppressed().length > 0) { - throw potential; - } - } - } - - /** * If removing YANG files makes yang store inconsistent, method {@link #getYangStoreSnapshot()} * will throw exception. There is no rollback. @@ -163,31 +154,25 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer consistentURLsToBeRemoved = consistentBundlesToYangURLs.removeAll(bundle); - - if (consistentURLsToBeRemoved.isEmpty()){ - return; // no change - } - boolean adding = false; - notifyListeners(consistentURLsToBeRemoved, adding); + consistentBundlesToYangURLs.removeAll(bundle); } @Override public synchronized YangStoreSnapshot getYangStoreSnapshot() throws YangStoreException { - Optional yangStoreOpt = cache.getCachedYangStore(consistentBundlesToYangURLs); + Optional yangStoreOpt = cache.getSnapshotIfPossible(consistentBundlesToYangURLs); if (yangStoreOpt.isPresent()) { logger.trace("Returning cached yang store {}", yangStoreOpt.get()); return yangStoreOpt.get(); } - YangStoreSnapshot snapshot = createSnapshot(mbeParser, consistentBundlesToYangURLs); + YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, consistentBundlesToYangURLs); updateCache(snapshot); return snapshot; } - private static YangStoreSnapshot createSnapshot(MbeParser mbeParser, Multimap multimap) throws YangStoreException { + private static YangStoreSnapshotImpl createSnapshot(MbeParser mbeParser, Multimap multimap) throws YangStoreException { try { - YangStoreSnapshot yangStoreSnapshot = mbeParser.parseYangFiles(fromUrlsToInputStreams(multimap)); + YangStoreSnapshotImpl yangStoreSnapshot = mbeParser.parseYangFiles(fromUrlsToInputStreams(multimap)); logger.trace("{} module entries parsed successfully from {} yang files", yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size()); return yangStoreSnapshot; @@ -213,44 +198,46 @@ public class ExtenderYangTrackerCustomizer implements BundleTrackerCustomizer maybeBlacklistPattern) { + maybeBlacklist = maybeBlacklistPattern; + cache.invalidate(); } +} - private static final class YangStoreCache { - - Set cachedUrls; - YangStoreSnapshot cachedYangStoreSnapshot; - - Optional getCachedYangStore( - Multimap bundlesToYangURLs) { - Set urls = setFromMultimapValues(bundlesToYangURLs); - if (cachedUrls != null && cachedUrls.equals(urls)) { - Preconditions.checkState(cachedYangStoreSnapshot != null); - return Optional.of(cachedYangStoreSnapshot); - } - return Optional.absent(); +class YangStoreCache { + @GuardedBy("this") + private Set cachedUrls = Collections.emptySet(); + @GuardedBy("this") + private Optional cachedYangStoreSnapshot = Optional.absent(); + + 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()); + 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; - } + private static Set setFromMultimapValues( + Multimap bundlesToYangURLs) { + Set urls = Sets.newHashSet(bundlesToYangURLs.values()); + Preconditions.checkState(bundlesToYangURLs.size() == urls.size()); + return urls; + } - void cacheYangStore(Multimap urls, - YangStoreSnapshot yangStoreSnapshot) { - this.cachedUrls = setFromMultimapValues(urls); - this.cachedYangStoreSnapshot = yangStoreSnapshot; - } + synchronized void cacheYangStore(Multimap urls, + YangStoreSnapshotImpl yangStoreSnapshot) { + this.cachedUrls = setFromMultimapValues(urls); + this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot); + } + synchronized void invalidate() { + cachedUrls.clear(); + if (cachedYangStoreSnapshot.isPresent()){ + cachedYangStoreSnapshot.get().close(); + cachedYangStoreSnapshot = Optional.absent(); + } } } 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 fc895eb51d..211da6bfef 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 @@ -7,19 +7,11 @@ */ package org.opendaylight.controller.config.yang.store.impl; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.apache.commons.io.IOUtils; import org.opendaylight.controller.config.yang.store.api.YangStoreException; -import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator; import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; @@ -30,13 +22,19 @@ 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 com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; public class MbeParser { - public YangStoreSnapshot parseYangFiles( + public YangStoreSnapshotImpl parseYangFiles( Collection allInput) throws YangStoreException { YangParserImpl parser = new YangParserImpl(); diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java index a358e5f7c1..a25b05ab8a 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java @@ -7,50 +7,40 @@ */ package org.opendaylight.controller.config.yang.store.impl; -import java.util.Dictionary; -import java.util.Hashtable; - +import com.google.common.base.Optional; import org.opendaylight.controller.config.yang.store.api.YangStoreService; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.BundleTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class YangStoreActivator implements BundleActivator { +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.regex.Pattern; - private BundleTracker bundleTracker; - private ServiceRegistration registration; - private static final Logger logger = LoggerFactory - .getLogger(YangStoreActivator.class); +public class YangStoreActivator implements BundleActivator { + private static final Logger logger = LoggerFactory.getLogger(YangStoreActivator.class); @Override public void start(BundleContext context) throws Exception { - ExtenderYangTrackerCustomizer customizerAndService = new ExtenderYangTrackerCustomizer(); - bundleTracker = new BundleTracker(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, customizerAndService); - bundleTracker.open(); - + // get blacklist + Optional maybeBlacklistPattern = Optional.absent(); + String blacklist = context.getProperty("yangstore.blacklist"); + if (blacklist != null) { + try { + maybeBlacklistPattern = Optional.of(Pattern.compile(blacklist)); + } catch (RuntimeException e) { + logger.error("Cannot parse blacklist regex " + blacklist, e); + throw e; + } + } + ExtenderYangTracker extenderYangTracker = new ExtenderYangTracker(maybeBlacklistPattern, context); Dictionary properties = new Hashtable<>(); - registration = context.registerService(YangStoreService.class, - customizerAndService, properties); + context.registerService(YangStoreService.class, extenderYangTracker, properties); } @Override public void stop(BundleContext context) throws Exception { - try { - bundleTracker.close(); - } catch (Exception e) { - logger.warn("Exception while closing bundleTracker", e); - } - if (registration != null) { - try { - registration.unregister(); - } catch (Exception e) { - logger.warn("Exception while unregistring yang store service", - e); - } - } + } } 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 d5169eac38..7a5ca7debe 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 @@ -7,32 +7,31 @@ */ package org.opendaylight.controller.config.yang.store.impl; -import java.util.Map; -import java.util.Map.Entry; - 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 java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; + public class YangStoreSnapshotImpl implements YangStoreSnapshot { - private final Map> moduleMXBeanEntryMap; + private final Map> moduleMXBeanEntryMap; private final Map> moduleMap; public YangStoreSnapshotImpl( Map> moduleMXBeanEntryMap, Map> moduleMap) { - this.moduleMXBeanEntryMap = moduleMXBeanEntryMap; - this.moduleMap = moduleMap; + this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap); + this.moduleMap = Collections.unmodifiableMap(moduleMap); + } + + public YangStoreSnapshotImpl(YangStoreSnapshotImpl yangStoreSnapshot) { + this.moduleMXBeanEntryMap = yangStoreSnapshot.moduleMXBeanEntryMap; + this.moduleMap = yangStoreSnapshot.moduleMap; } @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 427da1f634..c4c523992f 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 @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.config.yang.store.impl; +import com.google.common.base.Optional; import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Test; @@ -15,14 +16,19 @@ import org.mockito.MockitoAnnotations; import org.opendaylight.controller.config.yang.store.api.YangStoreException; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleListener; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.util.Collections; import java.util.Enumeration; import java.util.List; +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; import static org.mockito.Mockito.doReturn; @@ -34,22 +40,26 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; public class ExtenderYangTrackerCustomizerTest { - private ExtenderYangTrackerCustomizer tested; + private ExtenderYangTracker tested; @Mock private MbeParser parser; @Mock - private YangStoreSnapshot yangStoreSnapshot; + private YangStoreSnapshotImpl yangStoreSnapshot; + @Mock + private BundleContext bundleContext; @Before public void setUp() throws YangStoreException { MockitoAnnotations.initMocks(this); - - tested = new ExtenderYangTrackerCustomizer(parser); + doNothing().when(bundleContext).addBundleListener(any(BundleListener.class)); + doReturn(new Bundle[0]).when(bundleContext).getBundles(); + tested = new ExtenderYangTracker(parser, Optional.absent(), bundleContext); doReturn(yangStoreSnapshot).when(parser).parseYangFiles( anyCollectionOf(InputStream.class)); doReturn(22).when(yangStoreSnapshot).countModuleMXBeanEntries(); doReturn("mock yang store").when(yangStoreSnapshot).toString(); doNothing().when(yangStoreSnapshot).close(); + doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModuleMap(); } @Test @@ -73,17 +83,15 @@ public class ExtenderYangTrackerCustomizerTest { bundle = getMockedBundle(10, false); tested.addingBundle(bundle, null); - for(int i = 0; i< 10; i++){ + for(int i = 0; i< 20; i++){ tested.getYangStoreSnapshot(); } - verify(parser, times(5)).parseYangFiles( - anyCollectionOf(InputStream.class)); + verify(parser, times(7)).parseYangFiles(anyCollectionOf(InputStream.class)); returnedStore = tested.getYangStoreSnapshot(); verifyNoMoreInteractions(parser); - assertEquals(yangStoreSnapshot, returnedStore); } int bundleCounter = 1; @@ -106,6 +114,7 @@ public class ExtenderYangTrackerCustomizerTest { doReturn(1L).when(mock).getBundleId(); doReturn("mockedBundle").when(mock).toString(); + doReturn("mockedBundle").when(mock).getSymbolicName(); return mock; } diff --git a/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/HardcodedYangStoreService.java b/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/HardcodedYangStoreService.java index 844f682b7a..6221682147 100644 --- a/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/HardcodedYangStoreService.java +++ b/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/HardcodedYangStoreService.java @@ -7,7 +7,10 @@ */ package org.opendaylight.controller.config.yang.store.impl; -import static org.junit.Assert.assertNotNull; +import org.apache.commons.io.IOUtils; +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 java.io.ByteArrayInputStream; import java.io.IOException; @@ -15,12 +18,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; -import org.apache.commons.io.IOUtils; -import org.opendaylight.controller.config.yang.store.api.YangStoreException; -import org.opendaylight.controller.config.yang.store.api.YangStoreListenerRegistration; -import org.opendaylight.controller.config.yang.store.api.YangStoreService; -import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.config.yang.store.spi.YangStoreListener; +import static org.junit.Assert.assertNotNull; public class HardcodedYangStoreService implements YangStoreService { @@ -50,9 +48,4 @@ public class HardcodedYangStoreService implements YangStoreService { } return new MbeParser().parseYangFiles(byteArrayInputStreams); } - - @Override - public YangStoreListenerRegistration registerListener(YangStoreListener listener){ - throw new UnsupportedOperationException("Cannot register for changes on this service"); - } } diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index caf9d09591..8347bf1e44 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -23,6 +23,7 @@ netconf.tcp.port=8383 #netconf.tls.keystore.password= netconf.config.persister.storageAdapterClass=org.opendaylight.controller.netconf.persist.impl.NoOpStorageAdapter +yangstore.blacklist=.*controller.model.* # Set Default start level for framework osgi.bundles.defaultStartLevel=4 -- 2.36.6