2 * Copyright (c) 2017, 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.binding.runtime.osgi.impl;
10 import static java.util.Objects.requireNonNull;
12 import java.util.List;
13 import java.util.NoSuchElementException;
14 import java.util.stream.Collectors;
15 import org.checkerframework.checker.lock.qual.GuardedBy;
16 import org.checkerframework.checker.lock.qual.Holding;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.binding.DataRoot;
19 import org.opendaylight.yangtools.binding.meta.YangFeatureProvider;
20 import org.opendaylight.yangtools.binding.meta.YangModuleInfo;
21 import org.opendaylight.yangtools.binding.runtime.api.ModuleInfoSnapshot;
22 import org.opendaylight.yangtools.binding.runtime.spi.ModuleInfoSnapshotResolver;
23 import org.opendaylight.yangtools.concepts.AbstractRegistration;
24 import org.opendaylight.yangtools.concepts.Registration;
25 import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
26 import org.osgi.service.component.ComponentFactory;
27 import org.osgi.service.component.ComponentInstance;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed.
34 final class RegularYangModuleInfoRegistry extends YangModuleInfoRegistry {
35 private static final Logger LOG = LoggerFactory.getLogger(RegularYangModuleInfoRegistry.class);
37 private final ComponentFactory<OSGiModuleInfoSnapshotImpl> contextFactory;
38 private final ModuleInfoSnapshotResolver resolver;
41 private ComponentInstance<OSGiModuleInfoSnapshotImpl> currentInstance;
43 private ModuleInfoSnapshot currentSnapshot;
45 private int generation;
47 private volatile boolean ignoreScanner = true;
49 RegularYangModuleInfoRegistry(final ComponentFactory<OSGiModuleInfoSnapshotImpl> contextFactory,
50 final YangParserFactory factory) {
51 this.contextFactory = requireNonNull(contextFactory);
52 resolver = new ModuleInfoSnapshotResolver("dom-schema-osgi", factory);
55 // Invocation from scanner, we may want to ignore this in order to not process partial updates
57 void scannerUpdate() {
66 synchronized void scannerShutdown() {
71 synchronized void enableScannerAndUpdate() {
72 ignoreScanner = false;
77 synchronized void close() {
79 if (currentInstance != null) {
80 currentInstance.dispose();
81 currentInstance = null;
86 Registration registerBundle(final List<YangModuleInfo> moduleInfos,
87 final List<YangFeatureProvider<?>> featureProviders) {
88 final var infoRegs = resolver.registerModuleInfos(moduleInfos);
89 final var featureRegs = featureProviders.stream().map(this::register).collect(Collectors.toList());
91 return new AbstractRegistration() {
93 protected void removeRegistration() {
94 featureRegs.forEach(Registration::close);
95 infoRegs.forEach(Registration::close);
100 @SuppressWarnings("unchecked")
101 private <R extends @NonNull DataRoot<R>> Registration register(final YangFeatureProvider<?> provider) {
102 @SuppressWarnings("rawtypes")
103 final YangFeatureProvider cast = provider;
104 return resolver.registerModuleFeatures(cast.boundModule(), cast.supportedFeatures());
108 private void updateService() {
109 final ModuleInfoSnapshot newSnapshot;
111 newSnapshot = resolver.takeSnapshot();
112 } catch (NoSuchElementException e) {
113 LOG.debug("No snapshot available", e);
116 if (newSnapshot.equals(currentSnapshot)) {
117 LOG.debug("No update to snapshot");
121 final ComponentInstance<OSGiModuleInfoSnapshotImpl> newInstance = contextFactory.newInstance(
122 OSGiModuleInfoSnapshotImpl.props(nextGeneration(), newSnapshot));
123 if (currentInstance != null) {
124 currentInstance.dispose();
126 currentInstance = newInstance;
127 currentSnapshot = newSnapshot;
131 private long nextGeneration() {
132 return generation == -1 ? -1 : ++generation;