2 * Copyright (c) 2015 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 java.lang.management.ManagementFactory;
12 import java.util.Hashtable;
13 import java.util.concurrent.atomic.AtomicBoolean;
14 import javax.management.MBeanServer;
15 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
16 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
17 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
18 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
19 import org.osgi.framework.BundleActivator;
20 import org.osgi.framework.BundleContext;
21 import org.osgi.framework.ServiceReference;
22 import org.osgi.framework.ServiceRegistration;
23 import org.osgi.util.tracker.ServiceTracker;
24 import org.osgi.util.tracker.ServiceTrackerCustomizer;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Start yang store service and the XML config manager facade
31 public class YangStoreActivator implements BundleActivator {
33 private static final Logger LOG = LoggerFactory.getLogger(YangStoreActivator.class);
35 private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
37 private ServiceRegistration<YangStoreService> yangStoreServiceServiceRegistration;
38 private ConfigRegistryLookupThread configRegistryLookup = null;
39 private BundleContext context;
40 private ServiceRegistration<ConfigSubsystemFacadeFactory> osgiRegistrayion;
43 public void start(final BundleContext context) throws Exception {
44 LOG.debug("ConfigPersister starting");
45 this.context = context;
47 ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService> schemaServiceTrackerCustomizer = new ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService>() {
49 private final AtomicBoolean alreadyStarted = new AtomicBoolean(false);
52 public YangStoreService addingService(ServiceReference<SchemaContextProvider> reference) {
53 LOG.debug("Got addingService(SchemaContextProvider) event");
55 // Yang store service should not be registered multiple times
56 if(!alreadyStarted.compareAndSet(false, true)) {
57 LOG.warn("Starting yang store service multiple times. Received new service {}", reference);
58 throw new RuntimeException("Starting yang store service multiple times");
60 SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext().getService(reference);
61 final YangStoreService yangStoreService = new YangStoreService(schemaContextProvider);
62 yangStoreServiceServiceRegistration = context.registerService(YangStoreService.class, yangStoreService, new Hashtable<String, Object>());
63 configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
64 configRegistryLookup.start();
65 return yangStoreService;
69 public void modifiedService(ServiceReference<SchemaContextProvider> reference, YangStoreService service) {
70 LOG.debug("Got modifiedService(SchemaContextProvider) event");
71 final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference.getProperty(BindingRuntimeContext.class.getName());
72 LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
73 service.refresh(runtimeContext);
77 public void removedService(ServiceReference<SchemaContextProvider> reference, YangStoreService service) {
78 LOG.debug("Got removedService(SchemaContextProvider) event");
79 alreadyStarted.set(false);
80 configRegistryLookup.interrupt();
81 yangStoreServiceServiceRegistration.unregister();
82 yangStoreServiceServiceRegistration = null;
86 ServiceTracker<SchemaContextProvider, YangStoreService> schemaContextProviderServiceTracker =
87 new ServiceTracker<>(context, SchemaContextProvider.class, schemaServiceTrackerCustomizer);
88 schemaContextProviderServiceTracker.open();
92 public void stop(BundleContext context) throws Exception {
93 if(configRegistryLookup != null) {
94 configRegistryLookup.interrupt();
96 if(osgiRegistrayion != null) {
97 osgiRegistrayion.unregister();
99 if (yangStoreServiceServiceRegistration != null) {
100 yangStoreServiceServiceRegistration.unregister();
101 yangStoreServiceServiceRegistration = null;
106 * Find ConfigRegistry from config manager in JMX
108 private class ConfigRegistryLookupThread extends Thread {
109 public static final int ATTEMPT_TIMEOUT_MS = 1000;
110 private static final int SILENT_ATTEMPTS = 30;
112 private final YangStoreService yangStoreService;
114 private ConfigRegistryLookupThread(YangStoreService yangStoreService) {
115 super("config-registry-lookup");
116 this.yangStoreService = yangStoreService;
122 ConfigRegistryJMXClient configRegistryJMXClient;
123 ConfigRegistryJMXClient configRegistryJMXClientNoNotifications;
125 // Config registry might not be present yet, but will be eventually
129 configRegistryJMXClient = new ConfigRegistryJMXClient(configMBeanServer);
130 configRegistryJMXClientNoNotifications = ConfigRegistryJMXClient.createWithoutNotifications(configMBeanServer);
132 } catch (IllegalStateException e) {
134 if (i > SILENT_ATTEMPTS) {
135 LOG.info("JMX client not created after {} attempts, still trying", i, e);
137 LOG.debug("JMX client could not be created, reattempting, try {}", i, e);
140 Thread.sleep(ATTEMPT_TIMEOUT_MS);
141 } catch (InterruptedException e1) {
142 Thread.currentThread().interrupt();
143 throw new IllegalStateException("Interrupted while reattempting connection", e1);
148 final ConfigRegistryJMXClient jmxClient = configRegistryJMXClient;
149 final ConfigRegistryJMXClient jmxClientNoNotifications = configRegistryJMXClientNoNotifications;
150 if (i > SILENT_ATTEMPTS) {
151 LOG.info("Created JMX client after {} attempts", i);
153 LOG.debug("Created JMX client after {} attempts", i);
156 final ConfigSubsystemFacadeFactory configSubsystemFacade =
157 new ConfigSubsystemFacadeFactory(jmxClient, jmxClientNoNotifications, yangStoreService);
158 osgiRegistrayion = context.registerService(ConfigSubsystemFacadeFactory.class, configSubsystemFacade, new Hashtable<String, Object>());