X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-topology-singleton%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Ftopology%2Fsingleton%2Fimpl%2FNetconfTopologyContext.java;h=0cb78da8aa5d7c7f24875a3612aa866da0023960;hb=90dcdd5d040eb22b74e87baccffd70a30d93bfc0;hp=62508a2c3b1d9ec9ccb0155ca147290217252662;hpb=285079f8492f35b980d1d11745e02370229231a7;p=netconf.git diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java index 62508a2c3b..0cb78da8aa 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java @@ -5,65 +5,66 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.topology.singleton.impl; -import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY; +import static java.util.Objects.requireNonNull; import akka.actor.ActorRef; import akka.cluster.Cluster; import akka.dispatch.OnComplete; import akka.pattern.Patterns; import akka.util.Timeout; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import javax.annotation.Nonnull; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector; import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData; +import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yangtools.util.concurrent.FluentFutures; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.concurrent.Future; -class NetconfTopologyContext implements ClusterSingletonService { +class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyContext.class); private final ServiceGroupIdentifier serviceGroupIdent; private final Timeout actorResponseWaitTime; private final DOMMountPointService mountService; + private final DeviceActionFactory deviceActionFactory; private NetconfTopologySetup netconfTopologyDeviceSetup; private RemoteDeviceId remoteDeviceId; private RemoteDeviceConnector remoteDeviceConnector; private NetconfNodeManager netconfNodeManager; private ActorRef masterActorRef; - private boolean finalClose = false; - private boolean closed = false; - private boolean isMaster; + private final AtomicBoolean closed = new AtomicBoolean(false); + private final AtomicBoolean stopped = new AtomicBoolean(false); + private volatile boolean isMaster; NetconfTopologyContext(final NetconfTopologySetup netconfTopologyDeviceSetup, - final ServiceGroupIdentifier serviceGroupIdent, - final Timeout actorResponseWaitTime, final DOMMountPointService mountService) { - this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup); + final ServiceGroupIdentifier serviceGroupIdent, final Timeout actorResponseWaitTime, + final DOMMountPointService mountService, final DeviceActionFactory deviceActionFactory) { + this.netconfTopologyDeviceSetup = requireNonNull(netconfTopologyDeviceSetup); this.serviceGroupIdent = serviceGroupIdent; this.actorResponseWaitTime = actorResponseWaitTime; this.mountService = mountService; + this.deviceActionFactory = deviceActionFactory; - remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(), - netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class)); - + final var node = netconfTopologyDeviceSetup.getNode(); + remoteDeviceId = NetconfNodeUtils.toRemoteDeviceId(node.getNodeId(), node.augmentation(NetconfNode.class)); remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId, - actorResponseWaitTime, mountService); - + deviceActionFactory); netconfNodeManager = createNodeDeviceManager(); } @@ -79,30 +80,29 @@ class NetconfTopologyContext implements ClusterSingletonService { netconfNodeManager = null; } - if (!finalClose) { + if (!closed.get()) { final String masterAddress = Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString(); masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props( - netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY, DEFAULT_SCHEMA_REPOSITORY, - actorResponseWaitTime, mountService), + netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService), NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress)); - remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef); + remoteDeviceConnector.startRemoteDeviceConnection(newMasterSalFacade()); } } // called when master is down/changed to slave @Override - public ListenableFuture closeServiceInstance() { + public ListenableFuture closeServiceInstance() { - if (!finalClose) { + if (!closed.get()) { // in case that master changes role to slave, new NodeDeviceManager must be created and listener registered netconfNodeManager = createNodeDeviceManager(); } stopDeviceConnectorAndActor(); - return Futures.immediateCheckedFuture(null); + return FluentFutures.immediateNullFluentFuture(); } @Override @@ -114,13 +114,16 @@ class NetconfTopologyContext implements ClusterSingletonService { final NetconfNodeManager ndm = new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService); ndm.registerDataTreeChangeListener(netconfTopologyDeviceSetup.getTopologyId(), - netconfTopologyDeviceSetup.getNode().getKey()); + netconfTopologyDeviceSetup.getNode().key()); return ndm; } - void closeFinal() throws Exception { - finalClose = true; + @Override + public void close() { + if (!closed.compareAndSet(false, true)) { + return; + } if (netconfNodeManager != null) { netconfNodeManager.close(); @@ -133,10 +136,10 @@ class NetconfTopologyContext implements ClusterSingletonService { * Refresh, if configuration data was changed. * @param setup new setup */ - void refresh(@Nonnull final NetconfTopologySetup setup) { - netconfTopologyDeviceSetup = Preconditions.checkNotNull(setup); - remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(), - netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class)); + void refresh(final @NonNull NetconfTopologySetup setup) { + netconfTopologyDeviceSetup = requireNonNull(setup); + final var node = netconfTopologyDeviceSetup.getNode(); + remoteDeviceId = NetconfNodeUtils.toRemoteDeviceId(node.getNodeId(), node.augmentation(NetconfNode.class)); if (isMaster) { remoteDeviceConnector.stopRemoteDeviceConnection(); @@ -145,27 +148,26 @@ class NetconfTopologyContext implements ClusterSingletonService { netconfNodeManager.refreshDevice(netconfTopologyDeviceSetup, remoteDeviceId); } remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId, - actorResponseWaitTime, mountService); + deviceActionFactory); if (isMaster) { final Future future = Patterns.ask(masterActorRef, new RefreshSetupMasterActorData( - netconfTopologyDeviceSetup, remoteDeviceId), actorResponseWaitTime); - + netconfTopologyDeviceSetup, remoteDeviceId), actorResponseWaitTime); future.onComplete(new OnComplete() { @Override - public void onComplete(final Throwable failure, final Object success) throws Throwable { + public void onComplete(final Throwable failure, final Object success) { if (failure != null) { - LOG.error("Failed to refresh master actor data: {}", failure); + LOG.error("Failed to refresh master actor data", failure); return; } - remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef); + remoteDeviceConnector.startRemoteDeviceConnection(newMasterSalFacade()); } }, netconfTopologyDeviceSetup.getActorSystem().dispatcher()); } } - private synchronized void stopDeviceConnectorAndActor() { - if (closed) { + private void stopDeviceConnectorAndActor() { + if (!stopped.compareAndSet(false, true)) { return; } if (remoteDeviceConnector != null) { @@ -176,6 +178,10 @@ class NetconfTopologyContext implements ClusterSingletonService { netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef); masterActorRef = null; } - closed = true; } -} + + protected MasterSalFacade newMasterSalFacade() { + return new MasterSalFacade(remoteDeviceId, netconfTopologyDeviceSetup.getActorSystem(), masterActorRef, + actorResponseWaitTime, mountService, netconfTopologyDeviceSetup.getDataBroker()); + } +} \ No newline at end of file