2 * Copyright (c) 2015, 2017 Cisco Systems, Inc. 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
9 package org.opendaylight.controller.config.facade.xml.osgi;
11 import com.google.common.base.Preconditions;
12 import java.lang.management.ManagementFactory;
13 import java.util.Hashtable;
14 import java.util.concurrent.atomic.AtomicBoolean;
15 import javax.management.MBeanServer;
16 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
17 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
18 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
19 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
20 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
21 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
22 import org.osgi.framework.BundleActivator;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.ServiceReference;
25 import org.osgi.framework.ServiceRegistration;
26 import org.osgi.util.tracker.ServiceTracker;
27 import org.osgi.util.tracker.ServiceTrackerCustomizer;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Start yang store service and the XML config manager facade.
34 public class YangStoreActivator implements BundleActivator {
36 private static final Logger LOG = LoggerFactory.getLogger(YangStoreActivator.class);
38 private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
40 private ServiceRegistration<YangStoreService> yangStoreServiceServiceRegistration;
41 private ConfigRegistryLookupThread configRegistryLookup = null;
42 private BundleContext context;
43 private ServiceRegistration<ConfigSubsystemFacadeFactory> osgiRegistrayion;
46 @SuppressWarnings("checkstyle:hiddenField")
47 public void start(final BundleContext context) throws Exception {
48 LOG.debug("ConfigPersister starting");
49 this.context = context;
51 final ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService> schemaServiceTrackerCustomizer =
52 new ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService>() {
54 private final AtomicBoolean alreadyStarted = new AtomicBoolean(false);
57 public YangStoreService addingService(final ServiceReference<SchemaContextProvider> reference) {
58 LOG.debug("Got addingService(SchemaContextProvider) event");
59 if (reference.getProperty(SchemaSourceProvider.class.getName()) == null
60 && reference.getProperty(BindingRuntimeContext.class.getName()) == null) {
61 LOG.debug("SchemaContextProvider not from config-manager. Ignoring");
65 // Yang store service should not be registered multiple times
66 if (!this.alreadyStarted.compareAndSet(false, true)) {
67 LOG.warn("Starting yang store service multiple times. Received new service {}", reference);
68 throw new RuntimeException("Starting yang store service multiple times");
70 final SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext()
71 .getService(reference);
72 final Object sourceProvider = Preconditions.checkNotNull(
73 reference.getProperty(SchemaSourceProvider.class.getName()), "Source provider not found");
74 Preconditions.checkArgument(sourceProvider instanceof SchemaSourceProvider);
77 final YangStoreService yangStoreService = new YangStoreService(schemaContextProvider,
78 (SchemaSourceProvider<YangTextSchemaSource>) sourceProvider);
80 final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference
81 .getProperty(BindingRuntimeContext.class.getName());
82 LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
83 if (runtimeContext != null) {
84 yangStoreService.refresh(runtimeContext);
87 YangStoreActivator.this.yangStoreServiceServiceRegistration = context
88 .registerService(YangStoreService.class, yangStoreService, new Hashtable<>());
89 YangStoreActivator.this.configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
90 YangStoreActivator.this.configRegistryLookup.start();
91 return yangStoreService;
95 public void modifiedService(final ServiceReference<SchemaContextProvider> reference,
96 final YangStoreService service) {
97 if (service == null) {
101 LOG.debug("Got modifiedService(SchemaContextProvider) event");
102 final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference
103 .getProperty(BindingRuntimeContext.class.getName());
104 LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
105 service.refresh(runtimeContext);
109 public void removedService(final ServiceReference<SchemaContextProvider> reference,
110 final YangStoreService service) {
111 if (service == null) {
115 LOG.debug("Got removedService(SchemaContextProvider) event");
116 this.alreadyStarted.set(false);
117 YangStoreActivator.this.configRegistryLookup.interrupt();
118 YangStoreActivator.this.yangStoreServiceServiceRegistration.unregister();
119 YangStoreActivator.this.yangStoreServiceServiceRegistration = null;
123 final ServiceTracker<SchemaContextProvider, YangStoreService> schemaContextProviderServiceTracker =
124 new ServiceTracker<>(context, SchemaContextProvider.class, schemaServiceTrackerCustomizer);
125 schemaContextProviderServiceTracker.open();
129 @SuppressWarnings("checkstyle:hiddenField")
130 public void stop(final BundleContext context) throws Exception {
131 if (this.configRegistryLookup != null) {
132 this.configRegistryLookup.interrupt();
134 if (this.osgiRegistrayion != null) {
135 this.osgiRegistrayion.unregister();
137 if (this.yangStoreServiceServiceRegistration != null) {
138 this.yangStoreServiceServiceRegistration.unregister();
139 this.yangStoreServiceServiceRegistration = null;
144 * Find ConfigRegistry from config manager in JMX.
146 private class ConfigRegistryLookupThread extends Thread {
147 public static final int ATTEMPT_TIMEOUT_MS = 1000;
148 private static final int SILENT_ATTEMPTS = 30;
150 private final YangStoreService yangStoreService;
152 ConfigRegistryLookupThread(final YangStoreService yangStoreService) {
153 super("config-registry-lookup");
154 this.yangStoreService = yangStoreService;
160 ConfigRegistryJMXClient configRegistryJMXClient;
161 ConfigRegistryJMXClient configRegistryJMXClientNoNotifications;
163 // Config registry might not be present yet, but will be eventually
167 configRegistryJMXClient = new ConfigRegistryJMXClient(YangStoreActivator.this.configMBeanServer);
168 configRegistryJMXClientNoNotifications = ConfigRegistryJMXClient
169 .createWithoutNotifications(YangStoreActivator.this.configMBeanServer);
171 } catch (final IllegalStateException e) {
173 if (index > SILENT_ATTEMPTS) {
174 LOG.info("JMX client not created after {} attempts, still trying", index, e);
176 LOG.debug("JMX client could not be created, reattempting, try {}", index, e);
179 Thread.sleep(ATTEMPT_TIMEOUT_MS);
180 } catch (final InterruptedException e1) {
181 Thread.currentThread().interrupt();
182 throw new IllegalStateException("Interrupted while reattempting connection", e1);
187 final ConfigRegistryJMXClient jmxClient = configRegistryJMXClient;
188 final ConfigRegistryJMXClient jmxClientNoNotifications = configRegistryJMXClientNoNotifications;
189 if (index > SILENT_ATTEMPTS) {
190 LOG.info("Created JMX client after {} attempts", index);
192 LOG.debug("Created JMX client after {} attempts", index);
195 final ConfigSubsystemFacadeFactory configSubsystemFacade = new ConfigSubsystemFacadeFactory(jmxClient,
196 jmxClientNoNotifications, this.yangStoreService);
197 YangStoreActivator.this.osgiRegistrayion = YangStoreActivator.this.context
198 .registerService(ConfigSubsystemFacadeFactory.class, configSubsystemFacade, new Hashtable<>());