Migrate netconf-topology to new transport
[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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import io.netty.util.concurrent.EventExecutor;
12 import java.util.Collection;
13 import javax.annotation.PreDestroy;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
17 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
18 import org.opendaylight.controller.config.threadpool.ThreadPool;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
21 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
22 import org.opendaylight.mdsal.binding.api.DataTreeModification;
23 import org.opendaylight.mdsal.binding.api.RpcProviderService;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
26 import org.opendaylight.netconf.client.NetconfClientFactory;
27 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
28 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
29 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
30 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
31 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
32 import org.opendaylight.netconf.topology.spi.NetconfNodeUtils;
33 import org.opendaylight.netconf.topology.spi.NetconfTopologyRPCProvider;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
39 import org.opendaylight.yangtools.concepts.Registration;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.osgi.service.component.annotations.Activate;
42 import org.osgi.service.component.annotations.Component;
43 import org.osgi.service.component.annotations.Deactivate;
44 import org.osgi.service.component.annotations.Reference;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 // Non-final for testing
49 @Singleton
50 @Component(service = { })
51 public class NetconfTopologyImpl extends AbstractNetconfTopology
52         implements DataTreeChangeListener<Node>, AutoCloseable {
53     private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyImpl.class);
54
55     private Registration dtclReg;
56     private NetconfTopologyRPCProvider rpcProvider;
57
58     @Inject
59     @Activate
60     public NetconfTopologyImpl(
61             @Reference(target = "(type=netconf-client-factory)") final NetconfClientFactory clientFactory,
62             @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
63             @Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
64             final ScheduledThreadPool scheduledThreadPool,
65             @Reference(target = "(type=global-netconf-processing-executor)") final ThreadPool processingThreadPool,
66             @Reference final SchemaResourceManager schemaRepositoryProvider, @Reference final DataBroker dataBroker,
67             @Reference final DOMMountPointService mountPointService,
68             @Reference final AAAEncryptionService encryptionService,
69             @Reference(target = "(type=default)") final NetconfClientConfigurationBuilderFactory builderFactory,
70             @Reference final RpcProviderService rpcProviderService, @Reference final BaseNetconfSchemas baseSchemas,
71             @Reference final DeviceActionFactory deviceActionFactory) {
72         this(NetconfNodeUtils.DEFAULT_TOPOLOGY_NAME, clientFactory, eventExecutor, scheduledThreadPool,
73             processingThreadPool, schemaRepositoryProvider, dataBroker, mountPointService, encryptionService,
74             builderFactory, rpcProviderService, baseSchemas, deviceActionFactory);
75     }
76
77     public NetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientclientFactory,
78             final EventExecutor eventExecutor, final ScheduledThreadPool scheduledThreadPool,
79             final ThreadPool processingThreadPool, final SchemaResourceManager schemaRepositoryProvider,
80             final DataBroker dataBroker, final DOMMountPointService mountPointService,
81             final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory,
82             final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
83         this(topologyId, clientclientFactory, eventExecutor, scheduledThreadPool, processingThreadPool,
84             schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
85             rpcProviderService, baseSchemas, null);
86     }
87
88     @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
89         justification = "DTCL registration of 'this'")
90     public NetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory,
91             final EventExecutor eventExecutor, final ScheduledThreadPool scheduledThreadPool,
92             final ThreadPool processingThreadPool, final SchemaResourceManager schemaRepositoryProvider,
93             final DataBroker dataBroker, final DOMMountPointService mountPointService,
94             final AAAEncryptionService encryptionService, final NetconfClientConfigurationBuilderFactory builderFactory,
95             final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas,
96             final DeviceActionFactory deviceActionFactory) {
97         super(topologyId, clientFactory, eventExecutor, scheduledThreadPool, processingThreadPool,
98             schemaRepositoryProvider, dataBroker, mountPointService, builderFactory, deviceActionFactory, baseSchemas);
99
100         LOG.debug("Registering datastore listener");
101         dtclReg = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
102             LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(NetworkTopology.class)
103                 .child(Topology.class, new TopologyKey(new TopologyId(topologyId)))
104                 .child(Node.class)
105                 .build()), this);
106         rpcProvider = new NetconfTopologyRPCProvider(rpcProviderService, dataBroker, encryptionService, topologyId);
107     }
108
109     @PreDestroy
110     @Deactivate
111     @Override
112     public void close() {
113         if (rpcProvider != null) {
114             rpcProvider.close();
115             rpcProvider = null;
116         }
117
118         // close all existing connectors, delete whole topology in datastore?
119         deleteAllNodes();
120
121         if (dtclReg != null) {
122             dtclReg.close();
123             dtclReg = null;
124         }
125     }
126
127     @Override
128     public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
129         for (var change : changes) {
130             final var rootNode = change.getRootNode();
131             final var modType = rootNode.getModificationType();
132             switch (modType) {
133                 case SUBTREE_MODIFIED -> ensureNode("updated", rootNode.getDataAfter());
134                 case WRITE -> ensureNode("created", rootNode.getDataAfter());
135                 case DELETE -> {
136                     final var nodeId = InstanceIdentifier.keyOf(change.getRootPath().getRootIdentifier()).getNodeId();
137                     LOG.debug("Config for node {} deleted", nodeId);
138                     deleteNode(nodeId);
139                 }
140                 default -> LOG.debug("Unsupported modification type: {}.", modType);
141             }
142         }
143     }
144
145     private void ensureNode(final String operation, final Node node) {
146         final var nodeId = node.getNodeId();
147         LOG.debug("Config for node {} {}", nodeId, operation);
148         ensureNode(node);
149     }
150 }