<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-topology</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>netconf-api</artifactId>
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.netconf.callhome.server.CallHomeStatusRecorder;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
import org.opendaylight.netconf.topology.spi.NetconfNodeHandler;
import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
@Inject
public CallHomeMountService(
final @Reference(target = "(type=global-timer)") Timer timer,
- final @Reference(target = "(type=global-netconf-processing-executor)") ThreadPool processingThreadPool,
+ final @Reference NetconfTopologySchemaAssembler schemaAssembler,
final @Reference SchemaResourceManager schemaRepositoryProvider,
final @Reference BaseNetconfSchemas baseSchemas,
final @Reference DataBroker dataBroker,
final @Reference DOMMountPointService mountService,
final @Reference DeviceActionFactory deviceActionFactory) {
- this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, timer,
- processingThreadPool.getExecutor(), schemaRepositoryProvider, baseSchemas,
+ this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, timer, schemaAssembler, schemaRepositoryProvider, baseSchemas,
dataBroker, mountService, deviceActionFactory);
}
- public CallHomeMountService(final String topologyId, final Timer timer, final Executor executor,
- final SchemaResourceManager schemaRepositoryProvider, final BaseNetconfSchemas baseSchemas,
- final DataBroker dataBroker, final DOMMountPointService mountService,
+ public CallHomeMountService(final String topologyId, final Timer timer,
+ final NetconfTopologySchemaAssembler schemaAssembler, final SchemaResourceManager schemaRepositoryProvider,
+ final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker, final DOMMountPointService mountService,
final DeviceActionFactory deviceActionFactory) {
final var clientConfBuilderFactory = createClientConfigurationBuilderFactory();
final var clientFactory = createClientFactory();
- topology = new CallHomeTopology(topologyId, clientFactory, timer, executor,
+ topology = new CallHomeTopology(topologyId, clientFactory, timer, schemaAssembler,
schemaRepositoryProvider, dataBroker, mountService, clientConfBuilderFactory,
baseSchemas, deviceActionFactory);
}
}
@Override
- public void remove(String id) {
+ public void remove(final String id) {
super.remove(id);
topology.disableNode(new NodeId(id));
}
}
@Override
- public void remove(String id) {
+ public void remove(final String id) {
super.remove(id);
topology.disableNode(new NodeId(id));
}
package org.opendaylight.netconf.callhome.mount;
import io.netty.util.Timer;
-import java.util.concurrent.Executor;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.netconf.client.NetconfClientFactory;
import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
// Non-final for mocking
class CallHomeTopology extends AbstractNetconfTopology {
CallHomeTopology(final String topologyId, final NetconfClientFactory clientFactory, final Timer timer,
- final Executor processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
+ final NetconfTopologySchemaAssembler schemaAssembler, final SchemaResourceManager schemaRepositoryProvider,
final DataBroker dataBroker, final DOMMountPointService mountPointService,
final NetconfClientConfigurationBuilderFactory builderFactory, final BaseNetconfSchemas baseSchemas,
final DeviceActionFactory deviceActionFactory) {
- super(topologyId, clientFactory, timer, processingExecutor, schemaRepositoryProvider, dataBroker,
+ super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
mountPointService, builderFactory, deviceActionFactory, baseSchemas);
}
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-binding-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>netconf-api</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>netconf-topology</artifactId>
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.util.Timer;
import java.util.Collection;
-import java.util.concurrent.Executor;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.aaa.encrypt.AAAEncryptionService;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
public NetconfTopologyImpl(
@Reference(target = "(type=netconf-client-factory)") final NetconfClientFactory clientFactory,
@Reference(target = "(type=global-timer)") final Timer timer,
- @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingThreadPool,
+ @Reference final NetconfTopologySchemaAssembler schemaAssembler,
@Reference final SchemaResourceManager schemaRepositoryProvider, @Reference final DataBroker dataBroker,
@Reference final DOMMountPointService mountPointService,
@Reference final AAAEncryptionService encryptionService,
@Reference final NetconfClientConfigurationBuilderFactory builderFactory,
@Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas,
@Reference final DeviceActionFactory deviceActionFactory) {
- this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientFactory, timer, processingThreadPool.getExecutor(),
- schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
- rpcProviderService, baseSchemas, deviceActionFactory);
+ this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientFactory, timer, schemaAssembler, schemaRepositoryProvider,
+ dataBroker, mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas,
+ deviceActionFactory);
}
public NetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientclientFactory,
- final Timer timer, final Executor processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
- final DataBroker dataBroker, final DOMMountPointService mountPointService,
- final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory,
- final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
- this(topologyId, clientclientFactory, timer, processingExecutor, schemaRepositoryProvider, dataBroker,
+ final Timer timer, final NetconfTopologySchemaAssembler schemaAssembler,
+ final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
+ final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
+ final NetconfClientConfigurationBuilderFactory builderFactory, final RpcProviderService rpcProviderService,
+ final BaseNetconfSchemas baseSchemas) {
+ this(topologyId, clientclientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas, null);
}
@SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
justification = "DTCL registration of 'this'")
public NetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory, final Timer timer,
- final Executor processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
+ final NetconfTopologySchemaAssembler schemaAssembler, final SchemaResourceManager schemaRepositoryProvider,
final DataBroker dataBroker, final DOMMountPointService mountPointService,
final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory,
final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas,
final DeviceActionFactory deviceActionFactory) {
- super(topologyId, clientFactory, timer, processingExecutor, schemaRepositoryProvider, dataBroker,
+ super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
mountPointService, builderFactory, deviceActionFactory, baseSchemas);
LOG.debug("Registering datastore listener");
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import com.google.common.util.concurrent.MoreExecutors;
import io.netty.util.Timer;
import java.util.List;
-import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
@Mock
private DataTreeModification<Node> treeMod;
- private TestingNetconfTopologyImpl topology;
- private TestingNetconfTopologyImpl spyTopology;
-
@Test
void testOnDataTreeChange() throws Exception {
doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
- topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(), mockedClientFactory,
- mockedTimer, MoreExecutors.directExecutor(), mockedResourceManager, dataBroker, mountPointService,
- encryptionService, builderFactory, rpcProviderService,
- new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
- //verify initialization of topology
- verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
- new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
-
- spyTopology = spy(topology);
-
- final var key = new NodeKey(new NodeId("testing-node"));
- final var node = new NodeBuilder()
- .withKey(key)
- .addAugmentation(new NetconfNodeBuilder()
- .setLockDatastore(true)
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(Uint16.valueOf(9999)))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
- .setMinBackoffMillis(Uint16.valueOf(100))
- .setKeepaliveDelay(Uint32.valueOf(1000))
- .setTcpOnly(true)
- .setCredentials(new LoginPwUnencryptedBuilder()
- .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder()
- .setUsername("testuser")
- .setPassword("testpassword")
+ try (var schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS)) {
+ final var topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(),
+ mockedClientFactory, mockedTimer, schemaAssembler, mockedResourceManager, dataBroker, mountPointService,
+ encryptionService, builderFactory, rpcProviderService,
+ new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
+ //verify initialization of topology
+ verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
+ new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
+
+ final var spyTopology = spy(topology);
+
+ final var key = new NodeKey(new NodeId("testing-node"));
+ final var node = new NodeBuilder()
+ .withKey(key)
+ .addAugmentation(new NetconfNodeBuilder()
+ .setLockDatastore(true)
+ .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+ .setPort(new PortNumber(Uint16.valueOf(9999)))
+ .setReconnectOnChangedSchema(true)
+ .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
+ .setMinBackoffMillis(Uint16.valueOf(100))
+ .setKeepaliveDelay(Uint32.valueOf(1000))
+ .setTcpOnly(true)
+ .setCredentials(new LoginPwUnencryptedBuilder()
+ .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder()
+ .setUsername("testuser")
+ .setPassword("testpassword")
+ .build())
.build())
.build())
- .build())
- .build();
+ .build();
- doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
- doReturn(node).when(objMod).getDataAfter();
+ doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
+ doReturn(node).when(objMod).getDataAfter();
- doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_PATH.child(Node.class, key)))
- .when(treeMod).getRootPath();
- final var changes = List.of(treeMod);
+ doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION,
+ TOPOLOGY_PATH.child(Node.class, key))).when(treeMod).getRootPath();
+ final var changes = List.of(treeMod);
- doReturn(objMod).when(treeMod).getRootNode();
- spyTopology.onDataTreeChanged(changes);
- verify(spyTopology).ensureNode(node);
+ doReturn(objMod).when(treeMod).getRootNode();
+ spyTopology.onDataTreeChanged(changes);
+ verify(spyTopology).ensureNode(node);
- doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
- spyTopology.onDataTreeChanged(changes);
- verify(spyTopology).deleteNode(key.getNodeId());
+ doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
+ spyTopology.onDataTreeChanged(changes);
+ verify(spyTopology).deleteNode(key.getNodeId());
- doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
- spyTopology.onDataTreeChanged(changes);
+ doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
+ spyTopology.onDataTreeChanged(changes);
- // one in previous creating and deleting node and one in updating
- verify(spyTopology, times(2)).ensureNode(node);
+ // one in previous creating and deleting node and one in updating
+ verify(spyTopology, times(2)).ensureNode(node);
+ }
}
private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
TestingNetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory, final Timer timer,
- final Executor processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
- final DataBroker dataBroker, final DOMMountPointService mountPointService,
- final AAAEncryptionService encryptionService,
+ final NetconfTopologySchemaAssembler schemaAssembler,
+ final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
+ final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
final NetconfClientConfigurationBuilderFactory builderFactory,
final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
- super(topologyId, clientFactory, timer, processingExecutor, schemaRepositoryProvider,
+ super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider,
dataBroker, mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemas);
}
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-clustering-commons</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-singleton-common-api</artifactId>
masterSalFacade = createSalFacade(netconfNode.requireLockDatastore());
nodeHandler = new NetconfNodeHandler(setup.getNetconfClientFactory(), setup.getTimer(), setup.getBaseSchemas(),
- schemaManager, setup.getProcessingExecutor(), builderFactory, deviceActionFactory, masterSalFacade,
+ schemaManager, setup.getSchemaAssembler(), builderFactory, deviceActionFactory, masterSalFacade,
remoteDeviceId, configNode.getNodeId(), netconfNode, nodeOptional);
nodeHandler.connect();
}
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.aaa.encrypt.AAAEncryptionService;
import org.opendaylight.controller.cluster.ActorSystemProvider;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.DataObjectModification;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev231121.NetconfNode;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
private final DataBroker dataBroker;
private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
private final Timer timer;
- private final Executor processingExecutor;
+ private final NetconfTopologySchemaAssembler schemaAssembler;
private final ActorSystem actorSystem;
private final NetconfClientFactory clientFactory;
private final String topologyId;
@Reference final DataBroker dataBroker,
@Reference final ClusterSingletonServiceProvider clusterSingletonServiceProvider,
@Reference(target = "(type=global-timer)") final Timer timer,
- @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingExecutor,
+ @Reference final NetconfTopologySchemaAssembler schemaAssembler,
@Reference final ActorSystemProvider actorSystemProvider,
@Reference(target = "(type=netconf-client-factory)") final NetconfClientFactory clientFactory,
@Reference final DOMMountPointService mountPointService,
@Reference final SchemaResourceManager resourceManager,
@Reference final NetconfClientConfigurationBuilderFactory builderFactory,
final Configuration configuration) {
- this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, processingExecutor.getExecutor(),
+ this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
actorSystemProvider.getActorSystem(), clientFactory, mountPointService, encryptionService,
rpcProviderService, deviceActionFactory, resourceManager, builderFactory, configuration.topology$_$id(),
Uint16.valueOf(configuration.write$_$transaction$_$idle$_$timeout()));
@Inject
public NetconfTopologyManager(final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker,
final ClusterSingletonServiceProvider clusterSingletonServiceProvider, final Timer timer,
- final ThreadPool processingExecutor, final ActorSystemProvider actorSystemProvider,
+ final NetconfTopologySchemaAssembler schemaAssembler, final ActorSystemProvider actorSystemProvider,
final NetconfClientFactory clientFactory, final DOMMountPointService mountPointService,
final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
final DeviceActionFactory deviceActionFactory, final SchemaResourceManager resourceManager,
final NetconfClientConfigurationBuilderFactory builderFactory) {
- this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, processingExecutor.getExecutor(),
+ this(baseSchemas, dataBroker, clusterSingletonServiceProvider, timer, schemaAssembler,
actorSystemProvider.getActorSystem(), clientFactory, mountPointService, encryptionService,
rpcProviderService, deviceActionFactory, resourceManager, builderFactory,
NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, Uint16.ZERO);
justification = "Non-final for mocking, but we register for DTCL and that leaks 'this'")
public NetconfTopologyManager(final BaseNetconfSchemas baseSchemas, final DataBroker dataBroker,
final ClusterSingletonServiceProvider clusterSingletonServiceProvider, final Timer timer,
- final Executor processingExecutor, final ActorSystem actorSystem, final NetconfClientFactory clientFactory,
- final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
- final RpcProviderService rpcProviderService, final DeviceActionFactory deviceActionFactory,
- final SchemaResourceManager resourceManager, final NetconfClientConfigurationBuilderFactory builderFactory,
- final String topologyId, final Uint16 writeTransactionIdleTimeout) {
+ final NetconfTopologySchemaAssembler schemaAssembler, final ActorSystem actorSystem,
+ final NetconfClientFactory clientFactory, final DOMMountPointService mountPointService,
+ final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
+ final DeviceActionFactory deviceActionFactory, final SchemaResourceManager resourceManager,
+ final NetconfClientConfigurationBuilderFactory builderFactory, final String topologyId,
+ final Uint16 writeTransactionIdleTimeout) {
this.baseSchemas = requireNonNull(baseSchemas);
this.dataBroker = requireNonNull(dataBroker);
this.clusterSingletonServiceProvider = requireNonNull(clusterSingletonServiceProvider);
this.timer = requireNonNull(timer);
- this.processingExecutor = requireNonNull(processingExecutor);
+ this.schemaAssembler = requireNonNull(schemaAssembler);
this.actorSystem = requireNonNull(actorSystem);
this.clientFactory = requireNonNull(clientFactory);
this.topologyId = requireNonNull(topologyId);
.setNode(node)
.setActorSystem(actorSystem)
.setTimer(timer)
- .setProcessingExecutor(processingExecutor)
+ .setSchemaAssembler(schemaAssembler)
.setTopologyId(topologyId)
.setNetconfClientFactory(clientFactory)
.setSchemaResourceDTO(resourceManager.getSchemaResources(netconfNode.getSchemaCacheDirectory(), deviceId))
import akka.actor.ActorSystem;
import io.netty.util.Timer;
import java.time.Duration;
-import java.util.concurrent.Executor;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.netconf.client.NetconfClientFactory;
import org.opendaylight.netconf.client.mdsal.NetconfDevice;
import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
private final InstanceIdentifier<Node> instanceIdentifier;
private final Node node;
private final Timer timer;
- private final Executor processingExecutor;
+ private final NetconfTopologySchemaAssembler schemaAssembler;
private final ActorSystem actorSystem;
private final NetconfClientFactory netconfClientFactory;
private final String topologyId;
instanceIdentifier = builder.getInstanceIdentifier();
node = builder.getNode();
timer = builder.getTimer();
- processingExecutor = builder.getProcessingExecutor();
+ schemaAssembler = builder.getSchemaAssembler();
actorSystem = builder.getActorSystem();
netconfClientFactory = builder.getNetconfClientFactory();
topologyId = builder.getTopologyId();
return node;
}
- public Executor getProcessingExecutor() {
- return processingExecutor;
+ public NetconfTopologySchemaAssembler getSchemaAssembler() {
+ return schemaAssembler;
}
public Timer getTimer() {
private InstanceIdentifier<Node> instanceIdentifier;
private Node node;
private Timer timer;
- private Executor processingExecutor;
+ private NetconfTopologySchemaAssembler schemaAssembler;
private ActorSystem actorSystem;
private String topologyId;
private NetconfClientFactory netconfClientFactory;
return this;
}
- Executor getProcessingExecutor() {
- return processingExecutor;
+
+ NetconfTopologySchemaAssembler getSchemaAssembler() {
+ return schemaAssembler;
}
- public Builder setProcessingExecutor(final Executor processingExecutor) {
- this.processingExecutor = processingExecutor;
+ public Builder setSchemaAssembler(final NetconfTopologySchemaAssembler schemaAssembler) {
+ this.schemaAssembler = schemaAssembler;
return this;
}
import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import com.typesafe.config.ConfigFactory;
import io.netty.util.Timer;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactoryImpl;
import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
private final ContainerNode getTopInput = ImmutableNodes.containerNode(GetTopInput.QNAME);
private SchemaResourceManager resourceManager;
+ private NetconfTopologySchemaAssembler schemaAssembler;
@Before
public void setUp() throws Exception {
deleteCacheDir();
+ schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS);
+
resourceManager = new DefaultSchemaResourceManager(new DefaultYangParserFactory(), TEST_ROOT_DIRECTORY,
TEST_DEFAULT_SUBDIR);
deleteCacheDir();
TestKit.shutdownActorSystem(slaveSystem, true);
TestKit.shutdownActorSystem(masterSystem, true);
+ schemaAssembler.close();
}
private void setupMaster() throws Exception {
YangTextSchemaSource.class, 1));
masterNetconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, masterDataBroker,
- masterClusterSingletonServiceProvider, mockTimer, MoreExecutors.directExecutor(), masterSystem,
+ masterClusterSingletonServiceProvider, mockTimer, schemaAssembler, masterSystem,
mockClientFactory, masterMountPointService, mockEncryptionService, mockRpcProviderService,
deviceActionFactory, resourceManager, builderFactory, TOPOLOGY_ID, Uint16.ZERO) {
@Override
.registerClusterSingletonService(any());
slaveNetconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, slaveDataBroker,
- mockSlaveClusterSingletonServiceProvider, mockTimer, MoreExecutors.directExecutor(), slaveSystem,
+ mockSlaveClusterSingletonServiceProvider, mockTimer, schemaAssembler, slaveSystem,
mockClientFactory, slaveMountPointService, mockEncryptionService, mockRpcProviderService,
deviceActionFactory, resourceManager, builderFactory, TOPOLOGY_ID, Uint16.ZERO) {
@Override
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
@Mock
private NetconfClientConfigurationBuilderFactory builderFactory;
+ private NetconfTopologySchemaAssembler schemaAssembler;
private DataBroker dataBroker;
private final Map<InstanceIdentifier<Node>, Function<NetconfTopologySetup, NetconfTopologyContext>>
@Before
public void setUp() throws Exception {
+ schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS);
+
AbstractDataBrokerTest dataBrokerTest = new AbstractDataBrokerTest() {
@Override
protected Set<YangModuleInfo> getModuleInfos() throws Exception {
doReturn(mockRpcReg).when(rpcProviderService).registerRpcImplementations(any());
netconfTopologyManager = new NetconfTopologyManager(BASE_SCHEMAS, dataBroker, clusterSingletonServiceProvider,
- timer, processingService, actorSystem, clientFactory, mountPointService, encryptionService,
+ timer, schemaAssembler, actorSystem, clientFactory, mountPointService, encryptionService,
rpcProviderService, actionFactory, new DefaultSchemaResourceManager(new DefaultYangParserFactory()),
builderFactory, TOPOLOGY_ID, Uint16.ZERO) {
@Override
};
}
+ @After
+ public void after() {
+ schemaAssembler.close();
+ }
+
@Test
public void testRegisterDataTreeChangeListener() throws Exception {
await().atMost(5, TimeUnit.SECONDS).until(() -> {
<groupId>org.opendaylight.aaa</groupId>
<artifactId>aaa-encrypt-service</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>threadpool-config-impl</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-topology</artifactId>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.component.annotations</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.metatype.annotations</artifactId>
+ </dependency>
<dependency>
<groupId>org.awaitility</groupId>
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
private final NetconfClientConfigurationBuilderFactory builderFactory;
private final Timer timer;
- protected final Executor processingExecutor;
+ protected final NetconfTopologySchemaAssembler schemaAssembler;
protected final DataBroker dataBroker;
protected final DOMMountPointService mountPointService;
protected final String topologyId;
protected AbstractNetconfTopology(final String topologyId, final NetconfClientFactory clientFactory,
- final Timer timer, final Executor processingExecutor, final SchemaResourceManager schemaManager,
- final DataBroker dataBroker, final DOMMountPointService mountPointService,
- final NetconfClientConfigurationBuilderFactory builderFactory,
+ final Timer timer, final NetconfTopologySchemaAssembler schemaAssembler,
+ final SchemaResourceManager schemaManager, final DataBroker dataBroker,
+ final DOMMountPointService mountPointService, final NetconfClientConfigurationBuilderFactory builderFactory,
final DeviceActionFactory deviceActionFactory, final BaseNetconfSchemas baseSchemas) {
this.topologyId = requireNonNull(topologyId);
this.clientFactory = requireNonNull(clientFactory);
this.timer = requireNonNull(timer);
- this.processingExecutor = requireNonNull(processingExecutor);
+ this.schemaAssembler = requireNonNull(schemaAssembler);
this.schemaManager = requireNonNull(schemaManager);
this.deviceActionFactory = deviceActionFactory;
this.dataBroker = requireNonNull(dataBroker);
final NetconfNodeHandler nodeHandler;
try {
- nodeHandler = new NetconfNodeHandler(clientFactory, timer, baseSchemas, schemaManager, processingExecutor,
+ nodeHandler = new NetconfNodeHandler(clientFactory, timer, baseSchemas, schemaManager, schemaAssembler,
builderFactory, deviceActionFactory, deviceSalFacade, deviceId, nodeId, netconfNode, nodeOptional);
} catch (IllegalArgumentException e) {
// This is a workaround for NETCONF-1114 where the encrypted password's lexical structure is not enforced
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.lock.qual.GuardedBy;
import org.checkerframework.checker.lock.qual.Holding;
public NetconfNodeHandler(final NetconfClientFactory clientFactory, final Timer timer,
final BaseNetconfSchemas baseSchemas, final SchemaResourceManager schemaManager,
- final Executor processingExecutor, final NetconfClientConfigurationBuilderFactory builderFactory,
+ final NetconfTopologySchemaAssembler schemaAssembler,
+ final NetconfClientConfigurationBuilderFactory builderFactory,
final DeviceActionFactory deviceActionFactory, final RemoteDeviceHandler delegate,
final RemoteDeviceId deviceId, final NodeId nodeId, final NetconfNode node,
final NetconfNodeAugmentedOptional nodeOptional) {
device = new NetconfDeviceBuilder()
.setReconnectOnSchemasChange(node.requireReconnectOnChangedSchema())
.setSchemaResourcesDTO(resources)
- .setGlobalProcessingExecutor(processingExecutor)
+ .setGlobalProcessingExecutor(schemaAssembler.executor())
.setId(deviceId)
.setSalFacade(salFacade)
.setDeviceActionFactory(deviceActionFactory)
--- /dev/null
+/*
+ * Copyright (c) 2024 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.topology.spi;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.controller.config.threadpool.util.FlexibleThreadPoolWrapper;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@NonNullByDefault
+@Component(service = NetconfTopologySchemaAssembler.class, configurationPid = "org.opendaylight.netconf.topology")
+@Designate(ocd = NetconfTopologySchemaAssembler.Configuration.class)
+public final class NetconfTopologySchemaAssembler implements AutoCloseable {
+ @ObjectClassDefinition
+ public @interface Configuration {
+ @AttributeDefinition(min = "0")
+ int assembler$_$min$_$threads() default 1;
+ @AttributeDefinition(min = "1")
+ int assembler$_$max$_$threads() default 4;
+ @AttributeDefinition(min = "0")
+ long assembler$_$keep$_$alive$_$millis() default 60_000;
+ }
+
+ private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder()
+ .setNameFormat("topology-schema-assembler-%d")
+ .setDaemon(true)
+ .build();
+
+ private final FlexibleThreadPoolWrapper threadPool;
+
+ public NetconfTopologySchemaAssembler(final int minThreads, final int maxThreads, final long keepAliveTime,
+ final TimeUnit unit) {
+ threadPool = new FlexibleThreadPoolWrapper(minThreads, maxThreads, keepAliveTime, unit, THREAD_FACTORY);
+ }
+
+ @Activate
+ public NetconfTopologySchemaAssembler(final Configuration config) {
+ this(config.assembler$_$min$_$threads(), config.assembler$_$max$_$threads(),
+ config.assembler$_$keep$_$alive$_$millis(), TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ @Deactivate
+ public void close() {
+ threadPool.close();
+ }
+
+ Executor executor() {
+ return threadPool.getExecutor();
+ }
+}
import io.netty.util.TimerTask;
import java.net.InetSocketAddress;
import java.util.List;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@Mock
private SchemaResourceManager schemaManager;
@Mock
- private Executor processingExecutor;
- @Mock
private DeviceActionFactory deviceActionFactory;
@Mock
private RemoteDeviceHandler delegate;
@Mock
private EffectiveModelContext schemaContext;
+ private NetconfTopologySchemaAssembler schemaAssembler;
private NetconfNodeHandler handler;
@BeforeClass
@Before
public void before() {
+ schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS);
+
// Instantiate the handler
- handler = new NetconfNodeHandler(clientFactory, timer, BASE_SCHEMAS, schemaManager, processingExecutor,
+ handler = new NetconfNodeHandler(clientFactory, timer, BASE_SCHEMAS, schemaManager, schemaAssembler,
new NetconfClientConfigurationBuilderFactoryImpl(encryptionService, credentialProvider,
sslHandlerFactoryProvider),
deviceActionFactory, delegate, DEVICE_ID, NODE_ID, new NetconfNodeBuilder()
.build(), null);
}
+ @After
+ public void after() {
+ schemaAssembler.close();
+ }
+
@Test
public void successfulOnDeviceConnectedPropagates() throws Exception {
assertSuccessfulConnect();
<artifactId>netconf-common-mdsal</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-config</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-dom-api</artifactId>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>netconf-client</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>netconf-config</artifactId>
- </dependency>
</dependencies>
</project>
<name>OpenDaylight :: Netconf :: Impl</name>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>odl-controller-exp-netty-config</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>odl-netconf-api</artifactId>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright © 2020 PANTHEON.tech, s.r.o. and others.
- ~
- ~ 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
- -->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-netconf-impl-${project.version}">
- <feature name="odl-netconf-impl" version="${project.version}">
- <feature version="[8,9)">odl-controller-exp-netty-config</feature>
- </feature>
-</features>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>netconf-parent</artifactId>
- <version>7.0.0-SNAPSHOT</version>
- <relativePath>../../parent</relativePath>
- </parent>
-
- <artifactId>netconf-config</artifactId>
- <description>Global threadpools for NETCONF</description>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jdt</groupId>
- <artifactId>org.eclipse.jdt.annotation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>com.guicedee.services</groupId>
- <artifactId>javax.inject</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>jakarta.annotation</groupId>
- <artifactId>jakarta.annotation-api</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.framework</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.service.component</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.service.component.annotations</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.service.metatype.annotations</artifactId>
- </dependency>
- </dependencies>
-</project>
+++ /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 org.eclipse.jdt.annotation.NonNullByDefault;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@NonNullByDefault
-@ObjectClassDefinition
-public @interface Configuration {
- @AttributeDefinition(min = "1")
- String name$_$prefix() default GlobalNetconfThreadFactory.DEFAULT_NAME_PREFIX;
- @AttributeDefinition(min = "0")
- int min$_$thread$_$count$_$flexible$_$thread$_$pool()
- default GlobalNetconfProcessingExecutor.DEFAULT_MIN_THREAD_COUNT;
- @AttributeDefinition(min = "1")
- int max$_$thread$_$count$_$flexible$_$thread$_$pool()
- default GlobalNetconfProcessingExecutor.DEFAULT_MAX_THREAD_COUNT;
- @AttributeDefinition(min = "0")
- long keep$_$alive$_$millis$_$flexible$_$thread$_$pool()
- default GlobalNetconfProcessingExecutor.DEFAULT_KEEPALIVE_MILLIS;
-}
+++ /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 com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Map;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.service.component.ComponentFactory;
-import org.osgi.service.component.ComponentInstance;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Modified;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Component instantiating global NETCONF resources.
- */
-@Component(service = { }, configurationPid = "org.opendaylight.netconf.config")
-@Designate(ocd = Configuration.class)
-public final class GlobalNetconfConfiguration {
- private static final Logger LOG = LoggerFactory.getLogger(GlobalNetconfConfiguration.class);
-
- private final ComponentFactory<GlobalNetconfProcessingExecutor> processingFactory;
-
- private GlobalNetconfThreadFactory threadFactory;
- private ComponentInstance<GlobalNetconfProcessingExecutor> processingExecutor;
- private Map<String, ?> processingProps;
-
- @Activate
- public GlobalNetconfConfiguration(
- @Reference(target = "(component.factory=" + GlobalNetconfProcessingExecutor.FACTORY_NAME + ")")
- final ComponentFactory<GlobalNetconfProcessingExecutor> processingFactory,
- final Configuration configuration) {
- this.processingFactory = requireNonNull(processingFactory);
-
- threadFactory = new GlobalNetconfThreadFactory(configuration.name$_$prefix());
- processingProps = GlobalNetconfProcessingExecutor.props(threadFactory, configuration);
- processingExecutor = processingFactory.newInstance(FrameworkUtil.asDictionary(processingProps));
- LOG.info("Global NETCONF configuration pools started");
- }
-
- @Modified
- void modified(final Configuration configuration) {
- final var newNamePrefix = configuration.name$_$prefix();
- if (!threadFactory.getNamePrefix().equals(newNamePrefix)) {
- threadFactory = new GlobalNetconfThreadFactory(newNamePrefix);
- processingProps = null;
- LOG.debug("Forcing restart of all executors");
- }
-
- // We want to instantiate new services before we dispose old ones, so
- final var toDispose = new ArrayList<ComponentInstance<?>>();
-
- final var newProcessingProps = GlobalNetconfProcessingExecutor.props(threadFactory, configuration);
- if (!newProcessingProps.equals(processingProps)) {
- processingProps = newProcessingProps;
- toDispose.add(processingExecutor);
- processingExecutor = processingFactory.newInstance(FrameworkUtil.asDictionary(processingProps));
- LOG.debug("Processing executor restarted with {}", processingProps);
- }
-
- toDispose.forEach(ComponentInstance::dispose);
- }
-
- @Deactivate
- void deactivate() {
- processingExecutor.dispose();
- processingExecutor = null;
- threadFactory = null;
- LOG.info("Global NETCONF configuration pools stopped");
- }
-
- static <T> T extractProp(final Map<String, ?> properties, final String key, final Class<T> valueType) {
- return valueType.cast(verifyNotNull(properties.get(requireNonNull(key))));
- }
-}
+++ /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 java.util.concurrent.TimeUnit;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
-import org.opendaylight.controller.config.threadpool.util.FlexibleThreadPoolWrapper;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-
-@Singleton
-@Component(factory = GlobalNetconfProcessingExecutor.FACTORY_NAME, service = ThreadPool.class)
-public final class GlobalNetconfProcessingExecutor extends FlexibleThreadPoolWrapper {
- public static final String OSGI_TYPE = "global-netconf-processing-executor";
- public static final int DEFAULT_MIN_THREAD_COUNT = 1;
- public static final int DEFAULT_MAX_THREAD_COUNT = 4;
- public static final long DEFAULT_KEEPALIVE_MILLIS = 600000;
-
- // OSGi DS Component Factory name
- static final String FACTORY_NAME = "org.opendaylight.netconf.config.GlobalNetconfProcessingExecutor";
-
- private static final String PROP_KEEPALIVE = ".keepAlive";
- private static final String PROP_MIN_THREAD_COUNT = ".minThreadCount";
- private static final String PROP_MAX_THREAD_COUNT = ".maxThreadCount";
- private static final String PROP_THREAD_FACTORY = ".threadFactory";
-
- public GlobalNetconfProcessingExecutor(final GlobalNetconfThreadFactory threadFactory, final int minThreadCount,
- final int maxThreadCount, final long keepAliveMillis) {
- super(minThreadCount, maxThreadCount, keepAliveMillis, TimeUnit.MILLISECONDS, threadFactory);
- }
-
- @Inject
- public GlobalNetconfProcessingExecutor(final GlobalNetconfThreadFactory threadFactory) {
- this(threadFactory, DEFAULT_MIN_THREAD_COUNT, DEFAULT_MAX_THREAD_COUNT, DEFAULT_KEEPALIVE_MILLIS);
- }
-
- @Activate
- public GlobalNetconfProcessingExecutor(final Map<String, ?> properties) {
- this(GlobalNetconfConfiguration.extractProp(properties, PROP_THREAD_FACTORY, GlobalNetconfThreadFactory.class),
- GlobalNetconfConfiguration.extractProp(properties, PROP_MIN_THREAD_COUNT, Integer.class),
- GlobalNetconfConfiguration.extractProp(properties, PROP_MAX_THREAD_COUNT, Integer.class),
- GlobalNetconfConfiguration.extractProp(properties, PROP_KEEPALIVE, Long.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_THREAD_FACTORY, requireNonNull(threadFactory),
- PROP_KEEPALIVE, configuration.keep$_$alive$_$millis$_$flexible$_$thread$_$pool(),
- PROP_MIN_THREAD_COUNT, configuration.min$_$thread$_$count$_$flexible$_$thread$_$pool(),
- PROP_MAX_THREAD_COUNT, configuration.max$_$thread$_$count$_$flexible$_$thread$_$pool());
- }
-}
+++ /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 javax.inject.Inject;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory;
-
-/**
- * Shared {@link NamingThreadPoolFactory} for {@link GlobalNetconfProcessingExecutor}.
- */
-@NonNullByDefault
-public final class GlobalNetconfThreadFactory extends NamingThreadPoolFactory {
- public static final String DEFAULT_NAME_PREFIX = "remote-connector-processing-executor";
-
- public GlobalNetconfThreadFactory(final String namePrefix) {
- super(namePrefix);
- }
-
- @Inject
- public GlobalNetconfThreadFactory() {
- this(DEFAULT_NAME_PREFIX);
- }
-}
</properties>
<modules>
- <module>netconf-config</module>
<module>netconf-netty-util</module>
<module>netconf-auth</module>
<module>yanglib</module>