X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-persister-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fpersist%2Fimpl%2Fosgi%2FConfigPersisterActivator.java;h=0cc55719e12875ece51220073657867fc3a9c21f;hp=241830ddc33ebb74a4d95168887f48c225d77bc8;hb=f776809962df87deeaa533ba995cc6fceba64d0e;hpb=3fb02545b8541925b54932e2d67a6360fe77f134 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 241830ddc3..0cc55719e1 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,73 +8,177 @@ 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.NetconfOperationProvider; +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.opendaylight.controller.netconf.util.CloseableUtil; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.InvalidSyntaxException; +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 static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - 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"; + + private List autoCloseables; - private static final String NETCONF_CONFIG_PERSISTER_PREFIX = "netconf.config.persister."; - public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass"; @Override public void start(final BundleContext context) throws Exception { logger.debug("ConfigPersister starting"); + autoCloseables = new ArrayList<>(); + PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context); + + final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider); + autoCloseables.add(persisterAggregator); + long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider); + List configs = persisterAggregator.loadLastConfigs(); + long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider); + logger.trace("Following configs will be pushed: {}", configs); + + InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis, + conflictingVersionTimeoutMillis, persisterAggregator); + OuterCustomizer outerCustomizer = new OuterCustomizer(context, innerCustomizer); + new ServiceTracker<>(context, NetconfOperationProvider.class, outerCustomizer).open(); + } - PropertiesProvider propertiesProvider = new PropertiesProvider() { - @Override - public String getProperty(String key) { - return context.getProperty(getFullKeyForReporting(key)); - } + 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 synchronized void stop(BundleContext context) throws Exception { + CloseableUtil.closeAll(autoCloseables); + } + + + @VisibleForTesting + public static String getFilterString() { + return "(&" + + "(" + Constants.OBJECTCLASS + "=" + NetconfOperationServiceFactory.class.getName() + ")" + + "(name" + "=" + "config-netconf-connector" + ")" + + ")"; + } - @Override - public String getFullKeyForReporting(String key) { - return NETCONF_CONFIG_PERSISTER_PREFIX + key; + class OuterCustomizer implements ServiceTrackerCustomizer { + private final BundleContext context; + private final InnerCustomizer innerCustomizer; + + OuterCustomizer(BundleContext context, InnerCustomizer innerCustomizer) { + this.context = context; + this.innerCustomizer = innerCustomizer; + } + + @Override + public NetconfOperationProvider addingService(ServiceReference reference) { + logger.trace("Got OuterCustomizer.addingService {}", reference); + // JMX was registered, track config-netconf-connector + Filter filter; + try { + filter = context.createFilter(getFilterString()); + } catch (InvalidSyntaxException e) { + throw new IllegalStateException(e); } - }; - - PersisterImpl persister = PersisterImpl.createFromProperties(propertiesProvider); - - InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context, - "Netconf is not configured, persister is not operational"); - configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(persister, address, - platformMBeanServer); - - // 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"); + new ServiceTracker<>(context, filter, innerCustomizer).open(); + return null; + } + + @Override + public void modifiedService(ServiceReference reference, NetconfOperationProvider service) { + + } + + @Override + public void removedService(ServiceReference reference, NetconfOperationProvider service) { + + } + } + + class InnerCustomizer implements ServiceTrackerCustomizer { + private final List configs; + private final PersisterAggregator persisterAggregator; + private final long maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis; + + + InnerCustomizer(List configs, long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis, + PersisterAggregator persisterAggregator) { + this.configs = configs; + this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis; + this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis; + this.persisterAggregator = persisterAggregator; + } + + @Override + public NetconfOperationServiceFactory addingService(ServiceReference reference) { + logger.trace("Got InnerCustomizer.addingService {}", reference); + NetconfOperationServiceFactory service = reference.getBundle().getBundleContext().getService(reference); + + final ConfigPusher configPusher = new ConfigPusher(service, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis); + logger.debug("Configuration Persister got {}", 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(); + } + }); } - }; - initializationThread = new Thread(initializationRunnable, "ConfigPersister-registrator"); - initializationThread.start(); - } + pushingThread.start(); + return service; + } + + @Override + public void modifiedService(ServiceReference reference, NetconfOperationServiceFactory service) { + } + + @Override + public void removedService(ServiceReference reference, NetconfOperationServiceFactory service) { + } - @Override - public void stop(BundleContext context) throws Exception { - initializationThread.interrupt(); - configPersisterNotificationHandler.close(); } } +