Decouple config and netconf subsystems.
[controller.git] / opendaylight / netconf / netconf-impl / src / main / java / org / opendaylight / controller / netconf / impl / osgi / NetconfImplActivator.java
index 890bbe728804e469f0d2989253e6815ec1b85d06..8946765aa6b000ea7ed9d60c05a1d5fdc0688925 100644 (file)
  */
 package org.opendaylight.controller.netconf.impl.osgi;
 
-import com.google.common.base.Optional;
+import io.netty.channel.local.LocalAddress;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
+import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.TLSConfiguration;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.net.ssl.SSLContext;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-
 public class NetconfImplActivator implements BundleActivator {
 
-    private static final Logger logger = LoggerFactory.getLogger(NetconfImplActivator.class);
-
-    private Optional<InetSocketAddress> maybeTCPAddress;
-    private Optional<TLSConfiguration> maybeTLSConfiguration;
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfImplActivator.class);
 
     private NetconfOperationServiceFactoryTracker factoriesTracker;
-    private DefaultCommitNotificationProducer commitNot;
-    private NetconfServerDispatcher dispatch;
     private NioEventLoopGroup eventLoopGroup;
     private HashedWheelTimer timer;
+    private ServiceRegistration<NetconfMonitoringService> regMonitoring;
+
+    private BaseNotificationPublisherRegistration listenerReg;
 
     @Override
-    public void start(final BundleContext context) throws Exception {
-        maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context);
-        maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context);
-        if (maybeTCPAddress.isPresent() == false && maybeTLSConfiguration.isPresent() == false) {
-            throw new IllegalStateException("TCP nor TLS is configured, netconf not available.");
+    public void start(final BundleContext context)  {
+        try {
+            AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
+            startOperationServiceFactoryTracker(context, factoriesListener);
+
+            SessionIdProvider idProvider = new SessionIdProvider();
+            timer = new HashedWheelTimer();
+            long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context);
+
+            final NetconfMonitoringServiceImpl monitoringService = startMonitoringService(context, factoriesListener);
+
+            NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+                    timer, factoriesListener, idProvider, connectionTimeoutMillis, monitoringService);
+
+            eventLoopGroup = new NioEventLoopGroup();
+
+            NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
+                    serverNegotiatorFactory);
+            NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
+
+            LocalAddress address = NetconfConfigUtil.getNetconfLocalAddress();
+            LOG.trace("Starting local netconf server at {}", address);
+            dispatch.createLocalServer(address);
+
+            final ServiceTracker<NetconfNotificationCollector, NetconfNotificationCollector> notificationServiceTracker =
+                    new ServiceTracker<>(context, NetconfNotificationCollector.class, new ServiceTrackerCustomizer<NetconfNotificationCollector, NetconfNotificationCollector>() {
+                        @Override
+                        public NetconfNotificationCollector addingService(ServiceReference<NetconfNotificationCollector> reference) {
+                            listenerReg = context.getService(reference).registerBaseNotificationPublisher();
+                            monitoringService.setNotificationPublisher(listenerReg);
+                            return null;
+                        }
+
+                        @Override
+                        public void modifiedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
+
+                        }
+
+                        @Override
+                        public void removedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
+                            listenerReg.close();
+                            listenerReg = null;
+                            monitoringService.setNotificationPublisher(listenerReg);
+                        }
+                    });
+            notificationServiceTracker.open();
+        } catch (Exception e) {
+            LOG.warn("Unable to start NetconfImplActivator", e);
         }
-        NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+    }
+
+    private void startOperationServiceFactoryTracker(BundleContext context, NetconfOperationServiceFactoryListener factoriesListener) {
         factoriesTracker = new NetconfOperationServiceFactoryTracker(context, factoriesListener);
         factoriesTracker.open();
+    }
 
-        SessionIdProvider idProvider = new SessionIdProvider();
-        timer = new HashedWheelTimer();
-        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                timer, factoriesListener, idProvider);
-
-        commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-
-        NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
-                factoriesListener, commitNot, idProvider);
-
-        eventLoopGroup = new NioEventLoopGroup();
-
-        if (maybeTCPAddress.isPresent()) {
-            Optional<SSLContext> maybeSSLContext = Optional.absent();
-            InetSocketAddress address = maybeTCPAddress.get();
-            NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
-                    maybeSSLContext, serverNegotiatorFactory, listenerFactory);
-            dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
+    private NetconfMonitoringServiceImpl startMonitoringService(BundleContext context, AggregatedNetconfOperationServiceFactory factoriesListener) {
+        NetconfMonitoringServiceImpl netconfMonitoringServiceImpl = new NetconfMonitoringServiceImpl(factoriesListener);
+        Dictionary<String, ?> dic = new Hashtable<>();
+        regMonitoring = context.registerService(NetconfMonitoringService.class, netconfMonitoringServiceImpl, dic);
 
-            logger.info("Starting TCP netconf server at {}", address);
-            dispatch.createServer(address);
-        }
-        if (maybeTLSConfiguration.isPresent()) {
-            Optional<SSLContext> maybeSSLContext = Optional.of(maybeTLSConfiguration.get().getSslContext());
-            InetSocketAddress address = maybeTLSConfiguration.get().getAddress();
-            NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
-                    maybeSSLContext, serverNegotiatorFactory, listenerFactory);
-            dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
-
-            logger.info("Starting TLS netconf server at {}", address);
-            dispatch.createServer(address);
-        }
+        return netconfMonitoringServiceImpl;
     }
 
     @Override
-    public void stop(final BundleContext context) throws Exception {
-        logger.info("Shutting down netconf because YangStoreService service was removed");
+    public void stop(final BundleContext context) {
+        LOG.info("Shutting down netconf because YangStoreService service was removed");
 
-        commitNot.close();
-        eventLoopGroup.shutdownGracefully();
+        eventLoopGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS);
         timer.stop();
+
+        regMonitoring.unregister();
+        factoriesTracker.close();
     }
 }