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 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;
proposedNewState.putAll(bundle, addedURLs);
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;
+ onSnapshotSuccess(proposedNewState, snapshot);
} 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);
+ onSnapshotFailure(bundle, addedURLs, e);
}
}
}
return bundle;
}
- private void updateCache(YangStoreSnapshotImpl snapshot) {
+ private synchronized void onSnapshotFailure(Bundle bundle, List<URL> addedURLs, Exception failureReason) {
+ // inconsistent state
+ inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
+
+ logger.debug("Yang store is falling back to last consistent state containing {}, inconsistent yang files {}",
+ consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason);
+ logger.info("Yang store is falling back to last consistent state containing {} files, keeping {} inconsistent yang files due to {}",
+ consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason.toString());
+ cache.setInconsistentURLsForReporting(inconsistentBundlesToYangURLs.values());
+ }
+
+ private synchronized void onSnapshotSuccess(Multimap<Bundle, URL> proposedNewState, YangStoreSnapshotImpl snapshot) {
+ // consistent state
+ // merge into
+ consistentBundlesToYangURLs.clear();
+ consistentBundlesToYangURLs.putAll(proposedNewState);
+
+ logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs);
+
+ // If we cleared up some inconsistent models, report that
+ if (!inconsistentBundlesToYangURLs.isEmpty()) {
+ inconsistentBundlesToYangURLs.clear();
+ logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
+ }
+
+ updateCache(snapshot);
+ cache.setInconsistentURLsForReporting(Collections.<URL> emptySet());
+ }
+
+ private synchronized void updateCache(YangStoreSnapshotImpl snapshot) {
cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
}
*/
@Override
public synchronized void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+ logger.debug("Removed bundle {} {} {}", bundle, event, object);
inconsistentBundlesToYangURLs.removeAll(bundle);
consistentBundlesToYangURLs.removeAll(bundle);
}
throws YangStoreException {
Optional<YangStoreSnapshot> yangStoreOpt = cache.getSnapshotIfPossible(consistentBundlesToYangURLs);
if (yangStoreOpt.isPresent()) {
- logger.trace("Returning cached yang store {}", yangStoreOpt.get());
+ logger.debug("Returning cached yang store {}", yangStoreOpt.get());
return yangStoreOpt.get();
}
+
YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, consistentBundlesToYangURLs);
updateCache(snapshot);
return snapshot;
yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
return yangStoreSnapshot;
} catch (RuntimeException e) {
- throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e);
+ StringBuffer causeStr = new StringBuffer();
+ Throwable cause = e;
+ while (cause != null) {
+ causeStr.append(e.getMessage());
+ causeStr.append("\n");
+ cause = e.getCause();
+ }
+ throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
+ "URLs: " + multimap, e);
}
}
cache.invalidate();
}
}
-
-class YangStoreCache {
- @GuardedBy("this")
- private Set<URL> cachedUrls = Collections.emptySet();
- @GuardedBy("this")
- private Optional<YangStoreSnapshotImpl> cachedYangStoreSnapshot = Optional.absent();
-
- synchronized Optional<YangStoreSnapshot> getSnapshotIfPossible(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> 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<URL> setFromMultimapValues(
- Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
- Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
- return urls;
- }
-
- synchronized void cacheYangStore(Multimap<Bundle, URL> 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();
- }
- }
-}