import static java.util.Objects.requireNonNull;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
import org.opendaylight.netconf.server.api.monitoring.NetconfMonitoringService;
import org.opendaylight.netconf.server.api.operations.NetconfOperationServiceFactory;
import org.opendaylight.netconf.server.osgi.NetconfMonitoringServiceImpl;
public final class DefaultNetconfMonitoringService extends NetconfMonitoringServiceImpl {
static final String FACTORY_NAME = "org.opendaylight.netconf.impl.mdsal.DefaultNetconfMonitoringService";
+ private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder()
+ .setNameFormat("netconf-server-monitoring-%d")
+ .setDaemon(true)
+ .build();
private static final String OP_PROVIDER_PROP = ".opProvider";
- private static final String THREAD_POOL_PROP = ".threadPool";
private static final String UPDATE_INTERVAL_PROP = ".updateInterval";
+ private DefaultNetconfMonitoringService(final NetconfOperationServiceFactory opProvider, final long periodSeconds) {
+ super(opProvider, THREAD_FACTORY, periodSeconds, TimeUnit.SECONDS);
+ }
+
@Activate
public DefaultNetconfMonitoringService(final Map<String, ?> properties) {
- super(OSGiNetconfServer.extractProp(properties, OP_PROVIDER_PROP, NetconfOperationServiceFactory.class),
- OSGiNetconfServer.extractProp(properties, THREAD_POOL_PROP, ScheduledExecutorService.class),
+ this(OSGiNetconfServer.extractProp(properties, OP_PROVIDER_PROP, NetconfOperationServiceFactory.class),
OSGiNetconfServer.extractProp(properties, UPDATE_INTERVAL_PROP, Long.class));
}
super.close();
}
- static Map<String, ?> props(final NetconfOperationServiceFactory opProvider,
- final ScheduledExecutorService threadPool, final long updateInterval) {
+ static Map<String, ?> props(final NetconfOperationServiceFactory opProvider, final long updateInterval) {
return Map.of(
"type", "netconf-server-monitoring",
OP_PROVIDER_PROP, requireNonNull(opProvider),
- THREAD_POOL_PROP, requireNonNull(threadPool),
UPDATE_INTERVAL_PROP, updateInterval);
}
}
import io.netty.util.Timer;
import java.util.Map;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.opendaylight.netconf.server.NetconfServerSessionNegotiatorFactory;
import org.opendaylight.netconf.server.ServerTransportInitializer;
import org.opendaylight.netconf.server.api.SessionIdProvider;
final ComponentFactory<DefaultNetconfMonitoringService> monitoringFactory,
@Reference(target = "(type=mapper-aggregator-registry)")
final NetconfOperationServiceFactory mapperAggregatorRegistry,
- @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
- final ScheduledThreadPool sshScheduledExecutor,
@Reference(target = "(type=global-timer)") final Timer timer,
@Reference final SessionIdProvider sessionIdProvider,
final Configuration configuration) {
mappers.onAddNetconfOperationServiceFactory(mapperAggregatorRegistry);
monitoring = monitoringFactory.newInstance(FrameworkUtil.asDictionary(DefaultNetconfMonitoringService.props(
- mapperAggregatorRegistry, sshScheduledExecutor.getExecutor(),
- configuration.monitoring$_$update$_$interval())));
+ mapperAggregatorRegistry, configuration.monitoring$_$update$_$interval())));
serverTransportInitializer = new ServerTransportInitializer(NetconfServerSessionNegotiatorFactory.builder()
.setTimer(timer)
.setAggregatedOpService(mappers)
@AttributeDefinition(min = "0")
long keep$_$alive$_$millis$_$flexible$_$thread$_$pool()
default GlobalNetconfProcessingExecutor.DEFAULT_KEEPALIVE_MILLIS;
- @AttributeDefinition(min = "1")
- int max$_$thread$_$count$_$scheduled$_$thread$_$pool()
- default GlobalNetconfSshScheduledExecutor.DEFAULT_MAX_THREAD_COUNT;
}
private static final Logger LOG = LoggerFactory.getLogger(GlobalNetconfConfiguration.class);
private final ComponentFactory<GlobalNetconfProcessingExecutor> processingFactory;
- private final ComponentFactory<GlobalNetconfSshScheduledExecutor> sshScheduledFactory;
private GlobalNetconfThreadFactory threadFactory;
private ComponentInstance<GlobalNetconfProcessingExecutor> processingExecutor;
private Map<String, ?> processingProps;
- private ComponentInstance<GlobalNetconfSshScheduledExecutor> sshScheduledExecutor;
- private Map<String, ?> sshScheduledProps;
@Activate
public GlobalNetconfConfiguration(
@Reference(target = "(component.factory=" + GlobalNetconfProcessingExecutor.FACTORY_NAME + ")")
final ComponentFactory<GlobalNetconfProcessingExecutor> processingFactory,
- @Reference(target = "(component.factory=" + GlobalNetconfSshScheduledExecutor.FACTORY_NAME + ")")
- final ComponentFactory<GlobalNetconfSshScheduledExecutor> sshScheduledFactory,
final Configuration configuration) {
this.processingFactory = requireNonNull(processingFactory);
- this.sshScheduledFactory = requireNonNull(sshScheduledFactory);
threadFactory = new GlobalNetconfThreadFactory(configuration.name$_$prefix());
processingProps = GlobalNetconfProcessingExecutor.props(threadFactory, configuration);
processingExecutor = processingFactory.newInstance(FrameworkUtil.asDictionary(processingProps));
- sshScheduledProps = GlobalNetconfSshScheduledExecutor.props(threadFactory, configuration);
- sshScheduledExecutor = sshScheduledFactory.newInstance(FrameworkUtil.asDictionary(sshScheduledProps));
LOG.info("Global NETCONF configuration pools started");
}
if (!threadFactory.getNamePrefix().equals(newNamePrefix)) {
threadFactory = new GlobalNetconfThreadFactory(newNamePrefix);
processingProps = null;
- sshScheduledProps = null;
LOG.debug("Forcing restart of all executors");
}
LOG.debug("Processing executor restarted with {}", processingProps);
}
- final var newSshScheduledProps = GlobalNetconfSshScheduledExecutor.props(threadFactory, configuration);
- if (!newSshScheduledProps.equals(sshScheduledProps)) {
- sshScheduledProps = newSshScheduledProps;
- toDispose.add(sshScheduledExecutor);
- sshScheduledExecutor = sshScheduledFactory.newInstance(FrameworkUtil.asDictionary(sshScheduledProps));
- LOG.debug("Scheduled executor restarted with {}", sshScheduledProps);
- }
-
toDispose.forEach(ComponentInstance::dispose);
}
void deactivate() {
processingExecutor.dispose();
processingExecutor = null;
- sshScheduledExecutor.dispose();
- sshScheduledExecutor = null;
threadFactory = null;
LOG.info("Global NETCONF configuration pools stopped");
}
+++ /dev/null
-/*
- * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.netconf.config;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Map;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.util.ScheduledThreadPoolWrapper;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-
-@Singleton
-@Component(factory = GlobalNetconfSshScheduledExecutor.FACTORY_NAME, service = ScheduledThreadPool.class)
-public final class GlobalNetconfSshScheduledExecutor extends ScheduledThreadPoolWrapper {
- public static final String OSGI_TYPE = "global-netconf-ssh-scheduled-executor";
- public static final int DEFAULT_MAX_THREAD_COUNT = 8;
-
- // OSGi DS Component Factory name
- static final String FACTORY_NAME = "org.opendaylight.netconf.config.GlobalNetconfSshScheduledExecutor";
-
- private static final String PROP_MAX_THREAD_COUNT = ".maxThreadCount";
- private static final String PROP_THREAD_FACTORY = ".threadFactory";
-
- public GlobalNetconfSshScheduledExecutor(final GlobalNetconfThreadFactory threadFactory, final int maxThreadCount) {
- super(maxThreadCount, threadFactory);
- }
-
- @Inject
- public GlobalNetconfSshScheduledExecutor(final GlobalNetconfThreadFactory threadFactory) {
- this(threadFactory, DEFAULT_MAX_THREAD_COUNT);
- }
-
- @Activate
- public GlobalNetconfSshScheduledExecutor(final Map<String, ?> properties) {
- this(GlobalNetconfConfiguration.extractProp(properties, PROP_THREAD_FACTORY, GlobalNetconfThreadFactory.class),
- GlobalNetconfConfiguration.extractProp(properties, PROP_MAX_THREAD_COUNT, Integer.class));
- }
-
- @Override
- @PreDestroy
- @Deactivate
- public void close() {
- super.close();
- }
-
- static Map<String, ?> props(final GlobalNetconfThreadFactory threadFactory, final Configuration configuration) {
- return Map.of(
- "type", OSGI_TYPE,
- PROP_MAX_THREAD_COUNT, configuration.max$_$thread$_$count$_$scheduled$_$thread$_$pool(),
- PROP_THREAD_FACTORY, requireNonNull(threadFactory));
- }
-}
import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory;
/**
- * Shared {@link NamingThreadPoolFactory} for {@link GlobalNetconfProcessingExecutor} and
- * {@link GlobalNetconfSshScheduledExecutor}.
+ * Shared {@link NamingThreadPoolFactory} for {@link GlobalNetconfProcessingExecutor}.
*/
@NonNullByDefault
public final class GlobalNetconfThreadFactory extends NamingThreadPoolFactory {
import static java.util.Objects.requireNonNull;
import java.util.Optional;
+import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.opendaylight.netconf.server.api.monitoring.NetconfMonitoringService;
import org.opendaylight.netconf.server.api.monitoring.SessionListener;
public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, AutoCloseable {
private final NetconfCapabilityMonitoringService capabilityMonitoring;
private final NetconfSessionMonitoringService sessionMonitoring;
+ private final ScheduledExecutorService executorService;
private NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider,
final NetconfSessionMonitoringService sessionMonitoring) {
capabilityMonitoring = new NetconfCapabilityMonitoringService(opProvider);
this.sessionMonitoring = requireNonNull(sessionMonitoring);
+ executorService = null;
}
public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider) {
this(opProvider, new NetconfSessionMonitoringService.WithoutUpdates());
}
+ public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider,
+ final ThreadFactory threadFactory, final long period, final TimeUnit timeUnit) {
+ capabilityMonitoring = new NetconfCapabilityMonitoringService(opProvider);
+ if (period > 0) {
+ executorService = Executors.unconfigurableScheduledExecutorService(
+ // Note: 0 core pool size, as we want to shut the thread down when we do not have listeners
+ Executors.newScheduledThreadPool(0, threadFactory));
+ sessionMonitoring = new NetconfSessionMonitoringService.WithUpdates(executorService, period, timeUnit);
+ } else {
+ executorService = null;
+ sessionMonitoring = new NetconfSessionMonitoringService.WithoutUpdates();
+ }
+ }
+
public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider,
final ScheduledExecutorService threadPool, final long periodSeconds) {
this(opProvider, periodSeconds > 0
public void close() {
capabilityMonitoring.close();
sessionMonitoring.close();
+ if (executorService != null) {
+ executorService.shutdown();
+ }
}
}