import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
+
import static com.google.common.base.Preconditions.*;
-public class SchemaServiceImpl implements SchemaService, AutoCloseable {
+public class SchemaServiceImpl implements //
+ SchemaService, //
+ ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
+ AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class);
private ListenerRegistry<SchemaServiceListener> listeners;
private BundleTracker<Object> bundleTracker;
private final YangStoreCache cache = new YangStoreCache();
+ private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
+
public ListenerRegistry<SchemaServiceListener> getListeners() {
return listeners;
}
listeners = new ListenerRegistry<>();
}
+ listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, this);
bundleTracker = new BundleTracker<Object>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
bundleTracker.open();
+ listenerTracker.open();
}
public SchemaContext getGlobalContext() {
throw new UnsupportedOperationException();
}
-
@Override
public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(SchemaServiceListener listener) {
return listeners.register(listener);
}
-
+
@Override
public void close() throws Exception {
bundleTracker.close();
private synchronized boolean tryToUpdateState(Collection<URL> changedURLs, Multimap<Bundle, URL> proposedNewState,
boolean adding) {
- Preconditions.checkArgument(changedURLs.size() > 0, "No change can occur when no URLs are changed");
+ Preconditions.checkArgument(!changedURLs.isEmpty(), "No change can occur when no URLs are changed");
try {
// consistent state
} catch (Exception e) {
// inconsistent state
logger.debug(
- "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}, reason {}",
- consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e.toString());
+ "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}",
+ consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e);
return false;
}
}
private void updateCache(SchemaContext snapshot) {
cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
+
+ Object[] services = listenerTracker.getServices();
+ if (services != null) {
+ for (Object rawListener : services) {
+ SchemaServiceListener listener = (SchemaServiceListener) rawListener;
+ try {
+ listener.onGlobalContextUpdated(snapshot);
+ } catch (Exception e) {
+ logger.error("Exception occured during invoking listener", e);
+ }
+ }
+ }
for (ListenerRegistration<SchemaServiceListener> listener : listeners) {
try {
listener.getInstance().onGlobalContextUpdated(snapshot);
} catch (Exception e) {
- logger.error("Exception occured during invoking listener",e);
+ logger.error("Exception occured during invoking listener", e);
}
}
}
// system bundle might have config-api on classpath &&
// config-api contains yang files =>
// system bundle might contain yang files from that bundle
- if (bundle.getBundleId() == 0)
+ if (bundle.getBundleId() == 0) {
return bundle;
+ }
Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
if (enumeration != null && enumeration.hasMoreElements()) {
proposedNewState.putAll(inconsistentBundlesToYangURLs);
proposedNewState.putAll(bundle, addedURLs);
boolean adding = true;
+
if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) {
inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
}
this.cachedUrls = setFromMultimapValues(urls);
this.cachedContextSnapshot = ctx;
}
+ }
+
+ @Override
+ public SchemaServiceListener addingService(ServiceReference<SchemaServiceListener> reference) {
+
+ SchemaServiceListener listener = context.getService(reference);
+ SchemaContext _ctxContext = getGlobalContext();
+ if (getContext() != null) {
+ listener.onGlobalContextUpdated(_ctxContext);
+ }
+ return listener;
+ }
+ @Override
+ public void modifiedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+ // NOOP
+ }
+
+ @Override
+ public void removedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
+ context.ungetService(reference);
}
}