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 static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
13 import akka.actor.ActorRef;
14 import akka.cluster.Cluster;
15 import akka.dispatch.OnComplete;
16 import akka.pattern.Patterns;
17 import akka.util.Timeout;
18 import com.google.common.base.Preconditions;
19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture;
21 import java.util.concurrent.atomic.AtomicBoolean;
22 import javax.annotation.Nonnull;
23 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
24 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
25 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
26 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
27 import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector;
28 import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
29 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
30 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
31 import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import scala.concurrent.Future;
37 class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable {
39 private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyContext.class);
41 private final ServiceGroupIdentifier serviceGroupIdent;
42 private final Timeout actorResponseWaitTime;
43 private final DOMMountPointService mountService;
45 private NetconfTopologySetup netconfTopologyDeviceSetup;
46 private RemoteDeviceId remoteDeviceId;
47 private RemoteDeviceConnector remoteDeviceConnector;
48 private NetconfNodeManager netconfNodeManager;
49 private ActorRef masterActorRef;
50 private final AtomicBoolean closed = new AtomicBoolean(false);
51 private final AtomicBoolean stopped = new AtomicBoolean(false);
52 private volatile boolean isMaster;
54 NetconfTopologyContext(final NetconfTopologySetup netconfTopologyDeviceSetup,
55 final ServiceGroupIdentifier serviceGroupIdent,
56 final Timeout actorResponseWaitTime, final DOMMountPointService mountService) {
57 this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup);
58 this.serviceGroupIdent = serviceGroupIdent;
59 this.actorResponseWaitTime = actorResponseWaitTime;
60 this.mountService = mountService;
62 remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
63 netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class));
65 remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId,
66 actorResponseWaitTime, mountService);
68 netconfNodeManager = createNodeDeviceManager();
72 public void instantiateServiceInstance() {
73 LOG.info("Master was selected: {}", remoteDeviceId.getHost().getIpAddress());
77 // master should not listen on netconf-node operational datastore
78 if (netconfNodeManager != null) {
79 netconfNodeManager.close();
80 netconfNodeManager = null;
84 final String masterAddress =
85 Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString();
86 masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props(
87 netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY, DEFAULT_SCHEMA_REPOSITORY,
88 actorResponseWaitTime, mountService),
89 NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress));
91 remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef);
96 // called when master is down/changed to slave
98 public ListenableFuture<Void> closeServiceInstance() {
101 // in case that master changes role to slave, new NodeDeviceManager must be created and listener registered
102 netconfNodeManager = createNodeDeviceManager();
104 stopDeviceConnectorAndActor();
106 return Futures.immediateFuture(null);
110 public ServiceGroupIdentifier getIdentifier() {
111 return serviceGroupIdent;
114 private NetconfNodeManager createNodeDeviceManager() {
115 final NetconfNodeManager ndm =
116 new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService);
117 ndm.registerDataTreeChangeListener(netconfTopologyDeviceSetup.getTopologyId(),
118 netconfTopologyDeviceSetup.getNode().getKey());
124 public void close() throws Exception {
125 if (!closed.compareAndSet(false, true)) {
129 if (netconfNodeManager != null) {
130 netconfNodeManager.close();
132 stopDeviceConnectorAndActor();
137 * Refresh, if configuration data was changed.
138 * @param setup new setup
140 void refresh(@Nonnull final NetconfTopologySetup setup) {
141 netconfTopologyDeviceSetup = Preconditions.checkNotNull(setup);
142 remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
143 netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class));
146 remoteDeviceConnector.stopRemoteDeviceConnection();
149 netconfNodeManager.refreshDevice(netconfTopologyDeviceSetup, remoteDeviceId);
151 remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId,
152 actorResponseWaitTime, mountService);
155 final Future<Object> future = Patterns.ask(masterActorRef, new RefreshSetupMasterActorData(
156 netconfTopologyDeviceSetup, remoteDeviceId), actorResponseWaitTime);
158 future.onComplete(new OnComplete<Object>() {
160 public void onComplete(final Throwable failure, final Object success) throws Throwable {
161 if (failure != null) {
162 LOG.error("Failed to refresh master actor data: {}", failure);
165 remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef);
167 }, netconfTopologyDeviceSetup.getActorSystem().dispatcher());
171 private void stopDeviceConnectorAndActor() {
172 if (!stopped.compareAndSet(false, true)) {
175 if (remoteDeviceConnector != null) {
176 remoteDeviceConnector.stopRemoteDeviceConnection();
179 if (masterActorRef != null) {
180 netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef);
181 masterActorRef = null;