2 * Copyright (c) 2016 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.singleton.impl;
11 import akka.actor.ActorRef;
12 import akka.actor.PoisonPill;
13 import akka.util.Timeout;
14 import java.util.Collection;
15 import javax.annotation.Nonnull;
16 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
17 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
22 import org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService;
23 import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
24 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
25 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
26 import org.opendaylight.netconf.topology.singleton.messages.AskForMasterMountPoint;
27 import org.opendaylight.netconf.topology.singleton.messages.UnregisterSlaveMountPoint;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
33 import org.opendaylight.yangtools.concepts.ListenerRegistration;
34 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
35 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Managing and reacting on data tree changes in specific netconf node when master writes status to the operational
41 * data store (e.g. handling lifecycle of slave mount point).
43 class NetconfNodeManager
44 implements ClusteredDataTreeChangeListener<Node>, NetconfTopologySingletonService, AutoCloseable {
46 private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeManager.class);
48 private NetconfTopologySetup setup;
49 private ListenerRegistration<NetconfNodeManager> dataChangeListenerRegistration;
50 private RemoteDeviceId id;
51 private final SchemaSourceRegistry schemaRegistry;
52 private final SchemaRepository schemaRepository;
53 private ActorRef slaveActorRef;
54 private final Timeout actorResponseWaitTime;
56 NetconfNodeManager(final NetconfTopologySetup setup,
57 final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
58 final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime) {
61 this.schemaRegistry = schemaRegistry;
62 this.schemaRepository = schemaRepository;
63 this.actorResponseWaitTime = actorResponseWaitTime;
67 public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Node>> changes) {
68 for (final DataTreeModification<Node> change : changes) {
69 final DataObjectModification<Node> rootNode = change.getRootNode();
70 final NodeId nodeId = NetconfTopologyUtils.getNodeId(rootNode.getIdentifier());
71 switch (rootNode.getModificationType()) {
72 case SUBTREE_MODIFIED:
73 LOG.debug("{}: Operational for node {} updated. Trying to register slave mount point", id, nodeId);
74 handleSlaveMountPoint(rootNode);
77 if (rootNode.getDataBefore() != null) {
78 LOG.debug("{}: Operational for node {} rewrited. Trying to register slave mount point", id, nodeId);
80 LOG.debug("{}: Operational for node {} created. Trying to register slave mount point", id, nodeId);
82 handleSlaveMountPoint(rootNode);
85 LOG.debug("{}: Operational for node {} deleted. Trying to remove slave mount point", id, nodeId);
89 LOG.debug("{}: Uknown operation for node: {}", id, nodeId);
98 if (dataChangeListenerRegistration != null) {
99 dataChangeListenerRegistration.close();
100 dataChangeListenerRegistration = null;
104 private void closeActor() {
105 if (slaveActorRef != null) {
106 slaveActorRef.tell(new UnregisterSlaveMountPoint(), ActorRef.noSender());
107 slaveActorRef.tell(PoisonPill.getInstance(), ActorRef.noSender());
108 slaveActorRef = null;
112 void registerDataTreeChangeListener(final String topologyId, final NodeKey key) {
113 LOG.debug("{}: Registering data tree change listener on node {}", id, key);
114 dataChangeListenerRegistration = setup.getDataBroker().registerDataTreeChangeListener(
115 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
116 NetconfTopologyUtils.createTopologyNodeListPath(key, topologyId)), this);
119 private void handleSlaveMountPoint(final DataObjectModification<Node> rootNode) {
120 @SuppressWarnings("ConstantConditions")
121 final NetconfNode netconfNodeAfter = rootNode.getDataAfter().getAugmentation(NetconfNode.class);
123 if (NetconfNodeConnectionStatus.ConnectionStatus.Connected.equals(netconfNodeAfter.getConnectionStatus())) {
125 final String masterAddress = netconfNodeAfter.getClusteredConnectionStatus().getNetconfMasterNode();
126 final String path = NetconfTopologyUtils.createActorPath(masterAddress,
127 NetconfTopologyUtils.createMasterActorName(id.getName(),
128 netconfNodeAfter.getClusteredConnectionStatus().getNetconfMasterNode()));
129 setup.getActorSystem().actorSelection(path).tell(new AskForMasterMountPoint(), slaveActorRef);
135 private void createActorRef() {
136 if (slaveActorRef == null) {
137 slaveActorRef = setup.getActorSystem().actorOf(NetconfNodeActor.props(setup, id, schemaRegistry,
138 schemaRepository, actorResponseWaitTime), id.getName());
142 void refreshDevice(final NetconfTopologySetup netconfTopologyDeviceSetup, final RemoteDeviceId remoteDeviceId) {
143 setup = netconfTopologyDeviceSetup;