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=ae6c95312c9143d29f384571ffe9182b227aa862;hpb=bd2fdc53c6e7d21febc673b1d7062ca82849eb74;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 ae6c95312c..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,74 +8,140 @@ package org.opendaylight.controller.netconf.persist.impl.osgi; -import com.google.common.base.Optional; +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.NoOpStorageAdapter; -import org.opendaylight.controller.netconf.persist.impl.PersisterImpl; -import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; -import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.TLSConfiguration; +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.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(); + 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"; - @Override - public void start(BundleContext context) throws Exception { - logger.debug("ConfigPersister activator started"); - - Optional maybePersister = PersisterImpl.createFromProperties(context); - if (maybePersister.isPresent() == false) { - throw new IllegalStateException("No persister is defined in " + PersisterImpl.STORAGE_ADAPTER_CLASS_PROP - + " property. For noop persister use " + NoOpStorageAdapter.class.getCanonicalName() - + " . Persister is not operational"); - } - Optional maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context); - Optional maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context); + private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); + + private List autoCloseables; + + + @Override + public void start(final BundleContext context) throws Exception { + logger.debug("ConfigPersister starting"); + autoCloseables = new ArrayList<>(); + PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context); - InetSocketAddress address; - if (maybeTLSConfiguration.isPresent()) { - throw new UnsupportedOperationException("TLS is currently not supported for persister"); - } else if (maybeTCPAddress.isPresent()) { - address = maybeTCPAddress.get(); - } else { - throw new IllegalStateException("Netconf is not configured, persister is not operational"); - } - PersisterImpl persister = maybePersister.get(); - configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(persister, address, - platformMBeanServer); - Runnable initializationRunnable = new Runnable() { + 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 void run() { - try { - configPersisterNotificationHandler.init(); - } catch (InterruptedException e) { - logger.info("Interrupted while waiting for netconf connection"); + 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 void modifiedService(ServiceReference reference, NetconfOperationServiceFactory service) { + } + + @Override + 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; + } } }