X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-persister-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fpersist%2Fimpl%2Fosgi%2FConfigPersisterActivator.java;h=76afe8eb39b95f4500fd847cfe5df9a297c656e7;hb=88f3fac27f5dbc4043cdeadacaca34bd6f57c854;hp=036cb757ae9b0d20e88b22f696e64afc7284731f;hpb=03ac144dcc9a63b7c45e59b8fe849a9762d2de1a;p=controller.git diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java index 036cb757ae..76afe8eb39 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java @@ -8,84 +8,140 @@ package org.opendaylight.controller.netconf.persist.impl.osgi; -import org.opendaylight.controller.config.persist.api.storage.StorageAdapter.PropertiesProvider; +import com.google.common.annotations.VisibleForTesting; +import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; -import org.opendaylight.controller.netconf.persist.impl.PersisterImpl; -import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; +import org.opendaylight.controller.netconf.persist.impl.ConfigPusher; +import org.opendaylight.controller.netconf.persist.impl.PersisterAggregator; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.MBeanServer; import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.util.regex.Pattern; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; public class ConfigPersisterActivator implements BundleActivator { private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterActivator.class); - private final static MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - private static final String IGNORED_MISSING_CAPABILITY_REGEX_SUFFIX = "ignoredMissingCapabilityRegex"; + public static final String MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY = "maxWaitForCapabilitiesMillis"; + private static final long MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(2); + public static final String CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY = "conflictingVersionTimeoutMillis"; + private static final long CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT = TimeUnit.SECONDS.toMillis(30); - private ConfigPersisterNotificationHandler configPersisterNotificationHandler; + public static final String NETCONF_CONFIG_PERSISTER = "netconf.config.persister"; - private Thread initializationThread; + public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass"; + + + private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); + + private List autoCloseables; - private static final String NETCONF_CONFIG_PERSISTER_PREFIX = "netconf.config.persister."; - public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass"; - public static final String DEFAULT_IGNORED_REGEX = "^urn:ietf:params:xml:ns:netconf:base:1.0"; @Override public void start(final BundleContext context) throws Exception { logger.debug("ConfigPersister starting"); + autoCloseables = new ArrayList<>(); + PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context); - PropertiesProvider propertiesProvider = new PropertiesProvider() { + + final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider); + autoCloseables.add(persisterAggregator); + final long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider); + final List configs = persisterAggregator.loadLastConfigs(); + final long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider); + logger.trace("Following configs will be pushed: {}", configs); + ServiceTrackerCustomizer configNetconfCustomizer = new ServiceTrackerCustomizer() { @Override - public String getProperty(String key) { - return context.getProperty(getFullKeyForReporting(key)); + public NetconfOperationServiceFactory addingService(ServiceReference reference) { + NetconfOperationServiceFactory service = reference.getBundle().getBundleContext().getService(reference); + final ConfigPusher configPusher = new ConfigPusher(service, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis); + logger.debug("Configuration Persister got %s", service); + final Thread pushingThread = new Thread(new Runnable() { + @Override + public void run() { + configPusher.pushConfigs(configs); + logger.info("Configuration Persister initialization completed."); + ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator); + synchronized (ConfigPersisterActivator.this) { + autoCloseables.add(jmxNotificationHandler); + } + } + }, "config-pusher"); + synchronized (ConfigPersisterActivator.this){ + autoCloseables.add(new AutoCloseable() { + @Override + public void close() throws Exception { + pushingThread.interrupt(); + } + }); + } + pushingThread.start(); + return service; } @Override - public String getFullKeyForReporting(String key) { - return NETCONF_CONFIG_PERSISTER_PREFIX + key; + public void modifiedService(ServiceReference reference, NetconfOperationServiceFactory service) { } - }; - String regexProperty = propertiesProvider.getProperty(IGNORED_MISSING_CAPABILITY_REGEX_SUFFIX); - String regex; - if (regexProperty != null) { - regex = regexProperty; - } else { - regex = DEFAULT_IGNORED_REGEX; - } - Pattern ignoredMissingCapabilityRegex = Pattern.compile(regex); - PersisterImpl persister = PersisterImpl.createFromProperties(propertiesProvider); - - InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context, - "Netconf is not configured, persister is not operational"); - configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(persister, address, - platformMBeanServer, ignoredMissingCapabilityRegex); - - // offload initialization to another thread in order to stop blocking activator - Runnable initializationRunnable = new Runnable() { @Override - public void run() { - try { - configPersisterNotificationHandler.init(); - } catch (InterruptedException e) { - logger.info("Interrupted while waiting for netconf connection"); - } + public void removedService(ServiceReference reference, NetconfOperationServiceFactory service) { } }; - initializationThread = new Thread(initializationRunnable, "ConfigPersister-registrator"); - initializationThread.start(); + + Filter filter = context.createFilter(getFilterString()); + + ServiceTracker tracker = + new ServiceTracker<>(context, filter, configNetconfCustomizer); + tracker.open(); + } + + + @VisibleForTesting + public static String getFilterString() { + return "(&" + + "(" + Constants.OBJECTCLASS + "=" + NetconfOperationServiceFactory.class.getName() + ")" + + "(name" + "=" + "config-netconf-connector" + ")" + + ")"; + } + + private long getConflictingVersionTimeoutMillis(PropertiesProviderBaseImpl propertiesProvider) { + String timeoutProperty = propertiesProvider.getProperty(CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY); + return timeoutProperty == null ? CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); + } + + private long getMaxWaitForCapabilitiesMillis(PropertiesProviderBaseImpl propertiesProvider) { + String timeoutProperty = propertiesProvider.getProperty(MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY); + return timeoutProperty == null ? MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); } @Override - public void stop(BundleContext context) throws Exception { - initializationThread.interrupt(); - configPersisterNotificationHandler.close(); + public synchronized void stop(BundleContext context) throws Exception { + Exception lastException = null; + for (AutoCloseable autoCloseable : autoCloseables) { + try { + autoCloseable.close(); + } catch (Exception e) { + if (lastException == null) { + lastException = e; + } else { + lastException.addSuppressed(e); + } + } + } + if (lastException != null) { + throw lastException; + } } }