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.persist.impl.osgi;
11 import com.google.common.collect.Lists;
12 import java.lang.management.ManagementFactory;
13 import java.util.List;
14 import java.util.concurrent.TimeUnit;
15 import javax.management.MBeanServer;
16 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
17 import org.opendaylight.controller.config.persist.api.ConfigPusher;
18 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
19 import org.opendaylight.controller.config.persist.api.Persister;
20 import org.opendaylight.controller.config.persist.impl.ConfigPusherImpl;
21 import org.opendaylight.controller.config.persist.impl.PersisterAggregator;
22 import org.opendaylight.controller.config.util.CloseableUtil;
23 import org.osgi.framework.BundleActivator;
24 import org.osgi.framework.BundleContext;
25 import org.osgi.framework.ServiceReference;
26 import org.osgi.framework.ServiceRegistration;
27 import org.osgi.util.tracker.ServiceTracker;
28 import org.osgi.util.tracker.ServiceTrackerCustomizer;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public class ConfigPersisterActivator implements BundleActivator {
34 private static final Logger LOG = LoggerFactory.getLogger(ConfigPersisterActivator.class);
35 private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
37 public static final String MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY = "maxWaitForCapabilitiesMillis";
38 private static final long MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(2);
39 public static final String CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY = "conflictingVersionTimeoutMillis";
40 private static final long CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(1);
42 public static final String NETCONF_CONFIG_PERSISTER = "netconf.config.persister";
44 public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass";
46 private final List<AutoCloseable> autoCloseables = Lists.newArrayList();
47 private volatile BundleContext context;
49 ServiceRegistration<?> registration;
52 public void start(final BundleContext context) throws Exception {
53 LOG.debug("ConfigPersister starting");
54 this.context = context;
56 PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context);
58 final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider);
59 autoCloseables.add(persisterAggregator);
60 final long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
61 final List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
62 final long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
63 LOG.debug("Following configs will be pushed: {}", configs);
65 ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaServiceTrackerCustomizer = new ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory>() {
68 public ConfigSubsystemFacadeFactory addingService(ServiceReference<ConfigSubsystemFacadeFactory> reference) {
69 LOG.debug("Got addingService(SchemaContextProvider) event");
70 // Yang store service should not be registered multiple times
71 ConfigSubsystemFacadeFactory ConfigSubsystemFacadeFactory = reference.getBundle().getBundleContext().getService(reference);
72 startPusherThread(configs, maxWaitForCapabilitiesMillis, ConfigSubsystemFacadeFactory, conflictingVersionTimeoutMillis, persisterAggregator);
73 return ConfigSubsystemFacadeFactory;
77 public void modifiedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
78 LOG.warn("Config manager facade was modified unexpectedly");
82 public void removedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
83 LOG.warn("Config manager facade was removed unexpectedly");
87 ServiceTracker<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaContextProviderServiceTracker =
88 new ServiceTracker<>(context, ConfigSubsystemFacadeFactory.class, schemaServiceTrackerCustomizer);
89 schemaContextProviderServiceTracker.open();
92 private long getConflictingVersionTimeoutMillis(PropertiesProviderBaseImpl propertiesProvider) {
93 String timeoutProperty = propertiesProvider.getProperty(CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY);
94 return timeoutProperty == null ? CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT : Long.valueOf(timeoutProperty);
97 private long getMaxWaitForCapabilitiesMillis(PropertiesProviderBaseImpl propertiesProvider) {
98 String timeoutProperty = propertiesProvider.getProperty(MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY);
99 return timeoutProperty == null ? MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT : Long.valueOf(timeoutProperty);
103 public void stop(BundleContext context) throws Exception {
104 synchronized(autoCloseables) {
105 CloseableUtil.closeAll(autoCloseables);
106 autoCloseables.clear();
107 if (registration != null) {
108 registration.unregister();
114 private void startPusherThread(final List<? extends ConfigSnapshotHolder> configs, final long maxWaitForCapabilitiesMillis,
115 final ConfigSubsystemFacadeFactory service, final long conflictingVersionTimeoutMillis, final Persister persisterAggregator){
116 LOG.debug("Creating new job queue");
117 final ConfigPusherImpl configPusher = new ConfigPusherImpl(service,
118 maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis);
119 LOG.debug("Configuration Persister got {}", service);
120 LOG.debug("Context was {}", context);
121 LOG.debug("Registration was {}", registration);
122 final Thread pushingThread = new Thread(new Runnable() {
126 if(configs != null && !configs.isEmpty()) {
127 configPusher.pushConfigs(configs);
129 if(context != null) {
130 registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
131 configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator, false);
133 LOG.warn("Unable to process configs as BundleContext is null");
135 } catch (InterruptedException e) {
136 LOG.info("ConfigPusher thread stopped",e);
138 LOG.info("Configuration Persister initialization completed.");
141 synchronized (autoCloseables) {
142 autoCloseables.add(new AutoCloseable() {
144 public void close() {
145 pushingThread.interrupt();
149 pushingThread.setDaemon(true);
150 pushingThread.start();