Remove NetconfTopology
[netconf.git] / apps / netconf-topology-impl / src / main / java / org / opendaylight / netconf / topology / impl / NetconfTopologyImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.topology.impl;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import io.netty.util.concurrent.EventExecutor;
13 import java.util.Collection;
14 import javax.annotation.PreDestroy;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
18 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
19 import org.opendaylight.controller.config.threadpool.ThreadPool;
20 import org.opendaylight.mdsal.binding.api.DataBroker;
21 import org.opendaylight.mdsal.binding.api.DataObjectModification;
22 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
23 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
24 import org.opendaylight.mdsal.binding.api.DataTreeModification;
25 import org.opendaylight.mdsal.binding.api.RpcProviderService;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
28 import org.opendaylight.netconf.client.NetconfClientDispatcher;
29 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
30 import org.opendaylight.netconf.client.mdsal.api.CredentialProvider;
31 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
32 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
33 import org.opendaylight.netconf.client.mdsal.api.SslHandlerFactoryProvider;
34 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
35 import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
36 import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeTopologyService;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
45 import org.opendaylight.yangtools.concepts.Registration;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
49 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
50 import org.osgi.service.component.annotations.Activate;
51 import org.osgi.service.component.annotations.Component;
52 import org.osgi.service.component.annotations.Deactivate;
53 import org.osgi.service.component.annotations.Reference;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 // Non-final for testing
58 @Singleton
59 @Component(service = { })
60 public class NetconfTopologyImpl extends AbstractNetconfTopology
61         implements DataTreeChangeListener<Node>, AutoCloseable {
62     private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyImpl.class);
63
64     private Registration dtclReg;
65     private Registration rpcReg;
66
67     @Inject
68     @Activate
69     public NetconfTopologyImpl(
70             @Reference(target = "(type=netconf-client-dispatcher)") final NetconfClientDispatcher clientDispatcher,
71             @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
72             @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
73             final ScheduledThreadPool keepaliveExecutor,
74             @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingExecutor,
75             @Reference final SchemaResourceManager schemaRepositoryProvider, @Reference final DataBroker dataBroker,
76             @Reference final DOMMountPointService mountPointService,
77             @Reference final AAAEncryptionService encryptionService,
78             @Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas,
79             @Reference final CredentialProvider credentialProvider,
80             @Reference final SslHandlerFactoryProvider sslHandlerFactoryProvider,
81             @Reference final DeviceActionFactory deviceActionFactory) {
82         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientDispatcher, eventExecutor, keepaliveExecutor,
83             processingExecutor, schemaRepositoryProvider, dataBroker, mountPointService, encryptionService,
84             rpcProviderService, baseSchemas, credentialProvider, sslHandlerFactoryProvider, deviceActionFactory);
85     }
86
87     public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
88             final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
89             final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
90             final DataBroker dataBroker, final DOMMountPointService mountPointService,
91             final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
92             final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider,
93             final SslHandlerFactoryProvider sslHandlerFactoryProvider) {
94         this(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
95                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, rpcProviderService,
96                 baseSchemas, credentialProvider, sslHandlerFactoryProvider, null);
97     }
98
99     @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
100         justification = "DTCL registration of 'this'")
101     public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
102             final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
103             final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
104             final DataBroker dataBroker, final DOMMountPointService mountPointService,
105             final AAAEncryptionService encryptionService, final RpcProviderService rpcProviderService,
106             final BaseNetconfSchemas baseSchemas, final CredentialProvider credentialProvider,
107             final SslHandlerFactoryProvider sslHandlerFactoryProvider, final DeviceActionFactory deviceActionFactory) {
108         super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
109                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, deviceActionFactory,
110                 baseSchemas, credentialProvider, sslHandlerFactoryProvider);
111
112         LOG.debug("Registering datastore listener");
113         dtclReg = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
114             LogicalDatastoreType.CONFIGURATION, createTopologyListPath(topologyId).child(Node.class)), this);
115         rpcReg = rpcProviderService.registerRpcImplementation(NetconfNodeTopologyService.class,
116             new NetconfTopologyRPCProvider(dataBroker, encryptionService, topologyId));
117     }
118
119     @PreDestroy
120     @Deactivate
121     @Override
122     public void close() {
123         if (rpcReg != null) {
124             rpcReg.close();
125             rpcReg = null;
126         }
127
128         // close all existing connectors, delete whole topology in datastore?
129         deleteAllNodes();
130
131         if (dtclReg != null) {
132             dtclReg.close();
133             dtclReg = null;
134         }
135     }
136
137     @Override
138     public void onDataTreeChanged(final Collection<DataTreeModification<Node>> collection) {
139         for (final DataTreeModification<Node> change : collection) {
140             final DataObjectModification<Node> rootNode = change.getRootNode();
141             final NodeId nodeId;
142             switch (rootNode.getModificationType()) {
143                 case SUBTREE_MODIFIED -> {
144                     LOG.debug("Config for node {} updated", getNodeId(rootNode.getIdentifier()));
145                     ensureNode(rootNode.getDataAfter());
146                 }
147                 case WRITE -> {
148                     LOG.debug("Config for node {} created", getNodeId(rootNode.getIdentifier()));
149                     ensureNode(rootNode.getDataAfter());
150                 }
151                 case DELETE -> {
152                     nodeId = getNodeId(rootNode.getIdentifier());
153                     LOG.debug("Config for node {} deleted", nodeId);
154                     deleteNode(nodeId);
155                 }
156                 default -> LOG.debug("Unsupported modification type: {}.", rootNode.getModificationType());
157             }
158         }
159     }
160
161     /**
162      * Determines the Netconf Node Node ID, given the node's instance
163      * identifier.
164      *
165      * @param pathArgument Node's path argument
166      * @return     NodeId for the node
167      */
168     @VisibleForTesting
169     static NodeId getNodeId(final PathArgument pathArgument) {
170         if (pathArgument instanceof IdentifiableItem<?, ?> ident && ident.getKey() instanceof NodeKey nodeKey) {
171             return nodeKey.getNodeId();
172         }
173         throw new IllegalStateException("Unable to create NodeId from: " + pathArgument);
174     }
175
176     @VisibleForTesting
177     static KeyedInstanceIdentifier<Topology, TopologyKey> createTopologyListPath(final String topologyId) {
178         return InstanceIdentifier.create(NetworkTopology.class)
179             .child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
180     }
181 }