2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.netconf.topology.impl;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import io.netty.util.concurrent.EventExecutor;
14 import java.util.Collection;
15 import javax.annotation.Nonnull;
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.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
27 import org.opendaylight.netconf.client.NetconfClientDispatcher;
28 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
29 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
30 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalFacade;
31 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
32 import org.opendaylight.netconf.topology.AbstractNetconfTopology;
33 import org.opendaylight.netconf.topology.api.SchemaRepositoryProvider;
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.NetworkTopologyBuilder;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
41 import org.opendaylight.yangtools.concepts.ListenerRegistration;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class NetconfTopologyImpl extends AbstractNetconfTopology
47 implements DataTreeChangeListener<Node>, AutoCloseable {
49 private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyImpl.class);
51 private ListenerRegistration<NetconfTopologyImpl> datastoreListenerRegistration = null;
53 public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
54 final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
55 final ThreadPool processingExecutor,
56 final SchemaRepositoryProvider schemaRepositoryProvider,
57 final DataBroker dataBroker, final DOMMountPointService mountPointService,
58 final AAAEncryptionService encryptionService) {
59 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
60 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService);
64 public void close() throws Exception {
65 // close all existing connectors, delete whole topology in datastore?
66 for (final NetconfConnectorDTO connectorDTO : activeConnectors.values()) {
69 activeConnectors.clear();
71 if (datastoreListenerRegistration != null) {
72 datastoreListenerRegistration.close();
73 datastoreListenerRegistration = null;
78 protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id) {
79 return new NetconfDeviceSalFacade(id, mountPointService, dataBroker);
83 * Invoked by blueprint.
86 final WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
87 initTopology(wtx, LogicalDatastoreType.CONFIGURATION);
88 initTopology(wtx, LogicalDatastoreType.OPERATIONAL);
89 Futures.addCallback(wtx.submit(), new FutureCallback<Void>() {
91 public void onSuccess(final Void result) {
92 LOG.debug("topology initialization successful");
96 public void onFailure(final Throwable throwable) {
97 LOG.error("Unable to initialize netconf-topology, {}", throwable);
101 LOG.debug("Registering datastore listener");
102 datastoreListenerRegistration =
103 dataBroker.registerDataTreeChangeListener(
104 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
105 TopologyUtil.createTopologyListPath(topologyId).child(Node.class)), this);
111 public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Node>> collection) {
112 for (final DataTreeModification<Node> change : collection) {
113 final DataObjectModification<Node> rootNode = change.getRootNode();
114 switch (rootNode.getModificationType()) {
115 case SUBTREE_MODIFIED:
116 LOG.debug("Config for node {} updated", TopologyUtil.getNodeId(rootNode.getIdentifier()));
117 disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
118 connectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
121 LOG.debug("Config for node {} created", TopologyUtil.getNodeId(rootNode.getIdentifier()));
122 if (activeConnectors.containsKey(TopologyUtil.getNodeId(rootNode.getIdentifier()))) {
123 LOG.warn("RemoteDevice{{}} was already configured, reconfiguring..",
124 TopologyUtil.getNodeId(rootNode.getIdentifier()));
125 disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
127 connectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
130 LOG.debug("Config for node {} deleted", TopologyUtil.getNodeId(rootNode.getIdentifier()));
131 disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
134 LOG.debug("Unsupported modification type: {}.", rootNode.getModificationType());
139 private void initTopology(final WriteTransaction wtx, final LogicalDatastoreType datastoreType) {
140 final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
141 final InstanceIdentifier<NetworkTopology> networkTopologyId =
142 InstanceIdentifier.builder(NetworkTopology.class).build();
143 wtx.merge(datastoreType, networkTopologyId, networkTopology);
144 final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).build();
145 wtx.merge(datastoreType,
146 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(topologyId))), topology);