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
8 package org.opendaylight.netconf.topology.singleton.impl;
10 import akka.actor.ActorRef;
11 import akka.cluster.Cluster;
12 import akka.dispatch.OnComplete;
13 import akka.pattern.Patterns;
14 import akka.util.Timeout;
15 import com.google.common.base.Preconditions;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.util.concurrent.atomic.AtomicBoolean;
19 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
20 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
21 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
22 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
23 import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector;
24 import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
25 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
26 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
27 import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31 import scala.concurrent.Future;
33 class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable {
35 private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyContext.class);
37 private final ServiceGroupIdentifier serviceGroupIdent;
38 private final Timeout actorResponseWaitTime;
39 private final DOMMountPointService mountService;
41 private NetconfTopologySetup netconfTopologyDeviceSetup;
42 private RemoteDeviceId remoteDeviceId;
43 private RemoteDeviceConnector remoteDeviceConnector;
44 private NetconfNodeManager netconfNodeManager;
45 private ActorRef masterActorRef;
46 private final AtomicBoolean closed = new AtomicBoolean(false);
47 private final AtomicBoolean stopped = new AtomicBoolean(false);
48 private volatile boolean isMaster;
50 NetconfTopologyContext(final NetconfTopologySetup netconfTopologyDeviceSetup,
51 final ServiceGroupIdentifier serviceGroupIdent,
52 final Timeout actorResponseWaitTime, final DOMMountPointService mountService) {
53 this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup);
54 this.serviceGroupIdent = serviceGroupIdent;
55 this.actorResponseWaitTime = actorResponseWaitTime;
56 this.mountService = mountService;
58 remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
59 netconfTopologyDeviceSetup.getNode().augmentation(NetconfNode.class));
61 remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId);
63 netconfNodeManager = createNodeDeviceManager();
67 public void instantiateServiceInstance() {
68 LOG.info("Master was selected: {}", remoteDeviceId.getHost().getIpAddress());
72 // master should not listen on netconf-node operational datastore
73 if (netconfNodeManager != null) {
74 netconfNodeManager.close();
75 netconfNodeManager = null;
79 final String masterAddress =
80 Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString();
81 masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props(
82 netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService),
83 NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress));
85 remoteDeviceConnector.startRemoteDeviceConnection(newMasterSalFacade());
90 // called when master is down/changed to slave
92 public ListenableFuture<Void> closeServiceInstance() {
95 // in case that master changes role to slave, new NodeDeviceManager must be created and listener registered
96 netconfNodeManager = createNodeDeviceManager();
98 stopDeviceConnectorAndActor();
100 return Futures.immediateFuture(null);
104 public ServiceGroupIdentifier getIdentifier() {
105 return serviceGroupIdent;
108 private NetconfNodeManager createNodeDeviceManager() {
109 final NetconfNodeManager ndm =
110 new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService);
111 ndm.registerDataTreeChangeListener(netconfTopologyDeviceSetup.getTopologyId(),
112 netconfTopologyDeviceSetup.getNode().key());
118 public void close() {
119 if (!closed.compareAndSet(false, true)) {
123 if (netconfNodeManager != null) {
124 netconfNodeManager.close();
126 stopDeviceConnectorAndActor();
131 * Refresh, if configuration data was changed.
132 * @param setup new setup
134 void refresh(final NetconfTopologySetup setup) {
135 netconfTopologyDeviceSetup = Preconditions.checkNotNull(setup);
136 remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
137 netconfTopologyDeviceSetup.getNode().augmentation(NetconfNode.class));
140 remoteDeviceConnector.stopRemoteDeviceConnection();
143 netconfNodeManager.refreshDevice(netconfTopologyDeviceSetup, remoteDeviceId);
145 remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId);
148 final Future<Object> future = Patterns.ask(masterActorRef, new RefreshSetupMasterActorData(
149 netconfTopologyDeviceSetup, remoteDeviceId), actorResponseWaitTime);
151 future.onComplete(new OnComplete<Object>() {
153 public void onComplete(final Throwable failure, final Object success) {
154 if (failure != null) {
155 LOG.error("Failed to refresh master actor data", failure);
158 remoteDeviceConnector.startRemoteDeviceConnection(newMasterSalFacade());
160 }, netconfTopologyDeviceSetup.getActorSystem().dispatcher());
164 private void stopDeviceConnectorAndActor() {
165 if (!stopped.compareAndSet(false, true)) {
168 if (remoteDeviceConnector != null) {
169 remoteDeviceConnector.stopRemoteDeviceConnection();
172 if (masterActorRef != null) {
173 netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef);
174 masterActorRef = null;
178 protected MasterSalFacade newMasterSalFacade() {
179 return new MasterSalFacade(remoteDeviceId, netconfTopologyDeviceSetup.getActorSystem(), masterActorRef,
180 actorResponseWaitTime, mountService, netconfTopologyDeviceSetup.getDataBroker());