<classifier>config</classifier>
<type>xml</type>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>abstract-topology</artifactId>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-topology</artifactId>
<bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.controller.model/model-inventory/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.netconf/netconf-topology/{{VERSION}}</bundle>
- <bundle>mvn:org.opendaylight.netconf/abstract-topology/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.netconf/netconf-config-dispatcher/{{VERSION}}</bundle>
<configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.netconf/netconf-config/{{VERSION}}/xml/config</configfile>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>bundle-parent</artifactId>
- <version>1.8.0-SNAPSHOT</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>abstract-topology</artifactId>
- <version>1.2.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <properties>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.mdsal.model</groupId>
- <artifactId>ietf-topology</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-clustering-commons</artifactId>
- </dependency>
- <dependency>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-library</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe.akka</groupId>
- <artifactId>akka-actor_${scala.version}</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe.akka</groupId>
- <artifactId>akka-remote_${scala.version}</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe.akka</groupId>
- <artifactId>akka-cluster_${scala.version}</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe.akka</groupId>
- <artifactId>akka-osgi_${scala.version}</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe</groupId>
- <artifactId>config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.jayway.awaitility</groupId>
- <artifactId>awaitility</artifactId>
- <version>1.6.5</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Provides initial and failed state for NodeManagers
- */
-@Beta
-public interface InitialStateProvider {
- @Nonnull
- Node getInitialState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode);
-
- @Nonnull
- Node getFailedState(@Nonnull final NodeId nodeId, @Nullable final Node configNode);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Node events that happen on a single node on cluster, for a method to notify remote nodes of these events look into RemoteNodeListener
- */
-@Beta
-public interface NodeListener extends RoleChangeListener {
-
- @Nonnull ListenableFuture<Node> onNodeCreated(@Nonnull NodeId nodeId, @Nonnull Node configNode);
-
- @Nonnull ListenableFuture<Node> onNodeUpdated(@Nonnull NodeId nodeId, @Nonnull Node configNode);
-
- @Nonnull ListenableFuture<Void> onNodeDeleted(@Nonnull NodeId nodeId);
-
- @Nonnull ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-
-/**
- * Node manager that handles communication between node managers and delegates calls to the customizable NodeManagerCallback
- */
-@Beta
-public interface NodeManager extends InitialStateProvider, NodeListener, Receiver, RemoteNodeListener, RemoteDeviceHandler<NetconfSessionPreferences> {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-
-/**
- * Customizable layer that handles communication with your application.
- */
-@Beta
-public interface NodeManagerCallback extends InitialStateProvider, NodeListener, Receiver, RemoteDeviceHandler<NetconfSessionPreferences> {
-
- interface NodeManagerCallbackFactory<M> {
- NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import scala.concurrent.Future;
-
-/**
- * Interface that provides methods of calling node events on a remote actor.
- * Use these when you want to call node events asynchronously similar to akka ask()
- */
-@Beta
-public interface RemoteNodeListener {
-
- /**
- * This is called when a remote node is informing you that a new configuration was recieved.
- * @param message - serializable message to send
- * @return response from the remote node
- */
- Future<NormalizedNodeMessage> onRemoteNodeCreated(NormalizedNodeMessage message);
-
- /**
- * This is called when a remote node is informing you that a configuration was updated.
- * @param message - serializable message to send
- * @return response from the remote node
- */
- Future<NormalizedNodeMessage> onRemoteNodeUpdated(NormalizedNodeMessage message);
-
- /**
- * This is called when a remote node is informing you that a new configuration was deleted.
- * @param nodeId - id of the node which was deleted
- * @return void future success if delete succeed, failure otherwise
- */
- Future<Void> onRemoteNodeDeleted(NodeId nodeId);
-
- /**
- * Called when a remote node is requesting a node's status, after a status change notification(f.ex sessionUp, sessionDown)
- * on lower level
- * @param nodeId - id of the node which status we want to retrieve
- * @return status for the node requested
- */
- Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(NodeId nodeId);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A listener that recieves {@link #onRoleChanged(RoleChangeDTO)} callbacks when a role change occurs
- */
-@Beta
-public interface RoleChangeListener {
-
- /**
- * Called when a role change occurs
- * @param roleChangeDTO a DTO that wraps the current ownership status
- */
- void onRoleChanged(RoleChangeDTO roleChangeDTO);
-
- /**
- * A DTO that wraps an ownership change status
- */
- class RoleChangeDTO {
-
- private final boolean wasOwner;
- private final boolean isOwner;
- private final boolean hasOwner;
-
- public RoleChangeDTO(boolean wasOwner, boolean isOwner, boolean hasOwner) {
- this.wasOwner = wasOwner;
- this.isOwner = isOwner;
- this.hasOwner = hasOwner;
- }
-
- public boolean wasOwner() {
- return wasOwner;
- }
-
- public boolean isOwner() {
- return isOwner;
- }
-
- public boolean hasOwner() {
- return hasOwner;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A customizable strategy that gets executed when a BaseTopologyManager|BaseNodeManager is created.
- * If the election should be executed at another moment, you need to pass the NoopRoleChangeStrategy into the Manager
- * and the role candidate registration needs to happen in your implemented Node/Topology callback
- */
-@Beta
-public interface RoleChangeStrategy extends RoleChangeListener {
-
- /**
- * Your pre-election and election logic goes here, e.g you should register your candidate into the ElectionService
- * @param electionCandidate NodeListener that should receive the subsequent onRoleChanged callback
- * when a role change occurs.
- */
- void registerRoleCandidate(NodeListener electionCandidate);
-
- /**
- * Invoke whenever you want to stop candidate from partaking in election.
- */
- void unregisterRoleCandidate();
-
- /**
- *
- * @return True/False based on if this candidate is already registered into ownership service
- */
- boolean isCandidateRegistered();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Aggregate different node states into a single state
- */
-@Beta
-public interface StateAggregator {
-
- ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures);
-
- ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures);
-
- ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import akka.actor.TypedActor.PostStop;
-import akka.actor.TypedActor.PreStart;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import scala.concurrent.Future;
-
-/**
- * Top level topology manager that handles comunication between nodes, aggregates results, and handles writes into the datastore
- */
-@Beta
-public interface TopologyManager extends NodeListener, Receiver, RemoteNodeListener, PreStart, PostStop{
-
- /**
- * ask if this manager is master
- * @return true/false based on ownership status
- */
- Future<Boolean> isMaster();
-
- /**
- *
- * @param nodeId - id of the node that sessionUp/Down happened on
- */
- void notifyNodeStatusChange(NodeId nodeId);
-
- boolean hasAllPeersUp();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-
-/**
- * Customizable extension layer between the top level TopologyManager and NodeManager
- */
-@Beta
-public interface TopologyManagerCallback extends InitialStateProvider, NodeListener, Receiver, RoleChangeListener {
-
- interface TopologyManagerCallbackFactory {
- TopologyManagerCallback create(ActorSystem actorSystem, String topologyId);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.example;
-
-import akka.actor.ActorRef;
-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.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class ExampleNodeManagerCallback implements NodeManagerCallback {
-
- public ExampleNodeManagerCallback() {
- }
-
- @Nonnull
- @Override public Node getInitialState(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- return new NodeBuilder().addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connecting).build()).build();
- }
-
- @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- return new NodeBuilder().addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.UnableToConnect).build()).build();
- }
-
- @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- return Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connected).build()).build());
- }
-
- @Nonnull @Override public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- // update magic
- return Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connected).build()).build());
- }
-
- @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
- return Futures.immediateFuture(null);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- return null;
- }
-
- @Override
- public void onReceive(Object message, ActorRef sender) {
-
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
- }
-
- @Override
- public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
-
- }
-
- @Override
- public void onDeviceDisconnected() {
-
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
-
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
-
- }
-
- @Override
- public void close() {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.example;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Aggregator implementation expecting just a single state
- */
-public final class ExampleSingleStateAggregator implements StateAggregator {
-
- @Override public ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures) {
- return getSingleFuture(stateFutures);
- }
-
- private <T> ListenableFuture<T> getSingleFuture(final List<ListenableFuture<T>> stateFutures) {
- Preconditions.checkArgument(stateFutures.size() == 1, "Recieved multiple results, Single result is enforced here");
- return stateFutures.get(0);
- }
-
- @Override public ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures) {
- return getSingleFuture(stateFutures);
- }
-
- @Override public ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures) {
- return getSingleFuture(stateFutures);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.example;
-
-import akka.actor.ActorSystem;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-
-public class ExampleTopology {
-
- private static final String TOPOLOGY_NETCONF = "topology-netconf";
- private BaseTopologyManager netconfNodeBaseTopologyManager;
- private final DataBroker dataBroker;
-
- public ExampleTopology(final EntityOwnershipService entityOwnershipService, final DataBroker dataBroker) {
- final ActorSystem actorSystem = ActorSystem.create("netconf-cluster");
-
- this.dataBroker = dataBroker;
-
- final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
- @Override
- public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
- return new ExampleNodeManagerCallback();
- }
- };
-
- final TopologyManagerCallbackFactory topologyManagerCallbackFactory = new TopologyManagerCallbackFactory() {
- @Override
- public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
- return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory);
- }
- };
-
-// netconfNodeBaseTopologyManager = new BaseTopologyManager<>(dataBroker, TOPOLOGY_NETCONF,
-// topologyManagerCallbackFactory,
-// new SingleStateAggregator(),
-// new SalNodeWriter(dataBroker, TOPOLOGY_NETCONF),
-// new TopologyRoleChangeStrategy(dataBroker, entityOwnershipService, "netconf", TOPOLOGY_NETCONF));
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.example;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.util.BaseNodeManager.BaseNodeManagerBuilder;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.SalNodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ExampleTopologyManagerCallback implements TopologyManagerCallback {
-
- private static final Logger LOG = LoggerFactory.getLogger(ExampleTopologyManagerCallback.class);
-
- private final DataBroker dataBroker;
- private final ActorSystem actorSystem;
- private boolean isMaster;
-
- private final String topologyId;
- private final NodeWriter naSalNodeWriter;
- private final Map<NodeId, NodeManager> nodes = new HashMap<>();
- private final NodeManagerCallbackFactory nodeHandlerFactory;
-
- public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
- final DataBroker dataBroker,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory) {
- this(actorSystem, dataBroker, topologyId, nodeHandlerFactory, new SalNodeWriter(dataBroker, topologyId));
- }
-
- public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
- final DataBroker dataBroker,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory,
- final NodeWriter naSalNodeWriter) {
- this(actorSystem, dataBroker, topologyId, nodeHandlerFactory, naSalNodeWriter, false);
-
- }
-
- public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
- final DataBroker dataBroker,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory,
- final NodeWriter naSalNodeWriter,
- boolean isMaster) {
- this.dataBroker = dataBroker;
- this.actorSystem = actorSystem;
- this.topologyId = topologyId;
- this.nodeHandlerFactory = nodeHandlerFactory;
- this.naSalNodeWriter = naSalNodeWriter;
-
- this.isMaster = isMaster;
- }
-
- @Override
- public ListenableFuture<Node> onNodeCreated(NodeId nodeId, Node node) {
- // Init node admin and a writer for it
-
- // TODO let end user code notify the baseNodeManager about state changes and handle them here on topology level
- final NodeManager naBaseNodeManager =
- createNodeManager(nodeId);
-
- nodes.put(nodeId, naBaseNodeManager);
-
- // Set initial state ? in every peer or just master ? TODO
- if (isMaster) {
- naSalNodeWriter.init(nodeId, naBaseNodeManager.getInitialState(nodeId, node));
- }
-
- // trigger connect on this node
- return naBaseNodeManager.onNodeCreated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
- // Set initial state
- naSalNodeWriter.init(nodeId, nodes.get(nodeId).getInitialState(nodeId, node));
-
- // Trigger onNodeUpdated only on this node
- return nodes.get(nodeId).onNodeUpdated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
- // Trigger delete only on this node
- final ListenableFuture<Void> future = nodes.get(nodeId).onNodeDeleted(nodeId);
- Futures.addCallback(future, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- // remove proxy from node list and stop the actor
- final NodeManager remove = nodes.remove(nodeId);
- TypedActor.get(actorSystem).stop(remove);
- }
-
- @Override
- public void onFailure(Throwable t) {
- // NOOP will be handled on higher level
- }
- });
- return future;
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- return nodes.get(nodeId).getCurrentStatusForNode(nodeId);
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
- isMaster = roleChangeDTO.isOwner();
- // our post-election logic
- }
-
- private NodeManager createNodeManager(NodeId nodeId) {
- return new BaseNodeManagerBuilder().setNodeId(nodeId.getValue())
- .setActorContext(TypedActor.context())
- .setDelegateFactory(nodeHandlerFactory)
- .setRoleChangeStrategy(new NoopRoleChangeStrategy())
- .setTopologyId(topologyId)
- .build();
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
-
- }
-
- @Nonnull
- @Override
- public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- return nodes.get(nodeId).getInitialState(nodeId, configNode);
- }
-
- @Nonnull
- @Override
- public Node getFailedState(@Nonnull NodeId nodeId, @Nullable Node configNode) {
- return nodes.get(nodeId).getFailedState(nodeId, configNode);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.example;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import javax.annotation.Nonnull;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LoggingSalNodeWriter implements NodeWriter{
-
- private static final Logger LOG = LoggerFactory.getLogger(LoggingSalNodeWriter.class);
-
- private final ArrayList<NodeWriter> delegates;
-
- public LoggingSalNodeWriter(final NodeWriter... delegates) {
- this.delegates = new ArrayList<>(Arrays.asList(delegates));
- }
-
- @Override
- public void init(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
- LOG.warn("Init recieved");
- LOG.warn("NodeId: {}", id.getValue());
- LOG.warn("Node: {}", operationalDataNode);
- for (final NodeWriter delegate : delegates) {
- delegate.init(id, operationalDataNode);
- }
- }
-
- @Override
- public void update(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
- LOG.warn("Update recieved");
- LOG.warn("NodeId: {}", id.getValue());
- LOG.warn("Node: {}", operationalDataNode);
- for (final NodeWriter delegate : delegates) {
- delegate.update(id, operationalDataNode);
- }
- }
-
- @Override
- public void delete(@Nonnull NodeId id) {
- LOG.warn("Delete recieved");
- LOG.warn("NodeId: {}", id.getValue());
- for (final NodeWriter delegate : delegates) {
- delegate.delete(id);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-
-public final class BaseNodeManager implements NodeManager {
-
- private static final Logger LOG = LoggerFactory.getLogger(BaseNodeManager.class);
-
- private final String nodeId;
- private final NodeManagerCallback delegate;
-
- private BaseNodeManager(final String nodeId,
- final String topologyId,
- final ActorSystem actorSystem,
- final NodeManagerCallbackFactory delegateFactory,
- final RoleChangeStrategy roleChangeStrategy) {
- LOG.debug("Creating BaseNodeManager, id: {}, {}", topologyId, nodeId );
- this.nodeId = nodeId;
- this.delegate = delegateFactory.create(nodeId, topologyId, actorSystem);
- // if we want to override the place election happens,
- // we need to override this with noop election strategy and implement election in callback
- // cannot leak "this" here! have to use TypedActor.self()
- roleChangeStrategy.registerRoleCandidate((NodeManager) TypedActor.self());
- }
-
- @Nonnull @Override public Node getInitialState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
- LOG.trace("Retrieving Node {} initial state", nodeId);
- return delegate.getInitialState(nodeId, configNode);
- }
-
- @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
- LOG.trace("Retrieving Node {} failed state", nodeId);
- return delegate.getFailedState(nodeId, configNode);
- }
-
- @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
- LOG.debug("Creating Node {}, with configuration: {}", nodeId.getValue(), configNode);
- return delegate.onNodeCreated(nodeId, configNode);
- }
-
- @Nonnull @Override public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
- LOG.debug("Updating Node {}, with configuration: {}", nodeId.getValue(), configNode);
- return delegate.onNodeUpdated(nodeId, configNode);
- }
-
- @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
- LOG.debug("Deleting Node {}", nodeId.getValue());
- return delegate.onNodeDeleted(nodeId);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- LOG.debug("Getting current status for node: {}", nodeId.getValue());
- return delegate.getCurrentStatusForNode(nodeId);
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
- LOG.debug("Node {} role has changed from: {} to {}", nodeId,
- (roleChangeDTO.wasOwner() ? "master" : "slave"),
- (roleChangeDTO.isOwner() ? "master" : "slave"));
-
- delegate.onRoleChanged(roleChangeDTO);
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
- delegate.onReceive(o, actorRef);
- }
-
- @Override
- public Future<NormalizedNodeMessage> onRemoteNodeCreated(final NormalizedNodeMessage message) {
- return null;
- }
-
- @Override
- public Future<NormalizedNodeMessage> onRemoteNodeUpdated(final NormalizedNodeMessage message) {
- return null;
- }
-
- @Override
- public Future<Void> onRemoteNodeDeleted(final NodeId nodeId) {
- return null;
- }
-
- @Override
- public Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(final NodeId nodeId) {
- return null;
- }
-
- @Override
- public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
- delegate.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
- }
-
- @Override
- public void onDeviceDisconnected() {
- delegate.onDeviceDisconnected();
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
- delegate.onDeviceFailed(throwable);
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
- delegate.onNotification(domNotification);
- }
-
- @Override
- public void close() {
- // NOOP
- }
-
- /**
- * Builder of BaseNodeManager instances that are proxied as TypedActors
- */
- public static class BaseNodeManagerBuilder {
- private String nodeId;
- private String topologyId;
- private NodeManagerCallbackFactory delegateFactory;
- private RoleChangeStrategy roleChangeStrategy;
- private ActorContext actorContext;
-
-
- public BaseNodeManagerBuilder setNodeId(final String nodeId) {
- this.nodeId = nodeId;
- return this;
- }
-
- public BaseNodeManagerBuilder setTopologyId(final String topologyId) {
- this.topologyId = topologyId;
- return this;
- }
-
- public BaseNodeManagerBuilder setDelegateFactory(final NodeManagerCallbackFactory delegateFactory) {
- this.delegateFactory = delegateFactory;
- return this;
- }
-
- public BaseNodeManagerBuilder setRoleChangeStrategy(final RoleChangeStrategy roleChangeStrategy) {
- this.roleChangeStrategy = roleChangeStrategy;
- return this;
- }
-
- public BaseNodeManagerBuilder setActorContext(final ActorContext actorContext) {
- this.actorContext = actorContext;
- return this;
- }
-
- public NodeManager build() {
- Preconditions.checkNotNull(nodeId);
- Preconditions.checkNotNull(topologyId);
- Preconditions.checkNotNull(delegateFactory);
- Preconditions.checkNotNull(roleChangeStrategy);
- Preconditions.checkNotNull(actorContext);
- LOG.debug("Creating typed actor with id: {}", nodeId);
-
- return TypedActor.get(actorContext).typedActorOf(new TypedProps<>(NodeManager.class, new Creator<BaseNodeManager>() {
- @Override
- public BaseNodeManager create() throws Exception {
- return new BaseNodeManager(nodeId, topologyId, actorContext.system(), delegateFactory, roleChangeStrategy);
- }
- }), nodeId);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorIdentity;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.Address;
-import akka.actor.Identify;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.ClusterEvent;
-import akka.cluster.ClusterEvent.MemberEvent;
-import akka.cluster.ClusterEvent.MemberExited;
-import akka.cluster.ClusterEvent.MemberRemoved;
-import akka.cluster.ClusterEvent.MemberUp;
-import akka.cluster.ClusterEvent.ReachableMember;
-import akka.cluster.ClusterEvent.UnreachableMember;
-import akka.cluster.Member;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.util.messages.CustomIdentifyMessage;
-import org.opendaylight.netconf.topology.util.messages.CustomIdentifyMessageReply;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-import scala.concurrent.impl.Promise.DefaultPromise;
-
-public final class BaseTopologyManager
- implements TopologyManager {
-
- private static final Logger LOG = LoggerFactory.getLogger(BaseTopologyManager.class);
-
- private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
-
- private final ActorSystem system;
- private final TypedActorExtension typedExtension;
- private final Cluster clusterExtension;
-
- private final BindingNormalizedNodeCodecRegistry codecRegistry;
-
- private static final String PATH = "/user/";
-
- private final DataBroker dataBroker;
- private final RoleChangeStrategy roleChangeStrategy;
- private final StateAggregator aggregator;
-
- private final NodeWriter naSalNodeWriter;
- private final String topologyId;
- private final TopologyManagerCallback delegateTopologyHandler;
- private final Set<NodeId> created = new HashSet<>();
-
- private final Map<Address, TopologyManager> peers = new HashMap<>();
- private final int id = new Random().nextInt();
-
- private boolean isMaster;
-
- public BaseTopologyManager(final ActorSystem system,
- final BindingNormalizedNodeCodecRegistry codecRegistry,
- final DataBroker dataBroker,
- final String topologyId,
- final TopologyManagerCallbackFactory topologyManagerCallbackFactory,
- final StateAggregator aggregator,
- final NodeWriter naSalNodeWriter,
- final RoleChangeStrategy roleChangeStrategy) {
- this(system, codecRegistry, dataBroker, topologyId, topologyManagerCallbackFactory, aggregator, naSalNodeWriter, roleChangeStrategy, false);
- }
-
- public BaseTopologyManager(final ActorSystem system,
- final BindingNormalizedNodeCodecRegistry codecRegistry,
- final DataBroker dataBroker,
- final String topologyId,
- final TopologyManagerCallbackFactory topologyManagerCallbackFactory,
- final StateAggregator aggregator,
- final NodeWriter naSalNodeWriter,
- final RoleChangeStrategy roleChangeStrategy,
- final boolean isMaster) {
-
- this.system = system;
- this.typedExtension = TypedActor.get(system);
- this.clusterExtension = Cluster.get(system);
- this.dataBroker = dataBroker;
- this.topologyId = topologyId;
- this.delegateTopologyHandler = topologyManagerCallbackFactory.create(system, topologyId);
- this.aggregator = aggregator;
- this.naSalNodeWriter = naSalNodeWriter;
- this.roleChangeStrategy = roleChangeStrategy;
- this.codecRegistry = codecRegistry;
-
- // election has not yet happened
- this.isMaster = isMaster;
-
- this.topologyListPath = TopologyUtil.createTopologyListPath(topologyId);
-
- LOG.debug("Base manager started ", +id);
- }
-
- @Override
- public void preStart() {
- LOG.debug("preStart called");
- // TODO change to enum, master/slave active/standby
- roleChangeStrategy.registerRoleCandidate(TypedActor.<BaseTopologyManager>self());
- LOG.debug("candidate registered");
- clusterExtension.subscribe(TypedActor.context().self(), ClusterEvent.initialStateAsEvents(), MemberEvent.class, UnreachableMember.class);
- }
-
- @Override
- public void postStop() {
- LOG.debug("postStop called");
- clusterExtension.leave(clusterExtension.selfAddress());
- clusterExtension.unsubscribe(TypedActor.context().self());
- }
-
- @Override
- public ListenableFuture<Node> onNodeCreated(final NodeId nodeId, final Node node) {
- LOG.debug("TopologyManager({}) onNodeCreated received, nodeid: {} , isMaster: {}", id, nodeId.getValue(), isMaster);
-
- if (created.contains(nodeId)) {
- LOG.warn("Node{} already exists, triggering update..", nodeId);
- return onNodeUpdated(nodeId, node);
- }
- created.add(nodeId);
- final ArrayList<ListenableFuture<Node>> futures = new ArrayList<>();
-
- if (isMaster) {
-
- futures.add(delegateTopologyHandler.onNodeCreated(nodeId, node));
- // only master should call connect on peers and aggregate futures
- for (TopologyManager topologyManager : peers.values()) {
- // convert binding into NormalizedNode for transfer
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), node);
-
- LOG.debug("YangInstanceIdentifier {}", normalizedNodeEntry.getKey());
- LOG.debug("Value {}", normalizedNodeEntry.getValue());
-
- // add a future into our futures that gets its completion status from the converted scala future
- final SettableFuture<Node> settableFuture = SettableFuture.create();
- futures.add(settableFuture);
- final Future<NormalizedNodeMessage> scalaFuture = topologyManager.onRemoteNodeCreated(new NormalizedNodeMessage(normalizedNodeEntry.getKey(), normalizedNodeEntry.getValue()));
- scalaFuture.onComplete(new OnComplete<NormalizedNodeMessage>() {
- @Override
- public void onComplete(Throwable failure, NormalizedNodeMessage success) throws Throwable {
- if (failure != null) {
- settableFuture.setException(failure);
- return;
- }
- final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
- codecRegistry.fromNormalizedNode(success.getIdentifier(), success.getNode());
- final Node value = (Node) fromNormalizedNode.getValue();
-
- settableFuture.set(value);
- }
- }, TypedActor.context().dispatcher());
- }
-
- final ListenableFuture<Node> aggregatedFuture = aggregator.combineCreateAttempts(futures);
- Futures.addCallback(aggregatedFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(final Node result) {
- LOG.debug("Futures aggregated succesfully");
- naSalNodeWriter.init(nodeId, result);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- // If the combined connection attempt failed, set the node to connection failed
- LOG.debug("Futures aggregation failed");
- naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, node));
- }
- }, TypedActor.context().dispatcher());
-
- //combine peer futures
- return aggregatedFuture;
- }
-
- // trigger create on this slave
- return delegateTopologyHandler.onNodeCreated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
- LOG.debug("TopologyManager({}) onNodeUpdated received, nodeid: {}", id, nodeId.getValue());
-
- // Master needs to trigger onNodeUpdated on peers and combine results
- if (isMaster) {
- // first cleanup old node
- final ListenableFuture<Void> deleteFuture = onNodeDeleted(nodeId);
- final SettableFuture<Node> createFuture = SettableFuture.create();
- final TopologyManager selfProxy = TypedActor.self();
- final ActorContext context = TypedActor.context();
- Futures.addCallback(deleteFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- LOG.warn("Delete part of update succesfull, triggering create");
- // trigger create on all nodes
- Futures.addCallback(selfProxy.onNodeCreated(nodeId, node), new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- createFuture.set(result);
- }
-
- @Override
- public void onFailure(Throwable t) {
- createFuture.setException(t);
- }
- }, context.dispatcher());
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.warn("Delete part of update failed, {}", t);
- }
- }, context.dispatcher());
- return createFuture;
- }
-
- // Trigger update on this slave
- return delegateTopologyHandler.onNodeUpdated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
- final ArrayList<ListenableFuture<Void>> futures = new ArrayList<>();
- created.remove(nodeId);
-
- // Master needs to trigger delete on peers and combine results
- if (isMaster) {
- futures.add(delegateTopologyHandler.onNodeDeleted(nodeId));
- for (TopologyManager topologyManager : peers.values()) {
- // add a future into our futures that gets its completion status from the converted scala future
- final SettableFuture<Void> settableFuture = SettableFuture.create();
- futures.add(settableFuture);
- final Future<Void> scalaFuture = topologyManager.onRemoteNodeDeleted(nodeId);
- scalaFuture.onComplete(new OnComplete<Void>() {
- @Override
- public void onComplete(Throwable failure, Void success) throws Throwable {
- if (failure != null) {
- settableFuture.setException(failure);
- return;
- }
-
- settableFuture.set(success);
- }
- }, TypedActor.context().dispatcher());
- }
-
- final ListenableFuture<Void> aggregatedFuture = aggregator.combineDeleteAttempts(futures);
- Futures.addCallback(aggregatedFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- naSalNodeWriter.delete(nodeId);
- }
-
- @Override
- public void onFailure(final Throwable t) {
-
- }
- });
-
- return aggregatedFuture;
- }
-
- // Trigger delete
- return delegateTopologyHandler.onNodeDeleted(nodeId);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull final NodeId nodeId) {
- return delegateTopologyHandler.getCurrentStatusForNode(nodeId);
- }
-
- @Override
- public void onRoleChanged(final RoleChangeDTO roleChangeDTO) {
- isMaster = roleChangeDTO.isOwner();
- delegateTopologyHandler.onRoleChanged(roleChangeDTO);
- if (isMaster) {
- LOG.debug("Node {} is master now", clusterExtension.selfAddress());
- clusterExtension.join(clusterExtension.selfAddress());
- }
- }
-
- @Override
- public Future<Boolean> isMaster() {
- return new DefaultPromise<Boolean>().success(isMaster).future();
- }
-
- @Override
- public void notifyNodeStatusChange(final NodeId nodeId) {
- LOG.debug("Connection status has changed on node {}", nodeId.getValue());
- if (isMaster) {
- // grab status from all peers and aggregate
- final ArrayList<ListenableFuture<Node>> futures = new ArrayList<>();
- futures.add(delegateTopologyHandler.getCurrentStatusForNode(nodeId));
- // only master should call connect on peers and aggregate futures
- for (TopologyManager topologyManager : peers.values()) {
- // add a future into our futures that gets its completion status from the converted scala future
- final SettableFuture<Node> settableFuture = SettableFuture.create();
- futures.add(settableFuture);
- final Future<NormalizedNodeMessage> scalaFuture = topologyManager.remoteGetCurrentStatusForNode(nodeId);
- scalaFuture.onComplete(new OnComplete<NormalizedNodeMessage>() {
- @Override
- public void onComplete(Throwable failure, NormalizedNodeMessage success) throws Throwable {
- if (failure != null) {
- settableFuture.setException(failure);
- return;
- }
- final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
- codecRegistry.fromNormalizedNode(success.getIdentifier(), success.getNode());
- final Node value = (Node) fromNormalizedNode.getValue();
-
- settableFuture.set(value);
- }
- }, TypedActor.context().dispatcher());
- }
-
- final ListenableFuture<Node> aggregatedFuture = aggregator.combineUpdateAttempts(futures);
- Futures.addCallback(aggregatedFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(final Node result) {
- LOG.debug("Futures aggregated succesfully");
- naSalNodeWriter.update(nodeId, result);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- // If the combined connection attempt failed, set the node to connection failed
- LOG.debug("Futures aggregation failed");
- naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, null));
- }
- });
- return;
- }
- LOG.debug("Not master, forwarding..");
- for (final TopologyManager manager : peers.values()) {
- // asynchronously find out which peer is master
- final Future<Boolean> future = manager.isMaster();
- future.onComplete(new OnComplete<Boolean>() {
- @Override
- public void onComplete(Throwable failure, Boolean success) throws Throwable {
- if (failure == null && success) {
- LOG.debug("Found master peer");
- // forward to master
- manager.notifyNodeStatusChange(nodeId);
- return;
- }
- if (failure != null) {
- LOG.debug("Retrieving master peer failed, {}", failure);
- }
- }
- }, TypedActor.context().dispatcher());
- }
- }
-
- @Override
- public boolean hasAllPeersUp() {
- LOG.debug("Peers needed: {} Peers up: {}", 2, peers.size());
- LOG.warn(clusterExtension.state().toString());
- LOG.warn(peers.toString());
- return peers.size() == 2;
- }
-
- @Override
- public Future<NormalizedNodeMessage> onRemoteNodeCreated(final NormalizedNodeMessage message) {
- final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
- codecRegistry.fromNormalizedNode(message.getIdentifier(), message.getNode());
- final InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>) fromNormalizedNode.getKey();
- final Node value = (Node) fromNormalizedNode.getValue();
-
- LOG.debug("TopologyManager({}) onRemoteNodeCreated received, nodeid: {}", value.getNodeId(), value);
- final ListenableFuture<Node> nodeListenableFuture = onNodeCreated(value.getNodeId(), value);
- final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(iid, result);
- promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
-
- return promise.future();
- }
-
- @Override
- public Future<NormalizedNodeMessage> onRemoteNodeUpdated(final NormalizedNodeMessage message) {
- final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
- codecRegistry.fromNormalizedNode(message.getIdentifier(), message.getNode());
- final InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>) fromNormalizedNode.getKey();
- final Node value = (Node) fromNormalizedNode.getValue();
-
- LOG.debug("TopologyManager({}) onRemoteNodeUpdated received, nodeid: {}", id, value.getNodeId());
-
- final ListenableFuture<Node> nodeListenableFuture = onNodeUpdated(value.getNodeId(), value);
- final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(iid, result);
- promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
- return promise.future();
- }
-
- @Override
- public Future<Void> onRemoteNodeDeleted(final NodeId nodeId) {
- LOG.debug("TopologyManager({}) onRemoteNodeDeleted received, nodeid: {}", id, nodeId.getValue());
-
- final ListenableFuture<Void> listenableFuture = onNodeDeleted(nodeId);
- final DefaultPromise<Void> promise = new DefaultPromise<>();
- Futures.addCallback(listenableFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- promise.success(null);
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
-
- return promise.future();
- }
-
- public Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(final NodeId nodeId) {
- LOG.debug("TopologyManager({}) remoteGetCurrentStatusForNode received, nodeid: {}", id, nodeId.getValue());
-
- final ListenableFuture<Node> listenableFuture = getCurrentStatusForNode(nodeId);
- final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
- Futures.addCallback(listenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), result);
- promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
- return promise.future();
- }
-
- @Override
- public void onReceive(final Object message, final ActorRef actorRef) {
- LOG.debug("message received {}", message);
- if (message instanceof MemberUp) {
- final Member member = ((MemberUp) message).member();
- LOG.info("Member is Up: {}", member);
- if (member.address().equals(clusterExtension.selfAddress())) {
- return;
- }
-
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
- final String path = pathCreator.build();
- LOG.debug("Actor at :{} is resolving topology actor for path {}", clusterExtension.selfAddress(), path);
-
- // first send basic identify message in case our messages have not been loaded through osgi yet to prevent crashing akka.
- clusterExtension.system().actorSelection(path).tell(new Identify(member.address()), TypedActor.context().self());
- } else if (message instanceof MemberExited) {
- // remove peer
- final Member member = ((MemberExited) message).member();
- LOG.info("Member exited cluster: {}", member);
- peers.remove(member.address());
- } else if (message instanceof MemberRemoved) {
- // remove peer
- final Member member = ((MemberRemoved) message).member();
- LOG.info("Member was removed from cluster: {}", member);
- peers.remove(member.address());
- } else if (message instanceof UnreachableMember) {
- // remove peer
- final Member member = ((UnreachableMember) message).member();
- LOG.info("Member is unreachable: {}", member);
- peers.remove(member.address());
- } else if (message instanceof ReachableMember) {
- // resync peer
- final Member member = ((ReachableMember) message).member();
- LOG.info("Member is reachable again: {}", member);
-
- if (member.address().equals(clusterExtension.selfAddress())) {
- return;
- }
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
- final String path = pathCreator.build();
- LOG.debug("Actor at :{} is resolving topology actor for path {}", clusterExtension.selfAddress(), path);
-
- clusterExtension.system().actorSelection(path).tell(new Identify(member.address()), TypedActor.context().self());
- } else if (message instanceof ActorIdentity) {
- LOG.debug("Received ActorIdentity message", message);
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(((ActorIdentity) message).correlationId().toString(), topologyId);
- final String path = pathCreator.build();
- if (((ActorIdentity) message).getRef() == null) {
- LOG.debug("ActorIdentity has null actor ref, retrying..", message);
- final ActorRef self = TypedActor.context().self();
- final ActorContext context = TypedActor.context();
- system.scheduler().scheduleOnce(new FiniteDuration(5, TimeUnit.SECONDS), new Runnable() {
- @Override
- public void run() {
- LOG.debug("Retrying identify message from master to node {} , full path {}", ((ActorIdentity) message).correlationId(), path);
- context.system().actorSelection(path).tell(new Identify(((ActorIdentity) message).correlationId()), self);
-
- }
- }, system.dispatcher());
- return;
- }
- LOG.debug("Actor at :{} is resolving topology actor for path {}, with a custom message", clusterExtension.selfAddress(), path);
-
- clusterExtension.system().actorSelection(path).tell(new CustomIdentifyMessage(clusterExtension.selfAddress()), TypedActor.context().self());
- } else if (message instanceof CustomIdentifyMessageReply) {
-
- LOG.warn("Received a custom identify reply message from: {}", ((CustomIdentifyMessageReply) message).getAddress());
- if (!peers.containsKey(((CustomIdentifyMessage) message).getAddress())) {
- final TopologyManager peer = typedExtension.typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
- peers.put(((CustomIdentifyMessageReply) message).getAddress(), peer);
- if (isMaster) {
- resyncPeer(peer);
- }
- }
- } else if (message instanceof CustomIdentifyMessage) {
- LOG.warn("Received a custom identify message from: {}", ((CustomIdentifyMessage) message).getAddress());
- if (!peers.containsKey(((CustomIdentifyMessage) message).getAddress())) {
- final TopologyManager peer = typedExtension.typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
- peers.put(((CustomIdentifyMessage) message).getAddress(), peer);
- if (isMaster) {
- resyncPeer(peer);
- }
- }
- actorRef.tell(new CustomIdentifyMessageReply(clusterExtension.selfAddress()), TypedActor.context().self());
- }
- }
-
- private void resyncPeer(final TopologyManager peer) {
- final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
- final CheckedFuture<Optional<Topology>, ReadFailedException> read = rTx.read(LogicalDatastoreType.CONFIGURATION, topologyListPath);
-
- Futures.addCallback(read, new FutureCallback<Optional<Topology>>() {
- @Override
- public void onSuccess(Optional<Topology> result) {
- if (result.isPresent() && result.get().getNode() != null) {
- for (final Node node : result.get().getNode()) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), node);
- peer.onRemoteNodeCreated(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
- // we dont care about the future from now on since we will be notified by the onConnected event
- }
- }
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("Unable to read from datastore");
- }
- });
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.NodeListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NodeRoleChangeStrategy implements RoleChangeStrategy, EntityOwnershipListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(NodeRoleChangeStrategy.class);
-
- private final EntityOwnershipService entityOwnershipService;
- private final String entityType;
- private final String entityName;
- private final Entity entity;
- private NodeListener ownershipCandidate;
-
- private EntityOwnershipCandidateRegistration candidateRegistration = null;
- private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
- public NodeRoleChangeStrategy(final EntityOwnershipService entityOwnershipService,
- final String entityType,
- final String entityName) {
- this.entityOwnershipService = entityOwnershipService;
- this.entityType = entityType + "/" + entityName;
- this.entityName = entityName;
- this.entity = new Entity(this.entityType, entityName);
- }
-
- @Override
- public void registerRoleCandidate(NodeListener electionCandidate) {
- LOG.debug("Registering role candidate type: {} , name: {}", entityType, entityName);
- this.ownershipCandidate = electionCandidate;
- try {
- if (candidateRegistration != null) {
- unregisterRoleCandidate();
- }
- candidateRegistration = entityOwnershipService.registerCandidate(entity);
- ownershipListenerRegistration = entityOwnershipService.registerListener(entityType, this);
- } catch (CandidateAlreadyRegisteredException e) {
- LOG.error("Candidate already registered for election", e);
- throw new IllegalStateException("Candidate already registered for election", e);
- }
- }
-
- @Override
- public void unregisterRoleCandidate() {
- LOG.debug("Unregistering role candidate");
- if (candidateRegistration != null) {
- candidateRegistration.close();
- candidateRegistration = null;
- }
- if (ownershipListenerRegistration != null) {
- ownershipListenerRegistration.close();
- ownershipListenerRegistration = null;
- }
- }
-
- @Override
- public boolean isCandidateRegistered() {
- return entityOwnershipService.isCandidateRegistered(entity);
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
- LOG.debug("Role was changed {}", roleChangeDTO);
- ownershipCandidate.onRoleChanged(roleChangeDTO);
- }
-
- @Override
- public void ownershipChanged(EntityOwnershipChange ownershipChange) {
- LOG.debug("Ownership has changed {}", ownershipChange);
- ownershipCandidate.onRoleChanged(new RoleChangeDTO(ownershipChange.wasOwner(), ownershipChange.isOwner(), ownershipChange.hasOwner()));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Customizable code that gets executed after result aggregation, meant for custom writes
- * into the datastore, but any user code can be run here if desired.
- */
-@Beta
-public interface NodeWriter {
-
- void init(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode);
-
- void update(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode);
-
- void delete(@Nonnull final NodeId id);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import org.opendaylight.netconf.topology.NodeListener;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-
-/**
- * Use this strategy to override the default roleChange registration's in BaseTopologyManager|BaseNodeManager
- * If you use this, you will need to execute your own election in your implemented callbacks.
- */
-public class NoopRoleChangeStrategy implements RoleChangeStrategy {
-
- @Override
- public void registerRoleCandidate(NodeListener electionCandidate) {
-
- }
-
- @Override
- public void unregisterRoleCandidate() {
-
- }
-
- @Override
- public boolean isCandidateRegistered() {
- return false;
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class SalNodeWriter implements NodeWriter {
-
- private static final Logger LOG = LoggerFactory.getLogger(SalNodeWriter.class);
-
- private final String topologyId;
-
- private final BindingTransactionChain transactionChain;
- public SalNodeWriter(final DataBroker dataBroker, final String topologyId) {
- this.topologyId = topologyId;
- this.transactionChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(new TransactionChainListener() {
- @Override
- public void onTransactionChainFailed(TransactionChain<?, ?> transactionChain, AsyncTransaction<?, ?> transaction, Throwable cause) {
- LOG.error("{}: TransactionChain({}) {} FAILED!", transactionChain,
- transaction.getIdentifier(), cause);
- throw new IllegalStateException("Abstract topology writer TransactionChain(" + transactionChain + ") not committed correctly", cause);
- }
-
- @Override
- public void onTransactionChainSuccessful(TransactionChain<?, ?> transactionChain) {
- LOG.trace("Abstract topology writer TransactionChain({}) SUCCESSFUL", transactionChain);
- }
- });
- }
-
- @Override public void init(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode) {
- // put into Datastore
- final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
- wTx.put(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId), operationalDataNode);
- commitTransaction(wTx, id, "init");
- }
-
- @Override public void update(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode) {
- // merge
- final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
- wTx.put(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId), operationalDataNode);
- commitTransaction(wTx, id, "update");
- }
-
- @Override public void delete(@Nonnull final NodeId id) {
- // delete
- final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
- wTx.delete(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId));
- commitTransaction(wTx, id, "delete");
- }
-
- private void commitTransaction(final WriteTransaction transaction, final NodeId id, final String txType) {
- LOG.debug("{}: Committing Transaction {}:{}", id.getValue(), txType,
- transaction.getIdentifier());
- final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
-
- Futures.addCallback(result, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- LOG.debug("{}: Transaction({}) {} SUCCESSFUL", id.getValue(), txType,
- transaction.getIdentifier());
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("{}: Transaction({}) {} FAILED!", id.getValue(), txType,
- transaction.getIdentifier(), t);
- throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly", t);
- }
- });
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util;
-
-import java.util.Collection;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.netconf.topology.NodeListener;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyRoleChangeStrategy implements RoleChangeStrategy, ClusteredDataTreeChangeListener<Node>, EntityOwnershipListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(TopologyRoleChangeStrategy.class);
-
- private final DataBroker dataBroker;
-
- private final EntityOwnershipService entityOwnershipService;
- private NodeListener ownershipCandidate;
- private final String entityType;
- // use topologyId as entityName
- private final Entity entity;
-
- private EntityOwnershipCandidateRegistration candidateRegistration = null;
- private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
- private ListenerRegistration<TopologyRoleChangeStrategy> datastoreListenerRegistration;
-
- public TopologyRoleChangeStrategy(final DataBroker dataBroker,
- final EntityOwnershipService entityOwnershipService,
- final String entityType,
- final String entityName) {
- this.dataBroker = dataBroker;
- this.entityOwnershipService = entityOwnershipService;
- this.entityType = entityType;
- this.entity = new Entity(entityType, entityName);
-
- datastoreListenerRegistration = null;
- }
-
- @Override
- public void registerRoleCandidate(NodeListener electionCandidate) {
- LOG.warn("Registering candidate");
- ownershipCandidate = electionCandidate;
- try {
- if (candidateRegistration != null) {
- unregisterRoleCandidate();
- }
- candidateRegistration = entityOwnershipService.registerCandidate(entity);
- ownershipListenerRegistration = entityOwnershipService.registerListener(entityType, this);
- } catch (CandidateAlreadyRegisteredException e) {
- LOG.error("Candidate already registered for election", e);
- throw new IllegalStateException("Candidate already registered for election", e);
- }
- }
-
- @Override
- public void unregisterRoleCandidate() {
- candidateRegistration.close();
- candidateRegistration = null;
- ownershipListenerRegistration.close();
- ownershipListenerRegistration = null;
- }
-
- @Override
- public boolean isCandidateRegistered() {
- return entityOwnershipService.isCandidateRegistered(entity);
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
- if (roleChangeDTO.isOwner()) {
- LOG.warn("Gained ownership of entity, registering datastore listener");
-
- if (datastoreListenerRegistration == null) {
- LOG.debug("Listener on path {}", TopologyUtil.createTopologyListPath(entityType).child(Node.class).getPathArguments());
- datastoreListenerRegistration = dataBroker.registerDataTreeChangeListener(
- new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, TopologyUtil.createTopologyListPath(entityType).child(Node.class)), this);
- }
- } else if (datastoreListenerRegistration != null) {
- LOG.warn("No longer owner of entity, unregistering datastore listener");
- datastoreListenerRegistration.close();
- datastoreListenerRegistration = null;
- }
- ownershipCandidate.onRoleChanged(roleChangeDTO);
- }
-
- @Override
- public void ownershipChanged(final EntityOwnershipChange ownershipChange) {
- onRoleChanged(new RoleChangeDTO(ownershipChange.wasOwner(), ownershipChange.isOwner(), ownershipChange.hasOwner()));
- }
-
- @Override
- public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Node>> changes) {
- for (DataTreeModification<Node> change : changes) {
- final DataObjectModification<Node> rootNode = change.getRootNode();
- switch (rootNode.getModificationType()) {
- case WRITE:
- LOG.debug("Data was Created {}, {}", rootNode.getIdentifier(), rootNode.getDataAfter());
- ownershipCandidate.onNodeCreated(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
- break;
- case SUBTREE_MODIFIED:
- LOG.debug("Data was Updated {}, {}", rootNode.getIdentifier(), rootNode.getDataAfter());
- ownershipCandidate.onNodeUpdated(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
- break;
- case DELETE:
- LOG.debug("Data was Deleted {}", rootNode.getIdentifier());
- ownershipCandidate.onNodeDeleted(TopologyUtil.getNodeId(rootNode.getIdentifier()));
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterMountPoint implements Serializable {
- private static final long serialVersionUID = 1L;
-
- public AnnounceMasterMountPoint() {}
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterMountPointDown implements Serializable {
- private static final long serialVersionUID = 1L;
-
- public AnnounceMasterMountPointDown() {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util.messages;
-
-import akka.actor.Address;
-import java.io.Serializable;
-
-public class CustomIdentifyMessage implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private final Address address;
-
- public CustomIdentifyMessage(final Address addressFrom) {
- address = addressFrom;
- }
-
- public Address getAddress() {
- return address;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util.messages;
-
-import akka.actor.Address;
-
-// Marker message, that signals that actor should not reply to this one
-public class CustomIdentifyMessageReply extends CustomIdentifyMessage {
- private static final long serialVersionUID = 1L;
-
- public CustomIdentifyMessageReply(final Address addressFrom) {
- super(addressFrom);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.util.messages;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-
-public class NormalizedNodeMessage implements Externalizable{
- private static final long serialVersionUID = 1L;
-
- private YangInstanceIdentifier identifier = null;
- private NormalizedNode<?, ?> node = null;
-
- public NormalizedNodeMessage() {
-
- }
-
- public NormalizedNodeMessage(YangInstanceIdentifier identifier, NormalizedNode<?, ?> node) {
- this.identifier = identifier;
- this.node = node;
- }
-
- public YangInstanceIdentifier getIdentifier() {
- return identifier;
- }
-
- public NormalizedNode<?, ?> getNode() {
- return node;
- }
-
- @Override
- public void writeExternal(final ObjectOutput out) throws IOException {
- final NormalizedNodeDataOutput dataOutput = NormalizedNodeInputOutput.newDataOutput(out);
- final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter((NormalizedNodeStreamWriter) dataOutput);
-
- dataOutput.writeYangInstanceIdentifier(identifier);
- normalizedNodeWriter.write(node);
- }
-
- @Override
- public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
- final NormalizedNodeDataInput dataInput = NormalizedNodeInputOutput.newDataInput(in);
-
- identifier = dataInput.readYangInstanceIdentifier();
- node = dataInput.readNormalizedNode();
- }
-}
<artifactId>aaa-authn-odl-plugin</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>abstract-topology</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-config-dispatcher</artifactId>
<classifier>config</classifier>
<type>xml</type>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-topology-config</artifactId>
- <version>${project.version}</version>
- <classifier>clustered-config</classifier>
- <type>xml</type>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>yanglib-config</artifactId>
<type>xml</type>
<classifier>config</classifier>
</artifact>
- <artifact>
- <file>${project.build.directory}/classes/initial/02-clustered-netconf-topology.xml</file>
- <type>xml</type>
- <classifier>clustered-config</classifier>
- </artifact>
</artifacts>
</configuration>
</execution>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">prefix:clustered-netconf-topology-impl</type>
- <name>clustered-netconf-topology</name>
- <topology-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">topology-netconf</topology-id>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
- <name>global-netconf-ssh-scheduled-executor</name>
- </keepalive-executor>
- <shared-schema-repository xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology:shared:schema:repository">prefix:shared-schema-repository</type>
- <name>default-shared-schema-repository</name>
- </shared-schema-repository>
- <entity-ownership-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:entity-ownership-service">prefix:entity-ownership-service</type>
- <name>entity-ownership-service</name>
- </entity-ownership-service>
- <actor-system-provider-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:service">prefix:actor-system-provider-service</type>
- <name>actor-system-provider</name>
- </actor-system-provider-service>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">prefix:netconf-topology</type>
- <instance>
- <name>clustered-netconf-topology</name>
- <provider>/modules/module[type='clustered-netconf-topology-impl'][name='clustered-netconf-topology']</provider>
- </instance>
- </service>
- </services>
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:topology?module=netconf-topology&revision=2015-07-27</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology?module=clustered-netconf-topology&revision=2015-11-04</capability>
- <capability>
- urn:opendaylight:params:xml:ns:yang:controller:config:legacy-entity-ownership-service-provider?module=opendaylight-legacy-entity-ownership-service-provider&revision=2016-02-26
- </capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:service?module=actor-system-provider-service&revision=2015-10-05</capability>
- </required-capabilities>
-</snapshot>
\ No newline at end of file
<groupId>org.opendaylight.netconf</groupId>
<artifactId>sal-netconf-connector</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-clustering-commons</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>abstract-topology</artifactId>
- </dependency>
- <dependency>
- <groupId>com.typesafe</groupId>
- <artifactId>config</artifactId>
- </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.jayway.awaitility</groupId>
- <artifactId>awaitility</artifactId>
- <version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.controller.config.yang.clustered.netconf.topology;
-
-import org.opendaylight.netconf.topology.impl.ClusteredNetconfTopology;
-
-public class ClusteredNetconfTopologyModule extends org.opendaylight.controller.config.yang.clustered.netconf.topology.AbstractClusteredNetconfTopologyModule {
- public ClusteredNetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public ClusteredNetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.clustered.netconf.topology.ClusteredNetconfTopologyModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- return new ClusteredNetconfTopology(getTopologyId(),
- getClientDispatcherDependency(),
- getBindingRegistryDependency(),
- getDomRegistryDependency(),
- getEventExecutorDependency(),
- getKeepaliveExecutorDependency(),
- getProcessingExecutorDependency(),
- getSharedSchemaRepositoryDependency(),
- getActorSystemProviderServiceDependency().getActorSystem(),
- getEntityOwnershipServiceDependency());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/*
-* Generated file
-*
-* Generated from: yang module name: clustered-netconf-topology yang module local name: clustered-netconf-topology-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Nov 04 10:59:45 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.clustered.netconf.topology;
-public class ClusteredNetconfTopologyModuleFactory extends org.opendaylight.controller.config.yang.clustered.netconf.topology.AbstractClusteredNetconfTopologyModuleFactory {
-
-}
import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
import org.opendaylight.protocol.framework.TimedReconnectStrategy;
@Override
public abstract void onSessionInitiated(ProviderContext session);
- @Override
- public String getTopologyId() {
- return topologyId;
- }
-
- @Override
- public DataBroker getDataBroker() {
- return dataBroker;
- }
-
@Override
public ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode) {
LOG.info("Connecting RemoteDevice{{}} , with config {}", nodeId, configNode);
protected abstract RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker);
- @Override
- public abstract ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
-
@Override
public void onSessionInitiated(ProviderSession session) {
mountPointService = session.getService(DOMMountPointService.class);
package org.opendaylight.netconf.topology;
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
public interface NetconfTopology {
- String getTopologyId();
-
- DataBroker getDataBroker();
-
ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode);
ListenableFuture<Void> disconnectNode(NodeId nodeId);
- /**
- * register master mount point
- * @param context
- * @param nodeId
- */
- void registerMountPoint(ActorContext context, NodeId nodeId);
-
- /**
- * register slave mountpoint with the provided ActorRef
- * @param context
- * @param nodeId
- * @param masterRef
- */
- void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef);
-
- void unregisterMountPoint(NodeId nodeId);
-
- ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.netty.util.concurrent.EventExecutor;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.Collections;
-import javassist.ClassPool;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.AbstractNetconfTopology;
-import org.opendaylight.netconf.topology.NetconfTopology;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.example.LoggingSalNodeWriter;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDevice;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator.NetconfClientSessionListenerRegistration;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.NodeRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.TopologyRoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfTopology extends AbstractNetconfTopology implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfTopology.class);
-
- private final BindingNormalizedNodeCodecRegistry codecRegistry;
-
- private final ActorSystem actorSystem;
- private final EntityOwnershipService entityOwnershipService;
- private TopologyManager topologyManager;
-
- public ClusteredNetconfTopology(final String topologyId, final NetconfClientDispatcher clientDispatcher,
- final BindingAwareBroker bindingAwareBroker, final Broker domBroker,
- final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
- final ThreadPool processingExecutor, final SchemaRepositoryProvider schemaRepositoryProvider,
- final ActorSystem actorSystem, final EntityOwnershipService entityOwnershipService) {
- super(topologyId, clientDispatcher,
- bindingAwareBroker, domBroker, eventExecutor,
- keepaliveExecutor, processingExecutor, schemaRepositoryProvider);
-
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
- final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
- Preconditions.checkState(schemaContextOptional.isPresent());
- final SchemaContext topologySchemaCtx = schemaContextOptional.get();
-
- final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
- codecRegistry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
- codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, topologySchemaCtx));
-
- this.actorSystem = actorSystem;
- this.entityOwnershipService = entityOwnershipService;
- registerToSal(this, this);
- LOG.warn("Clustered netconf topo started");
- }
-
-
-
- @Override
- public void onSessionInitiated(final ProviderContext session) {
- dataBroker = session.getSALService(DataBroker.class);
- final NodeWriter writer = new TopologyNodeWriter(topologyId, dataBroker);
- TypedActorExtension typedActorExtension = TypedActor.get(this.actorSystem);
- LOG.warn("Registering actor on path {}", actorSystem.name() + "/user/" + topologyId);
- topologyManager = typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
- @Override
- public BaseTopologyManager create() throws Exception {
- return new BaseTopologyManager(actorSystem,
- codecRegistry,
- dataBroker,
- topologyId,
- new TopologyCallbackFactory(ClusteredNetconfTopology.this, entityOwnershipService, writer),
- new NetconfNodeOperationalDataAggregator(),
- new LoggingSalNodeWriter(writer),
- new TopologyRoleChangeStrategy(dataBroker, entityOwnershipService, "topology-netconf", "topology-manager"));
- }
- }), topologyId);
- }
-
- @Override
- public void close() throws Exception {
- // close all existing connectors, delete whole topology in datastore?
- for (NetconfConnectorDTO connectorDTO : activeConnectors.values()) {
- connectorDTO.getCommunicator().close();
- }
- activeConnectors.clear();
- }
-
- @Override
- protected NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
- final NetconfNode node) {
- //setup default values since default value is not supported in mdsal
- final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null ? DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
- final Long keepaliveDelay = node.getKeepaliveDelay() == null ? DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay();
- final Boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null ? DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema();
-
- IpAddress ipAddress = node.getHost().getIpAddress();
- InetSocketAddress address = new InetSocketAddress(ipAddress.getIpv4Address() != null ?
- ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue(),
- node.getPort().getValue());
- RemoteDeviceId remoteDeviceId = new RemoteDeviceId(nodeId.getValue(), address);
-
- RemoteDeviceHandler<NetconfSessionPreferences> salFacade =
- createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker);
-
- if (keepaliveDelay > 0) {
- LOG.warn("Adding keepalive facade, for device {}", nodeId);
- salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay, defaultRequestTimeoutMillis);
- }
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = setupSchemaCacheDTO(nodeId, node);
-
- final NetconfDevice device = new ClusteredNetconfDevice(schemaResourcesDTO, remoteDeviceId, salFacade,
- processingExecutor.getExecutor(), actorSystem, topologyId, nodeId.getValue(), TypedActor.context(),
- reconnectOnChangedSchema);
-
- final int rpcMessageLimit =
- node.getConcurrentRpcLimit() == null ? DEFAULT_CONCURRENT_RPC_LIMIT : node.getConcurrentRpcLimit();
-
- if (rpcMessageLimit < 1) {
- LOG.info("Concurrent rpc limit is smaller than 1, no limit will be enforced for device {}", remoteDeviceId);
- }
-
- return new NetconfConnectorDTO(new ClusteredNetconfDeviceCommunicator(remoteDeviceId, device, entityOwnershipService, rpcMessageLimit), salFacade);
- }
-
- @Override
- protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker) {
- return new TopologyMountPointFacade(topologyId, id, domBroker, bindingBroker);
- }
-
- @Override
- public void registerMountPoint(final ActorContext context, final NodeId nodeId) {
- ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).registerMountPoint(actorSystem, context);
- }
-
- @Override
- public void registerMountPoint(final ActorContext context, final NodeId nodeId, final ActorRef masterRef) {
- ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).registerMountPoint(actorSystem, context, masterRef);
- }
-
- @Override
- public void unregisterMountPoint(final NodeId nodeId) {
- Preconditions.checkState(activeConnectors.containsKey(nodeId), "Cannot unregister nonexistent mountpoint");
- ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).unregisterMountPoint();
- }
-
- @Override
- public ConnectionStatusListenerRegistration registerConnectionStatusListener(final NodeId node, final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- Preconditions.checkState(activeConnectors.containsKey(node), "Need to connect a node before a connection listener can be registered");
- return ((TopologyMountPointFacade) activeConnectors.get(node).getFacade()).registerConnectionStatusListener(listener);
- }
-
- public Collection<ProviderFunctionality> getProviderFunctionality() {
- return Collections.emptySet();
- }
-
- public NetconfClientSessionListenerRegistration registerNetconfClientSessionListener(final NodeId node, final NetconfClientSessionListener listener) {
- Preconditions.checkState(activeConnectors.containsKey(node), "Need to connect a node before a session listener can be registered");
- return ((ClusteredNetconfDeviceCommunicator) activeConnectors.get(node).getCommunicator()).registerNetconfClientSessionListener(listener);
- }
-
- static class TopologyCallbackFactory implements TopologyManagerCallbackFactory {
-
- private final NetconfTopology netconfTopology;
- private final EntityOwnershipService entityOwnershipService;
- private final NodeWriter writer;
-
- TopologyCallbackFactory(final NetconfTopology netconfTopology, final EntityOwnershipService entityOwnershipService, final NodeWriter writer) {
- this.netconfTopology = netconfTopology;
- this.entityOwnershipService = entityOwnershipService;
- this.writer = writer;
- }
-
- @Override
- public TopologyManagerCallback create(final ActorSystem actorSystem, final String topologyId) {
- return new NetconfTopologyManagerCallback(actorSystem, topologyId, new NodeCallbackFactory(netconfTopology, entityOwnershipService), new LoggingSalNodeWriter(writer));
- }
- }
-
- private static class NodeCallbackFactory implements NodeManagerCallbackFactory {
-
- private final NetconfTopology netconfTopology;
- private final EntityOwnershipService entityOwnershipService;
-
- NodeCallbackFactory(final NetconfTopology netconfTopology, final EntityOwnershipService entityOwnershipService) {
- this.netconfTopology = netconfTopology;
- this.entityOwnershipService = entityOwnershipService;
- }
-
- @Override
- public NodeManagerCallback create(final String nodeId, final String topologyId, final ActorSystem actorSystem) {
- return new NetconfNodeManagerCallback(nodeId, topologyId, actorSystem, netconfTopology, new NodeRoleChangeStrategy(entityOwnershipService, "netconf-node", nodeId));
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NetconfTopology;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator.NetconfClientSessionListenerRegistration;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.BaseNodeManager;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPoint;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPointDown;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability.FailureReason;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapabilityBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfClientSessionListener{
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeManagerCallback.class);
-
- public static final Function<Entry<QName, FailureReason>, UnavailableCapability> UNAVAILABLE_CAPABILITY_TRANSFORMER = new Function<Entry<QName, FailureReason>, UnavailableCapability>() {
- @Override
- public UnavailableCapability apply(final Entry<QName, FailureReason> input) {
- return new UnavailableCapabilityBuilder()
- .setCapability(input.getKey().toString())
- .setFailureReason(input.getValue()).build();
- }
- };
-
- private static final String UNKNOWN_REASON = "Unknown reason";
-
- private boolean isMaster = false;
- private ClusteredNetconfTopology topologyDispatcher;
- private final ActorSystem actorSystem;
- private final Cluster clusterExtension;
-
- private final RoleChangeStrategy roleChangeStrategy;
-
- private String nodeId;
- private String topologyId;
- private TopologyManager topologyManager;
- private NodeManager nodeManager;
- // cached context so that we can use it in callbacks from topology
- private ActorContext cachedContext;
-
- private Node currentConfig;
- private Node currentOperationalNode;
-
- private ConnectionStatusListenerRegistration connectionStatusregistration = null;
- private NetconfClientSessionListenerRegistration sessionListener = null;
-
- private ActorRef masterDataBrokerRef = null;
- private boolean connected = false;
-
- public NetconfNodeManagerCallback(final String nodeId,
- final String topologyId,
- final ActorSystem actorSystem,
- final NetconfTopology topologyDispatcher,
- final RoleChangeStrategy roleChangeStrategy) {
- this.nodeId = nodeId;
- this.topologyId = topologyId;
- this.actorSystem = actorSystem;
- this.clusterExtension = Cluster.get(actorSystem);
- this.topologyDispatcher = (ClusteredNetconfTopology) topologyDispatcher;
- this.roleChangeStrategy = roleChangeStrategy;
-
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(topologyId);
- final Future<ActorRef> topologyRefFuture = actorSystem.actorSelection(pathCreator.build()).resolveOne(FiniteDuration.create(10L, TimeUnit.SECONDS));
- topologyRefFuture.onComplete(new OnComplete<ActorRef>() {
- @Override
- public void onComplete(Throwable throwable, ActorRef actorRef) throws Throwable {
- if (throwable != null) {
- LOG.warn("Unable to resolve actor for path: {} ", "/user/" + topologyId, throwable);
-
- }
-
- LOG.debug("Actor ref for path {} resolved", "/user/" + topologyId);
- topologyManager = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
- }
- }, actorSystem.dispatcher());
-
- final Future<ActorRef> nodeRefFuture = actorSystem.actorSelection(pathCreator.withSuffix(nodeId).build()).resolveOne(FiniteDuration.create(10L, TimeUnit.SECONDS));
- nodeRefFuture.onComplete(new OnComplete<ActorRef>() {
- @Override
- public void onComplete(Throwable throwable, ActorRef actorRef) throws Throwable {
- if (throwable != null) {
- LOG.warn("Unable to resolve actor for path: {} ", "/user/" + topologyId + "/" + nodeId, throwable);
- }
- LOG.debug("Actor ref for path {} resolved", "/user/" + topologyId);
- nodeManager = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(NodeManager.class, BaseNodeManager.class), actorRef);
- }
- }, actorSystem.dispatcher());
- }
-
-
- @Nonnull
- @Override public Node getInitialState(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
- final Node initialNode = new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setConnectionStatus(ConnectionStatus.Connecting)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Lists.newArrayList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Unavailable)
- .build()))
- .build())
- .build())
- .build();
-
- if (currentOperationalNode == null) {
- currentOperationalNode = initialNode;
- }
-
- return initialNode;
- }
-
- @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId,
- @Nullable final Node configNode) {
- final NetconfNode netconfNode = configNode == null ? currentOperationalNode.getAugmentation(NetconfNode.class) : configNode.getAugmentation(NetconfNode.class);
-
- final Node failedNode = new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setConnectionStatus(ConnectionStatus.UnableToConnect)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Failed)
- .build()))
- .build())
- .build())
- .build();
-
- if (currentOperationalNode == null) {
- currentOperationalNode = failedNode;
- }
-
- return failedNode;
- }
-
- @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- cachedContext = TypedActor.context();
- this.nodeId = nodeId.getValue();
- this.currentConfig = configNode;
- // set initial state before anything happens
- this.currentOperationalNode = getInitialState(nodeId, configNode);
-
- // connect magic, send config into the netconf pipeline through topo dispatcher
- final ListenableFuture<NetconfDeviceCapabilities> connectionFuture = topologyDispatcher.connectNode(nodeId, configNode);
-
- Futures.addCallback(connectionFuture, new FutureCallback<NetconfDeviceCapabilities>() {
- @Override
- public void onSuccess(@Nullable NetconfDeviceCapabilities result) {
- connectionStatusregistration = topologyDispatcher.registerConnectionStatusListener(nodeId, nodeManager);
- sessionListener = topologyDispatcher.registerNetconfClientSessionListener(nodeId, NetconfNodeManagerCallback.this);
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("Connection to device failed", t);
- }
- });
-
- final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
- // transform future result into state that gets written into datastore
- return Futures.transform(connectionFuture, new Function<NetconfDeviceCapabilities, Node>() {
- @Nullable
- @Override
- public Node apply(NetconfDeviceCapabilities input) {
- // build state data
- currentOperationalNode = new NodeBuilder().setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Connected)
- .build()))
- .build())
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build()).build();
- return currentOperationalNode;
- }
- });
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId,
- @Nonnull final Node configNode) {
- // first disconnect this node
- topologyDispatcher.unregisterMountPoint(nodeId);
-
- if (connectionStatusregistration != null) {
- connectionStatusregistration.close();
- }
- topologyDispatcher.disconnectNode(nodeId);
-
- // now reinit this connection with new settings
- final ListenableFuture<NetconfDeviceCapabilities> connectionFuture = topologyDispatcher.connectNode(nodeId, configNode);
-
- Futures.addCallback(connectionFuture, new FutureCallback<NetconfDeviceCapabilities>() {
- @Override
- public void onSuccess(@Nullable NetconfDeviceCapabilities result) {
- connectionStatusregistration = topologyDispatcher.registerConnectionStatusListener(nodeId, NetconfNodeManagerCallback.this);
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("Connection to device failed", t);
- }
- });
-
- final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
- return Futures.transform(connectionFuture, new Function<NetconfDeviceCapabilities, Node>() {
- @Nullable
- @Override
- public Node apply(NetconfDeviceCapabilities input) {
- // build state data
- return new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Connected)
- .build()))
- .build())
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build())
- .build();
- }
- });
- }
-
- @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
- // cleanup and disconnect
- topologyDispatcher.unregisterMountPoint(nodeId);
-
- if(connectionStatusregistration != null) {
- connectionStatusregistration.close();
- }
- roleChangeStrategy.unregisterRoleCandidate();
- return topologyDispatcher.disconnectNode(nodeId);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- LOG.debug("Getting current status for node: {} status: {}", nodeId, currentOperationalNode);
- return Futures.immediateFuture(currentOperationalNode);
- }
-
- @Override
- public void onRoleChanged(final RoleChangeDTO roleChangeDTO) {
- topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
-
- isMaster = roleChangeDTO.isOwner();
- }
-
- @Override
- public void onDeviceConnected(final SchemaContext remoteSchemaContext, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
- // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
- connected = true;
- if (isMaster) {
- LOG.debug("Master is done with schema resolution, registering mount point");
- topologyDispatcher.registerMountPoint(TypedActor.context(), new NodeId(nodeId));
- } else if (masterDataBrokerRef != null) {
- LOG.warn("Device connected, master already present in topology, registering mount point");
- topologyDispatcher.registerMountPoint(cachedContext, new NodeId(nodeId), masterDataBrokerRef);
- }
-
- List<AvailableCapability> capabilityList = new ArrayList<>();
- capabilityList.addAll(netconfSessionPreferences.getNetconfDeviceCapabilities().getNonModuleBasedCapabilities());
- capabilityList.addAll(netconfSessionPreferences.getNetconfDeviceCapabilities().getResolvedCapabilities());
- final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
- avCapabalitiesBuilder.setAvailableCapability(capabilityList);
-
- final UnavailableCapabilities unavailableCapabilities =
- new UnavailableCapabilitiesBuilder().setUnavailableCapability(FluentIterable.from(netconfSessionPreferences.getNetconfDeviceCapabilities().getUnresolvedCapabilites().entrySet())
- .transform(UNAVAILABLE_CAPABILITY_TRANSFORMER).toList()).build();
-
- final NetconfNode netconfNode = currentConfig.getAugmentation(NetconfNode.class);
- currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Connected)
- .build()))
- .build())
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setAvailableCapabilities(avCapabalitiesBuilder.build())
- .setUnavailableCapabilities(unavailableCapabilities)
- .build())
- .build();
- topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
- }
-
- @Override
- public void onDeviceDisconnected() {
- // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
- LOG.debug("onDeviceDisconnected received, unregistered role candidate");
- connected = false;
- if (isMaster) {
- // set master to false since we are unregistering, the ownershipChanged callback can sometimes lag behind causing multiple nodes behaving as masters
- isMaster = false;
- // onRoleChanged() callback can sometimes lag behind, so unregister the mount right when it disconnects
- topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
- }
-
- final NetconfNode netconfNode = currentConfig.getAugmentation(NetconfNode.class);
- currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connecting)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Unavailable)
- .build()))
- .build())
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .build()).build();
- topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
- // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
- // no need to remove mountpoint, we should receive onRoleChanged callback after unregistering from election that unregisters the mountpoint
- LOG.warn("Netconf node {} failed with {}", nodeId, throwable);
- connected = false;
- String reason = (throwable != null && throwable.getMessage() != null) ? throwable.getMessage() : UNKNOWN_REASON;
-
- currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.UnableToConnect)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode(clusterExtension.selfAddress().toString())
- .setStatus(Status.Failed)
- .build()))
- .build())
- .setConnectedMessage(reason)
- .build()).build();
- topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
- //NOOP
- }
-
- @Override
- public void close() {
- //NOOP
- }
-
- @Override
- public void onReceive(Object message, ActorRef actorRef) {
- LOG.debug("Netconf node callback received message {}", message);
- if (message instanceof AnnounceMasterMountPoint) {
- masterDataBrokerRef = actorRef;
- // candidate gets registered when mount point is already prepared so we can go ahead a register it
- if (connected) {
- topologyDispatcher.registerMountPoint(TypedActor.context(), new NodeId(nodeId), masterDataBrokerRef);
- } else {
- LOG.debug("Announce master mount point msg received but mount point is not ready yet");
- }
- } else if (message instanceof AnnounceMasterMountPointDown) {
- LOG.debug("Master mountpoint went down");
- masterDataBrokerRef = null;
- topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
- }
- }
-
- @Override
- public void onSessionUp(NetconfClientSession netconfClientSession) {
- //NetconfClientSession is up, we can register role candidate
- LOG.debug("Netconf client session is up, registering role candidate");
- roleChangeStrategy.registerRoleCandidate(nodeManager);
- }
-
- @Override
- public void onSessionDown(NetconfClientSession netconfClientSession, Exception e) {
- LOG.debug("Netconf client session is down, unregistering role candidate");
- roleChangeStrategy.unregisterRoleCandidate();
- }
-
- @Override
- public void onSessionTerminated(NetconfClientSession netconfClientSession, NetconfTerminationReason netconfTerminationReason) {
- LOG.debug("Netconf client session is down, unregistering role candidate");
- roleChangeStrategy.unregisterRoleCandidate();
- }
-
- @Override
- public void onMessage(NetconfClientSession netconfClientSession, NetconfMessage netconfMessage) {
- //NOOP
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfNodeOperationalDataAggregator implements StateAggregator{
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeOperationalDataAggregator.class);
-
- @Override
- public ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures) {
- final SettableFuture<Node> future = SettableFuture.create();
- final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
- @Override
- public void onSuccess(final List<Node> result) {
- Node base = null;
- NetconfNode baseAugmentation = null;
- AvailableCapabilities masterCaps = null;
- UnavailableCapabilities unavailableMasterCaps = null;
- final ArrayList<NodeStatus> statusList = new ArrayList<>();
- for (final Node node : result) {
- final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
- if (base == null && netconfNode.getConnectionStatus().equals(ConnectionStatus.Connected)) {
- base = node;
- baseAugmentation = netconfNode;
- }
- // we need to pull out caps from master, since slave does not go through resolution
- if (masterCaps == null) {
- masterCaps = netconfNode.getAvailableCapabilities();
- unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
- }
- if (netconfNode.getAvailableCapabilities().getAvailableCapability().size() > masterCaps.getAvailableCapability().size()) {
- masterCaps = netconfNode.getAvailableCapabilities();
- unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
- }
- LOG.debug(netconfNode.toString());
- statusList.addAll(netconfNode.getClusteredConnectionStatus().getNodeStatus());
- }
-
- if (base == null) {
- base = result.get(0);
- baseAugmentation = result.get(0).getAugmentation(NetconfNode.class);
- LOG.debug("All results {}", result.toString());
- }
-
- final Node aggregatedNode =
- new NodeBuilder(base)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder(baseAugmentation)
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(statusList)
- .build())
- .setAvailableCapabilities(masterCaps)
- .setUnavailableCapabilities(unavailableMasterCaps)
- .build())
- .build();
-
- future.set(aggregatedNode);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("One of the combined create attempts failed {}", t);
- future.setException(t);
- }
- });
- return future;
- }
-
- @Override
- public ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures) {
- final SettableFuture<Node> future = SettableFuture.create();
- final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
- @Override
- public void onSuccess(final List<Node> result) {
- Node base = null;
- NetconfNode baseAugmentation = null;
- AvailableCapabilities masterCaps = null;
- UnavailableCapabilities unavailableMasterCaps = null;
- final ArrayList<NodeStatus> statusList = new ArrayList<>();
- for (final Node node : result) {
- final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
- if (base == null && netconfNode.getConnectionStatus().equals(ConnectionStatus.Connected)) {
- base = node;
- baseAugmentation = netconfNode;
- }
- // we need to pull out caps from master, since slave does not go through resolution
- if (masterCaps == null) {
- masterCaps = netconfNode.getAvailableCapabilities();
- unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
- }
- if (netconfNode.getAvailableCapabilities().getAvailableCapability().size() > masterCaps.getAvailableCapability().size()) {
- masterCaps = netconfNode.getAvailableCapabilities();
- unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
- }
- LOG.debug(netconfNode.toString());
- statusList.addAll(netconfNode.getClusteredConnectionStatus().getNodeStatus());
- }
-
- if (base == null) {
- base = result.get(0);
- baseAugmentation = result.get(0).getAugmentation(NetconfNode.class);
- LOG.debug("All results {}", result.toString());
- }
-
- final Node aggregatedNode =
- new NodeBuilder(base)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder(baseAugmentation)
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(statusList)
- .build())
- .setAvailableCapabilities(masterCaps)
- .setUnavailableCapabilities(unavailableMasterCaps)
- .build())
- .build();
- future.set(aggregatedNode);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("One of the combined update attempts failed {}", t);
- future.setException(t);
- }
- });
- return future;
- }
-
- @Override
- public ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures) {
- final SettableFuture<Void> future = SettableFuture.create();
- final ListenableFuture<List<Void>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Void>>() {
- @Override
- public void onSuccess(final List<Void> result) {
- future.set(null);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("One of the combined delete attempts failed {}", t);
- future.setException(t);
- }
- });
- return future;
- }
-}
package org.opendaylight.netconf.topology.impl;
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import io.netty.util.concurrent.EventExecutor;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.netconf.topology.AbstractNetconfTopology;
import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
return new NetconfDeviceSalFacade(id, domBroker, bindingAwareBroker);
}
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId) {
- throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
- }
-
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
- throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
- }
-
- @Override
- public void unregisterMountPoint(NodeId nodeId) {
- throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
- }
-
- @Override
- public ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- throw new UnsupportedOperationException("Registering a listener on a regular netconf device is not supported(supported only in clustered netconf topology)");
- }
-
@Override
public void onSessionInitiated(ProviderContext session) {
dataBroker = session.getSALService(DataBroker.class);
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.util.BaseNodeManager.BaseNodeManagerBuilder;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.SalNodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfTopologyManagerCallback implements TopologyManagerCallback {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyManagerCallback.class);
-
- private final ActorSystem actorSystem;
- private boolean isMaster;
-
- private final String topologyId;
- private final NodeWriter naSalNodeWriter;
- private final Map<NodeId, NodeManager> nodes = new HashMap<>();
- private final NodeManagerCallbackFactory nodeHandlerFactory;
-
- public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
- final DataBroker dataBroker,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory) {
- this(actorSystem, topologyId, nodeHandlerFactory, new SalNodeWriter(dataBroker, topologyId));
- }
-
- public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory,
- final NodeWriter naSalNodeWriter) {
- this(actorSystem, topologyId, nodeHandlerFactory, naSalNodeWriter, false);
-
- }
-
- public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
- final String topologyId,
- final NodeManagerCallbackFactory nodeHandlerFactory,
- final NodeWriter naSalNodeWriter,
- boolean isMaster) {
- this.actorSystem = actorSystem;
- this.topologyId = topologyId;
- this.nodeHandlerFactory = nodeHandlerFactory;
- this.naSalNodeWriter = naSalNodeWriter;
-
- this.isMaster = isMaster;
- }
-
- @Override
- public ListenableFuture<Node> onNodeCreated(final NodeId nodeId, final Node node) {
-
- // if this node was already configured, and whole config was pushed again, reinit with update
- if (nodes.containsKey(nodeId)) {
- return onNodeUpdated(nodeId, node);
- }
-
- // Init node admin
- final NodeManager naBaseNodeManager =
- createNodeManager(nodeId);
- nodes.put(nodeId, naBaseNodeManager);
-
- // only master should put initial state into datastore
- if (isMaster) {
- naSalNodeWriter.init(nodeId, naBaseNodeManager.getInitialState(nodeId, node));
- }
-
- // trigger connect on this node
- return naBaseNodeManager.onNodeCreated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
- // only master should put initial state into datastore
- if (isMaster) {
- naSalNodeWriter.init(nodeId, nodes.get(nodeId).getInitialState(nodeId, node));
- }
-
- // Trigger onNodeUpdated only on this node
- return nodes.get(nodeId).onNodeUpdated(nodeId, node);
- }
-
- @Override
- public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
- // Trigger delete only on this node
- final ListenableFuture<Void> future = nodes.get(nodeId).onNodeDeleted(nodeId);
- Futures.addCallback(future, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- // remove proxy from node list and stop the actor
- LOG.debug("Stopping node actor for node : {}", nodeId.getValue());
- final NodeManager remove = nodes.remove(nodeId);
- TypedActor.get(actorSystem).stop(remove);
- }
-
- @Override
- public void onFailure(Throwable t) {
- // NOOP will be handled on higher level
- }
- });
- return future;
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- if (!nodes.containsKey(nodeId)) {
- nodes.put(nodeId, createNodeManager(nodeId));
- }
- return nodes.get(nodeId).getCurrentStatusForNode(nodeId);
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
- isMaster = roleChangeDTO.isOwner();
- // our post-election logic
- }
-
- private NodeManager createNodeManager(NodeId nodeId) {
- return new BaseNodeManagerBuilder().setNodeId(nodeId.getValue())
- .setActorContext(TypedActor.context())
- .setDelegateFactory(nodeHandlerFactory)
- .setRoleChangeStrategy(new NoopRoleChangeStrategy())
- .setTopologyId(topologyId)
- .build();
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
-
- }
-
- @Nonnull
- @Override
- public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- return nodes.get(nodeId).getInitialState(nodeId, configNode);
- }
-
- @Nonnull
- @Override
- public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- return nodes.get(nodeId).getFailedState(nodeId, configNode);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyNodeWriter implements NodeWriter{
-
- private static final Logger LOG = LoggerFactory.getLogger(TopologyNodeWriter.class);
-
- private final String topologyId;
- private final BindingTransactionChain txChain;
-
- private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
- private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
-
- private final ReentrantLock lock = new ReentrantLock(true);
-
- public TopologyNodeWriter(final String topologyId, final DataBroker dataBroker) {
- this.topologyId = topologyId;
- this.txChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(new TransactionChainListener() {
- @Override
- public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
- LOG.error("{}: TransactionChain({}) {} FAILED!", chain,
- transaction.getIdentifier(), cause);
- throw new IllegalStateException("Clustered topology writer TransactionChain(" + chain + ") not committed correctly", cause);
- }
-
- @Override
- public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
- LOG.trace("Clustered topology writer TransactionChain({}) SUCCESSFUL", chain);
- }
- });
-
- this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
- this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
-
- // write an empty topology container at the start
- final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
- createNetworkTopologyIfNotPresent(wTx, LogicalDatastoreType.OPERATIONAL);
- createNetworkTopologyIfNotPresent(wTx, LogicalDatastoreType.CONFIGURATION);
- commitTransaction(wTx, "init topology container", new NodeId("topology-netconf"));
- }
-
- @Override
- public void init(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
- lock.lock();
- try {
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
- createNetworkTopologyIfNotPresent(writeTx, LogicalDatastoreType.OPERATIONAL);
- final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
-
- LOG.trace("{}: Init device state transaction {} putting if absent operational data started. Putting data on path {}",
- id.getValue(), writeTx.getIdentifier(), path);
- writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
- LOG.trace("{}: Init device state transaction {} putting operational data ended.",
- id.getValue(), writeTx.getIdentifier());
-
- commitTransaction(writeTx, "init", id);
- } finally {
- lock.unlock();
- }
- }
-
- @Override
- public void update(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
- lock.lock();
- try {
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
- final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
- LOG.trace("{}: Update device state transaction {} merging operational data started. Putting data on path {}",
- id, writeTx.getIdentifier(), operationalDataNode);
- writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
- LOG.trace("{}: Update device state transaction {} merging operational data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "update", id);
- } finally {
- lock.unlock();
- }
-
- }
-
- @Override
- public void delete(@Nonnull NodeId id) {
- lock.lock();
- try {
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
- final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
-
- LOG.trace(
- "{}: Close device state transaction {} removing all data started. Path: {}",
- id, writeTx.getIdentifier(), path);
- writeTx.delete(LogicalDatastoreType.OPERATIONAL, path);
- LOG.trace(
- "{}: Close device state transaction {} removing all data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "close", id);
- } finally {
- lock.unlock();
- }
- }
-
- private void commitTransaction(final WriteTransaction transaction, final String txType, final NodeId id) {
- LOG.trace("{}: Committing Transaction {}:{}", id.getValue(), txType,
- transaction.getIdentifier());
- final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
-
- Futures.addCallback(result, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- LOG.trace("{}: Transaction({}) {} SUCCESSFUL", id.getValue(), txType,
- transaction.getIdentifier());
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("{}: Transaction({}) {} FAILED!", id.getValue(), txType,
- transaction.getIdentifier(), t);
- throw new IllegalStateException(id.getValue() + " Transaction(" + txType + ") not committed correctly", t);
- }
- });
- }
-
- private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx, final LogicalDatastoreType datastoreType) {
-
- final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
- LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
- NetworkTopology.QNAME, writeTx.getIdentifier());
- writeTx.merge(datastoreType, networkTopologyPath, networkTopology);
-
- final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).build();
- LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
- Topology.QNAME, writeTx.getIdentifier());
- writeTx.merge(datastoreType, topologyListPath, topology);
- }
-}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.netconf.topology.util;
+package org.opendaylight.netconf.topology.impl;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
}
-
- public static InstanceIdentifier<Node> createTopologyNodeListPath(final NodeKey key, final String topologyId) {
- return createTopologyListPath(topologyId).child(Node.class, new NodeKey(new NodeId(key.getNodeId().getValue())));
- }
-
- public static InstanceIdentifier<Node> createTopologyNodePath(final String topologyId) {
- return createTopologyListPath(topologyId).child(Node.class);
- }
}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.TypedActor;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import scala.concurrent.Future;
-
-public interface ClusteredDeviceSourcesResolver extends TypedActor.Receiver, TypedActor.PreStart {
-
- Future<Set<SourceIdentifier>> getResolvedSources();
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import akka.dispatch.Futures;
-import akka.dispatch.OnComplete;
-import java.util.List;
-import java.util.Set;
-import org.opendaylight.controller.cluster.schema.provider.impl.RemoteSchemaProvider;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceClusteredDeviceSourcesResolverUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterOnSameNodeUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterSourceProviderUp;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.Promise;
-
-
-public class ClusteredDeviceSourcesResolverImpl implements ClusteredDeviceSourcesResolver {
-
- private static Logger LOG = LoggerFactory.getLogger(ClusteredDeviceSourcesResolver.class);
-
- private final String topologyId;
- private final String nodeId;
- private final ActorSystem actorSystem;
- private final SchemaSourceRegistry schemaRegistry;
- private final List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations;
-
- private final Promise<Set<SourceIdentifier>> resolvedSourcesPromise;
- private MasterSourceProvider remoteYangTextSourceProvider;
-
- public ClusteredDeviceSourcesResolverImpl(String topologyId, String nodeId, ActorSystem actorSystem,
- SchemaSourceRegistry schemaRegistry,
- List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations) {
- this.topologyId = topologyId;
- this.nodeId = nodeId;
- this.actorSystem = actorSystem;
- this.schemaRegistry = schemaRegistry;
- this.sourceRegistrations = sourceRegistrations;
- resolvedSourcesPromise = Futures.promise();
- }
-
- @Override
- public void preStart(){
- Cluster cluster = Cluster.get(actorSystem);
- for(Member node : cluster.state().getMembers()) {
- if(!node.address().equals(cluster.selfAddress())) {
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(node.address().toString(), topologyId);
- final String path = pathCreator.withSuffix(nodeId).withSuffix(NetconfTopologyPathCreator.MASTER_SOURCE_PROVIDER).build();
- actorSystem.actorSelection(path).tell(new AnnounceClusteredDeviceSourcesResolverUp(), TypedActor.context().self());
- }
- }
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
- if(o instanceof AnnounceMasterSourceProviderUp) {
- if(remoteYangTextSourceProvider == null) {
- remoteYangTextSourceProvider = TypedActor.get(actorSystem).typedActorOf(
- new TypedProps<>(MasterSourceProvider.class,
- MasterSourceProviderImpl.class), actorRef);
- registerProvidedSourcesToSchemaRegistry();
- }
- } else if(o instanceof AnnounceMasterOnSameNodeUp) {
- resolvedSourcesPromise.failure(new MasterSourceProviderOnSameNodeException());
- }
- }
-
- private void registerProvidedSourcesToSchemaRegistry() {
- Future<Set<SourceIdentifier>> sourcesFuture = remoteYangTextSourceProvider.getProvidedSources();
- resolvedSourcesPromise.completeWith(sourcesFuture);
- final RemoteSchemaProvider remoteProvider = new RemoteSchemaProvider(remoteYangTextSourceProvider, actorSystem.dispatcher());
-
- sourcesFuture.onComplete(new OnComplete<Set<SourceIdentifier>>() {
- @Override
- public void onComplete(Throwable throwable, Set<SourceIdentifier> sourceIdentifiers) throws Throwable {
- for (SourceIdentifier sourceId : sourceIdentifiers) {
- sourceRegistrations.add(schemaRegistry.registerSchemaSource(remoteProvider,
- PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
- }
- }
- }, actorSystem.dispatcher());
- }
-
- @Override
- public Future<Set<SourceIdentifier>> getResolvedSources() {
- return resolvedSourcesPromise.future();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.dispatch.OnComplete;
-import akka.japi.Creator;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceBuilder;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfDevice extends NetconfDevice implements EntityOwnershipListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfDevice.class);
-
- private NetconfDeviceCommunicator listener;
- private NetconfSessionPreferences sessionPreferences;
- private SchemaRepository schemaRepo;
- private final ActorSystem actorSystem;
- private final String topologyId;
- private final String nodeId;
- private final ActorContext cachedContext;
-
- private MasterSourceProvider masterSourceProvider = null;
- private ClusteredDeviceSourcesResolver resolver = null;
-
- public ClusteredNetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ExecutorService globalProcessingExecutor, final ActorSystem actorSystem, final String topologyId, final String nodeId,
- final ActorContext cachedContext, final boolean reconnectOnSchemaChanged) {
- super(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, reconnectOnSchemaChanged);
- this.schemaRepo = (SchemaRepository) schemaResourcesDTO.getSchemaRegistry();
- this.actorSystem = actorSystem;
- this.topologyId = topologyId;
- this.nodeId = nodeId;
- this.cachedContext = cachedContext;
- }
-
- @Override
- public void onRemoteSessionUp(NetconfSessionPreferences remoteSessionCapabilities, NetconfDeviceCommunicator listener) {
- LOG.warn("Node {} SessionUp, with capabilities {}", nodeId, remoteSessionCapabilities);
- this.listener = listener;
- this.sessionPreferences = remoteSessionCapabilities;
- slaveSetupSchema();
- }
-
-
- @Override
- protected void handleSalInitializationSuccess(SchemaContext result, NetconfSessionPreferences remoteSessionCapabilities, DOMRpcService deviceRpc) {
- super.handleSalInitializationSuccess(result, remoteSessionCapabilities, deviceRpc);
-
- final Set<SourceIdentifier> sourceIds = Sets.newHashSet();
- for(ModuleIdentifier id : result.getAllModuleIdentifiers()) {
- sourceIds.add(SourceIdentifier.create(id.getName(), (SimpleDateFormatUtil.DEFAULT_DATE_REV == id.getRevision() ? Optional.<String>absent() :
- Optional.of(SimpleDateFormatUtil.getRevisionFormat().format(id.getRevision())))));
- }
-
- //TODO extract string constant to util class
- LOG.debug("Creating master source provider");
- masterSourceProvider = TypedActor.get(cachedContext).typedActorOf(
- new TypedProps<>(MasterSourceProvider.class,
- new Creator<MasterSourceProviderImpl>() {
- @Override
- public MasterSourceProviderImpl create() throws Exception {
- return new MasterSourceProviderImpl(schemaRepo, sourceIds, actorSystem, topologyId, nodeId);
- }
- }), NetconfTopologyPathCreator.MASTER_SOURCE_PROVIDER);
- }
-
- @Override
- public void onRemoteSessionDown() {
- super.onRemoteSessionDown();
- listener = null;
- sessionPreferences = null;
- if (masterSourceProvider != null) {
- // if we have master the slave that started on this node should be already killed via PoisonPill, so stop master only now
- LOG.debug("Stopping master source provider for node {}", nodeId);
- TypedActor.get(actorSystem).stop(masterSourceProvider);
- masterSourceProvider = null;
- } else {
- LOG.debug("Stopping slave source resolver for node {}", nodeId);
- TypedActor.get(actorSystem).stop(resolver);
- resolver = null;
- }
- }
-
- private void slaveSetupSchema() {
- //TODO extract string constant to util class
- resolver = TypedActor.get(cachedContext).typedActorOf(
- new TypedProps<>(ClusteredDeviceSourcesResolver.class,
- new Creator<ClusteredDeviceSourcesResolverImpl>() {
- @Override
- public ClusteredDeviceSourcesResolverImpl create() throws Exception {
- return new ClusteredDeviceSourcesResolverImpl(topologyId, nodeId, actorSystem, schemaRegistry, sourceRegistrations);
- }
- }), NetconfTopologyPathCreator.CLUSTERED_DEVICE_SOURCES_RESOLVER);
-
- final FutureCallback<SchemaContext> schemaContextFuture = new FutureCallback<SchemaContext>() {
- @Override
- public void onSuccess(SchemaContext schemaContext) {
- LOG.debug("{}: Schema context built successfully.", id);
-
- final NetconfDeviceCapabilities deviceCap = sessionPreferences.getNetconfDeviceCapabilities();
- final Set<AvailableCapability> providedSourcesQnames = Sets.newHashSet();
- final Set<AvailableCapability> providedSourcesNonModuleCaps = Sets.newHashSet();
- for(ModuleIdentifier id : schemaContext.getAllModuleIdentifiers()) {
- providedSourcesQnames.add(new AvailableCapabilityBuilder()
- .setCapability(QName.create(id.getQNameModule(), id.getName()).toString()).build());
- }
- sessionPreferences.getNonModuleCaps().forEach(e -> providedSourcesNonModuleCaps.add(new AvailableCapabilityBuilder()
- .setCapability(e).build()));
- deviceCap.addNonModuleBasedCapabilities(providedSourcesNonModuleCaps);
- deviceCap.addCapabilities(providedSourcesQnames);
-
- ClusteredNetconfDevice.super.handleSalInitializationSuccess(
- schemaContext, sessionPreferences, getDeviceSpecificRpc(schemaContext, listener));
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- LOG.warn("{}: Unexpected error resolving device sources: {}", id, throwable);
- handleSalInitializationFailure(throwable, listener);
- }
- };
-
- resolver.getResolvedSources().onComplete(
- new OnComplete<Set<SourceIdentifier>>() {
- @Override
- public void onComplete(Throwable throwable, Set<SourceIdentifier> sourceIdentifiers) throws Throwable {
- if(throwable != null) {
- if(throwable instanceof MasterSourceProviderOnSameNodeException) {
- //do nothing
- } else {
- LOG.warn("{}: Unexpected error resolving device sources: {}", id, throwable);
- handleSalInitializationFailure(throwable, listener);
- }
- } else {
- LOG.trace("{}: Trying to build schema context from {}", id, sourceIdentifiers);
- Futures.addCallback(schemaContextFactory.createSchemaContext(sourceIdentifiers), schemaContextFuture);
- }
- }
- }, actorSystem.dispatcher());
- }
-
- private NetconfDeviceRpc getDeviceSpecificRpc(SchemaContext result, RemoteDeviceCommunicator<NetconfMessage> listener) {
- return new NetconfDeviceRpc(result, listener, new NetconfMessageTransformer(result, true));
- }
-
- @Override
- public void ownershipChanged(EntityOwnershipChange ownershipChange) {
- LOG.debug("Entity ownership change received {}", ownershipChange);
- if(ownershipChange.isOwner()) {
- super.onRemoteSessionUp(sessionPreferences, listener);
- } else if (ownershipChange.wasOwner()) {
- slaveSetupSchema();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import java.util.ArrayList;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-
-public class ClusteredNetconfDeviceCommunicator extends NetconfDeviceCommunicator {
-
- private final EntityOwnershipService ownershipService;
-
- private final ArrayList<NetconfClientSessionListener> netconfClientSessionListeners = new ArrayList<>();
- private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
- public ClusteredNetconfDeviceCommunicator(RemoteDeviceId id, NetconfDevice remoteDevice, EntityOwnershipService ownershipService, final int rpcMessageLimit) {
- super(id, remoteDevice, rpcMessageLimit);
- this.ownershipService = ownershipService;
- }
-
- @Override
- public void onMessage(NetconfClientSession session, NetconfMessage message) {
- super.onMessage(session, message);
- for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
- listener.onMessage(session, message);
- }
- }
-
- @Override
- public void onSessionDown(NetconfClientSession session, Exception e) {
- super.onSessionDown(session, e);
- ownershipListenerRegistration.close();
- for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
- listener.onSessionDown(session, e);
- }
- }
-
- @Override
- public void onSessionUp(NetconfClientSession session) {
- super.onSessionUp(session);
- ownershipListenerRegistration = ownershipService.registerListener("netconf-node/" + id.getName(), (ClusteredNetconfDevice) remoteDevice);
- for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
- listener.onSessionUp(session);
- }
- }
-
- @Override
- public void onSessionTerminated(NetconfClientSession session, NetconfTerminationReason reason) {
- super.onSessionTerminated(session, reason);
- ownershipListenerRegistration.close();
- for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
- listener.onSessionTerminated(session, reason);
- }
- }
-
- public NetconfClientSessionListenerRegistration registerNetconfClientSessionListener(NetconfClientSessionListener listener) {
- netconfClientSessionListeners.add(listener);
- return new NetconfClientSessionListenerRegistration(listener);
- }
-
- public class NetconfClientSessionListenerRegistration {
-
- private final NetconfClientSessionListener listener;
-
- public NetconfClientSessionListenerRegistration(NetconfClientSessionListener listener) {
- this.listener = listener;
- }
-
- public void close() {
- netconfClientSessionListeners.remove(listener);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider.MountInstance;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfDeviceMountInstanceProxy implements Provider, AutoCloseable{
-
- private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfDeviceMountInstanceProxy.class);
-
- private final RemoteDeviceId id;
- private MountInstance mountInstance;
-
- public ClusteredNetconfDeviceMountInstanceProxy(final RemoteDeviceId deviceId) {
- this.id = deviceId;
- }
-
- public MountInstance getMountInstance() {
- Preconditions.checkState(mountInstance != null,
- "%s: Mount instance was not initialized by sal. Cannot get mount instance", id);
- return mountInstance;
- }
-
- @Override
- public void close() throws Exception {
- mountInstance.close();
- }
-
- @Override
- public void onSessionInitiated(final Broker.ProviderSession session) {
- LOG.debug("{}: (BI)Session with sal established {}", id, session);
-
- final DOMMountPointService mountService = session.getService(DOMMountPointService.class);
- if (mountService != null) {
- mountInstance = new MountInstance(mountService, id);
- }
- }
-
- @Override
- public Collection<ProviderFunctionality> getProviderFunctionality() {
- return Collections.emptySet();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.TypedActor;
-import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
-
-public interface MasterSourceProvider
- extends TypedActor.PreStart, TypedActor.Receiver, RemoteYangTextSourceProvider {
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.PoisonPill;
-import akka.actor.TypedActor;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import java.util.Set;
-import org.opendaylight.controller.cluster.schema.provider.impl.RemoteYangTextSourceProviderImpl;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceClusteredDeviceSourcesResolverUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterOnSameNodeUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterSourceProviderUp;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MasterSourceProviderImpl extends RemoteYangTextSourceProviderImpl
- implements MasterSourceProvider {
-
- private static Logger LOG = LoggerFactory.getLogger(MasterSourceProviderImpl.class);
-
- private final ActorSystem actorSystem;
- private final String topologyId;
- private final String nodeId;
-
- public MasterSourceProviderImpl(SchemaRepository schemaRepo, Set<SourceIdentifier> providedSources, ActorSystem actorSystem, String topologyId, String nodeId) {
- super(schemaRepo, providedSources);
- this.actorSystem = actorSystem;
- this.topologyId = topologyId;
- this.nodeId = nodeId;
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
- if(o instanceof AnnounceClusteredDeviceSourcesResolverUp) {
- LOG.debug("Received source resolver up");
- actorRef.tell(new AnnounceMasterSourceProviderUp(), TypedActor.context().self());
- }
- }
-
- @Override
- public void preStart() {
- Cluster cluster = Cluster.get(actorSystem);
- cluster.join(cluster.selfAddress());
- LOG.debug("Notifying members master schema source provider is up.");
- for(Member node : cluster.state().getMembers()) {
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(node.address().toString(),topologyId);
- final String path = pathCreator.withSuffix(nodeId).withSuffix(NetconfTopologyPathCreator.CLUSTERED_DEVICE_SOURCES_RESOLVER).build();
- if(node.address().equals(cluster.selfAddress())) {
- actorSystem.actorSelection(path).tell(new AnnounceMasterOnSameNodeUp(), TypedActor.context().self());
- actorSystem.actorSelection(path).tell(PoisonPill.getInstance(), TypedActor.context().self());
- } else {
- //TODO extract string constant to util class
- actorSystem.actorSelection(path).tell(new AnnounceMasterSourceProviderUp(), TypedActor.context().self());
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-public class MasterSourceProviderOnSameNodeException extends Exception {
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceDataBroker;
-import org.opendaylight.netconf.sal.connect.netconf.sal.tx.ReadWriteTx;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyReadOnlyTransaction;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyWriteOnlyTransaction;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import scala.concurrent.Future;
-import scala.concurrent.impl.Promise.DefaultPromise;
-
-public class NetconfDeviceMasterDataBroker implements ProxyNetconfDeviceDataBroker {
-
- private final RemoteDeviceId id;
-
- private final NetconfDeviceDataBroker delegateBroker;
- private final ActorSystem actorSystem;
-
- private DOMDataReadOnlyTransaction readTx;
- private DOMDataWriteTransaction writeTx;
-
- public NetconfDeviceMasterDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id,
- final SchemaContext schemaContext, final DOMRpcService rpc,
- final NetconfSessionPreferences netconfSessionPreferences) {
- this.id = id;
- delegateBroker = new NetconfDeviceDataBroker(id, schemaContext, rpc, netconfSessionPreferences);
- this.actorSystem = actorSystem;
-
- // only ever need 1 readTx since it doesnt need to be closed
- readTx = delegateBroker.newReadOnlyTransaction();
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- return new ProxyReadOnlyTransaction(actorSystem, id, TypedActor.<NetconfDeviceMasterDataBroker>self());
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- return new ReadWriteTx(new ProxyReadOnlyTransaction(actorSystem, id, TypedActor.<NetconfDeviceMasterDataBroker>self()),
- newWriteOnlyTransaction());
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- writeTx = delegateBroker.newWriteOnlyTransaction();
- return new ProxyWriteOnlyTransaction(actorSystem, TypedActor.<NetconfDeviceMasterDataBroker>self());
- }
-
- @Override
- public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(LogicalDatastoreType store, YangInstanceIdentifier path, DOMDataChangeListener listener, DataChangeScope triggeringScope) {
- throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(TransactionChainListener listener) {
- throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
- }
-
- @Nonnull
- @Override
- public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
- return Collections.emptyMap();
- }
-
- @Override
- public Future<Optional<NormalizedNodeMessage>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture = readTx.read(store, path);
-
- final DefaultPromise<Optional<NormalizedNodeMessage>> promise = new DefaultPromise<>();
- Futures.addCallback(readFuture, new FutureCallback<Optional<NormalizedNode<?, ?>>>() {
- @Override
- public void onSuccess(Optional<NormalizedNode<?, ?>> result) {
- if (!result.isPresent()) {
- promise.success(Optional.<NormalizedNodeMessage>absent());
- } else {
- promise.success(Optional.of(new NormalizedNodeMessage(path, result.get())));
- }
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
- return promise.future();
- }
-
- @Override
- public Future<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final CheckedFuture<Boolean, ReadFailedException> existsFuture = readTx.exists(store, path);
-
- final DefaultPromise<Boolean> promise = new DefaultPromise<>();
- Futures.addCallback(existsFuture, new FutureCallback<Boolean>() {
- @Override
- public void onSuccess(Boolean result) {
- promise.success(result);
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- }
- });
- return promise.future();
- }
-
- @Override
- public void put(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
- if (writeTx == null) {
- writeTx = delegateBroker.newWriteOnlyTransaction();
- }
- writeTx.put(store, data.getIdentifier(), data.getNode());
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
- if (writeTx == null) {
- writeTx = delegateBroker.newWriteOnlyTransaction();
- }
- writeTx.merge(store, data.getIdentifier(), data.getNode());
- }
-
- @Override
- public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- if (writeTx == null) {
- writeTx = delegateBroker.newWriteOnlyTransaction();
- }
- writeTx.delete(store, path);
- }
-
- @Override
- public boolean cancel() {
- return writeTx.cancel();
- }
-
- @Override
- public Future<Void> submit() {
- final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTx.submit();
- final DefaultPromise<Void> promise = new DefaultPromise<>();
- Futures.addCallback(submitFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- promise.success(result);
- writeTx = null;
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- writeTx = null;
- }
- });
- return promise.future();
- }
-
- @Override
- @Deprecated
- public Future<RpcResult<TransactionStatus>> commit() {
- final ListenableFuture<RpcResult<TransactionStatus>> commitFuture = writeTx.commit();
- final DefaultPromise<RpcResult<TransactionStatus>> promise = new DefaultPromise<>();
- Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
- @Override
- public void onSuccess(RpcResult<TransactionStatus> result) {
- promise.success(result);
- writeTx = null;
- }
-
- @Override
- public void onFailure(Throwable t) {
- promise.failure(t);
- writeTx = null;
- }
- });
- return promise.future();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.ActorSystem;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.netconf.sal.connect.netconf.sal.tx.ReadWriteTx;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyReadOnlyTransaction;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyWriteOnlyTransaction;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class NetconfDeviceSlaveDataBroker implements DOMDataBroker{
-
- private final RemoteDeviceId id;
- private final ProxyNetconfDeviceDataBroker masterDataBroker;
- private final ActorSystem actorSystem;
-
- public NetconfDeviceSlaveDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id, final ProxyNetconfDeviceDataBroker masterDataBroker) {
- this.id = id;
- this.masterDataBroker = masterDataBroker;
- this.actorSystem = actorSystem;
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- return new ProxyReadOnlyTransaction(actorSystem, id, masterDataBroker);
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- return new ReadWriteTx(new ProxyReadOnlyTransaction(actorSystem, id, masterDataBroker), new ProxyWriteOnlyTransaction(actorSystem, masterDataBroker));
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- return new ProxyWriteOnlyTransaction(actorSystem, masterDataBroker);
- }
-
- @Override
- public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(LogicalDatastoreType store, YangInstanceIdentifier path, DOMDataChangeListener listener, DataChangeScope triggeringScope) {
- throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(TransactionChainListener listener) {
- throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
- }
-
- @Nonnull
- @Override
- public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
- return Collections.emptyMap();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import scala.concurrent.Future;
-
-public interface ProxyNetconfDeviceDataBroker extends DOMDataBroker{
- Future<Optional<NormalizedNodeMessage>> read(LogicalDatastoreType store, YangInstanceIdentifier path);
-
- Future<Boolean> exists(LogicalDatastoreType store, YangInstanceIdentifier path);
-
- void put(LogicalDatastoreType store, NormalizedNodeMessage data);
-
- void merge(LogicalDatastoreType store, NormalizedNodeMessage data);
-
- void delete(LogicalDatastoreType store, YangInstanceIdentifier path);
-
- boolean cancel();
-
- Future<Void> submit();
-
- @Deprecated
- Future<RpcResult<TransactionStatus>> commit();
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import akka.japi.Creator;
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceNotificationService;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPoint;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPointDown;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
-
- private static final Logger LOG = LoggerFactory.getLogger(TopologyMountPointFacade.class);
-
- private static final String MOUNT_POINT = "mountpoint";
-
- private final String topologyId;
- private final RemoteDeviceId id;
- private final Broker domBroker;
- private final BindingAwareBroker bindingBroker;
-
- private SchemaContext remoteSchemaContext = null;
- private NetconfSessionPreferences netconfSessionPreferences = null;
- private DOMRpcService deviceRpc = null;
- private final ClusteredNetconfDeviceMountInstanceProxy salProvider;
-
- private ActorSystem actorSystem;
- private DOMDataBroker deviceDataBroker = null;
-
- private final ArrayList<RemoteDeviceHandler<NetconfSessionPreferences>> connectionStatusListeners = new ArrayList<>();
-
- public TopologyMountPointFacade(final String topologyId,
- final RemoteDeviceId id,
- final Broker domBroker,
- final BindingAwareBroker bindingBroker) {
- this.topologyId = topologyId;
- this.id = id;
- this.domBroker = domBroker;
- this.bindingBroker = bindingBroker;
- this.salProvider = new ClusteredNetconfDeviceMountInstanceProxy(id);
- registerToSal(domBroker);
- }
-
- public void registerToSal(final Broker domRegistryDependency) {
- domRegistryDependency.registerProvider(salProvider);
- }
-
- @Override
- public void onDeviceConnected(final SchemaContext remoteSchemaContext,
- final NetconfSessionPreferences netconfSessionPreferences,
- final DOMRpcService deviceRpc) {
- // prepare our prerequisites for mountpoint
- LOG.debug("Mount point facade onConnected capabilities {}", netconfSessionPreferences);
- this.remoteSchemaContext = remoteSchemaContext;
- this.netconfSessionPreferences = netconfSessionPreferences;
- this.deviceRpc = deviceRpc;
- for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
- listener.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
- }
- }
-
- @Override
- public void onDeviceDisconnected() {
- // do not unregister mount point here, this gets handle by the underlying call from role change callback
- for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
- listener.onDeviceDisconnected();
- }
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
- // do not unregister mount point here, this gets handle by the underlying call from role change callback
- for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
- listener.onDeviceFailed(throwable);
- }
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
- salProvider.getMountInstance().publish(domNotification);
- }
-
- public void registerMountPoint(final ActorSystem actorSystem, final ActorContext context) {
- if (remoteSchemaContext == null || netconfSessionPreferences == null) {
- LOG.debug("Master mount point does not have schemas ready yet, delaying registration");
- return;
- }
-
- Preconditions.checkNotNull(id);
- Preconditions.checkNotNull(remoteSchemaContext, "Device has no remote schema context yet. Probably not fully connected.");
- Preconditions.checkNotNull(netconfSessionPreferences, "Device has no capabilities yet. Probably not fully connected.");
- this.actorSystem = actorSystem;
- final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
-
- LOG.warn("Creating master data broker for device {}", id);
- deviceDataBroker = TypedActor.get(context).typedActorOf(new TypedProps<>(ProxyNetconfDeviceDataBroker.class, new Creator<NetconfDeviceMasterDataBroker>() {
- @Override
- public NetconfDeviceMasterDataBroker create() throws Exception {
- return new NetconfDeviceMasterDataBroker(actorSystem, id, remoteSchemaContext, deviceRpc, netconfSessionPreferences);
- }
- }), MOUNT_POINT);
- LOG.debug("Master data broker registered on path {}", TypedActor.get(actorSystem).getActorRefFor(deviceDataBroker).path());
- salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, deviceDataBroker, deviceRpc, notificationService);
- final Cluster cluster = Cluster.get(actorSystem);
- final Iterable<Member> members = cluster.state().getMembers();
- final ActorRef deviceDataBrokerRef = TypedActor.get(actorSystem).getActorRefFor(deviceDataBroker);
- for (final Member member : members) {
- if (!member.address().equals(cluster.selfAddress())) {
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(),topologyId);
- final String path = pathCreator.withSuffix(id.getName()).build();
- actorSystem.actorSelection(path).tell(new AnnounceMasterMountPoint(), deviceDataBrokerRef);
- }
- }
- }
-
- public void registerMountPoint(final ActorSystem actorSystem, final ActorContext context, final ActorRef masterRef) {
- if (remoteSchemaContext == null || netconfSessionPreferences == null) {
- LOG.debug("Slave mount point does not have schemas ready yet, delaying registration");
- return;
- }
-
- Preconditions.checkNotNull(id);
- Preconditions.checkNotNull(remoteSchemaContext, "Device has no remote schema context yet. Probably not fully connected.");
- Preconditions.checkNotNull(netconfSessionPreferences, "Device has no capabilities yet. Probably not fully connected.");
- this.actorSystem = actorSystem;
- final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
-
- final ProxyNetconfDeviceDataBroker masterDataBroker = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(ProxyNetconfDeviceDataBroker.class, NetconfDeviceMasterDataBroker.class), masterRef);
- LOG.warn("Creating slave data broker for device {}", id);
- final DOMDataBroker deviceDataBroker = new NetconfDeviceSlaveDataBroker(actorSystem, id, masterDataBroker);
- salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, deviceDataBroker, deviceRpc, notificationService);
- }
-
- public void unregisterMountPoint() {
- salProvider.getMountInstance().onTopologyDeviceDisconnected();
- if (deviceDataBroker != null) {
- LOG.debug("Stopping master data broker for device {}", id.getName());
- for (final Member member : Cluster.get(actorSystem).state().getMembers()) {
- if (member.address().equals(Cluster.get(actorSystem).selfAddress())) {
- continue;
- }
- final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
- final String path = pathCreator.withSuffix(id.getName()).build();
- actorSystem.actorSelection(path).tell(new AnnounceMasterMountPointDown(), null);
- }
- TypedActor.get(actorSystem).stop(deviceDataBroker);
- deviceDataBroker = null;
- }
- }
-
- public ConnectionStatusListenerRegistration registerConnectionStatusListener(final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- connectionStatusListeners.add(listener);
- return new ConnectionStatusListenerRegistration(listener);
- }
-
- @Override
- public void close() {
- closeGracefully(salProvider);
- }
-
- private void closeGracefully(final AutoCloseable resource) {
- if (resource != null) {
- try {
- resource.close();
- } catch (final Exception e) {
- LOG.warn("{}: Ignoring exception while closing {}", id, resource, e);
- }
- }
- }
-
- public class ConnectionStatusListenerRegistration{
-
- private final RemoteDeviceHandler<NetconfSessionPreferences> listener;
-
- public ConnectionStatusListenerRegistration(final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- this.listener = listener;
- }
-
- public void close() {
- connectionStatusListeners.remove(listener);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceClusteredDeviceSourcesResolverUp implements Serializable {
- public static final long serialVersionUID = 1L;
-
- public AnnounceClusteredDeviceSourcesResolverUp() {}
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterOnSameNodeUp implements Serializable {
- public static long serialVersionUID = 1L;
-
- public AnnounceMasterOnSameNodeUp() {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterSourceProviderUp implements Serializable {
- public static final long serialVersionUID = 1L;
-
- public AnnounceMasterSourceProviderUp() {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.tx;
-
-public interface NetconfDeviceDataBrokerProxy {
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.tx;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.SettableFuture;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import scala.concurrent.Future;
-
-public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
-
- private final RemoteDeviceId id;
- private final ProxyNetconfDeviceDataBroker delegate;
- private final ActorSystem actorSystem;
-
- public ProxyReadOnlyTransaction(final ActorSystem actorSystem, final RemoteDeviceId id, final ProxyNetconfDeviceDataBroker delegate) {
- this.id = id;
- this.delegate = delegate;
- this.actorSystem = actorSystem;
- }
-
- @Override
- public void close() {
- //NOOP
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final Future<Optional<NormalizedNodeMessage>> future = delegate.read(store, path);
- final SettableFuture<Optional<NormalizedNode<?, ?>>> settableFuture = SettableFuture.create();
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
- @Nullable
- @Override
- public ReadFailedException apply(Exception cause) {
- return new ReadFailedException("Read from transaction failed", cause);
- }
- });
- future.onComplete(new OnComplete<Optional<NormalizedNodeMessage>>() {
- @Override
- public void onComplete(Throwable throwable, Optional<NormalizedNodeMessage> normalizedNodeMessage) throws Throwable {
- if (throwable == null) {
- if (normalizedNodeMessage.isPresent()) {
- settableFuture.set(normalizedNodeMessage.transform(new Function<NormalizedNodeMessage, NormalizedNode<?, ?>>() {
- @Nullable
- @Override
- public NormalizedNode<?, ?> apply(NormalizedNodeMessage input) {
- return input.getNode();
- }
- }));
- } else {
- settableFuture.set(Optional.absent());
- }
- } else {
- settableFuture.setException(throwable);
- }
- }
- }, actorSystem.dispatcher());
- return checkedFuture;
- }
-
- @Override
- public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final Future<Boolean> existsFuture = delegate.exists(store, path);
- final SettableFuture<Boolean> settableFuture = SettableFuture.create();
- final CheckedFuture<Boolean, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
- @Nullable
- @Override
- public ReadFailedException apply(Exception cause) {
- return new ReadFailedException("Read from transaction failed", cause);
- }
- });
- existsFuture.onComplete(new OnComplete<Boolean>() {
- @Override
- public void onComplete(Throwable throwable, Boolean result) throws Throwable {
- if (throwable == null) {
- settableFuture.set(result);
- } else {
- settableFuture.setException(throwable);
- }
- }
- }, actorSystem.dispatcher());
- return checkedFuture;
- }
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.tx;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import scala.concurrent.Future;
-
-public class ProxyWriteOnlyTransaction implements DOMDataWriteTransaction {
-
- private final ProxyNetconfDeviceDataBroker delegate;
- private final ActorSystem actorSystem;
-
- public ProxyWriteOnlyTransaction(ActorSystem actorSystem, final ProxyNetconfDeviceDataBroker delegate) {
- this.delegate = delegate;
- this.actorSystem = actorSystem;
- }
-
- @Override
- public void put (final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode < ?,?>data){
- delegate.put(store, new NormalizedNodeMessage(path, data));
- }
-
- @Override
- public void merge (final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode < ?,?>data){
- delegate.merge(store, new NormalizedNodeMessage(path, data));
- }
-
- @Override
- public boolean cancel () {
- return delegate.cancel();
- }
-
- @Override
- public void delete (final LogicalDatastoreType store, final YangInstanceIdentifier path){
- delegate.delete(store, path);
- }
-
- @Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- final Future<Void> submit = delegate.submit();
- final SettableFuture<Void> settableFuture = SettableFuture.create();
- final CheckedFuture<Void, TransactionCommitFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, TransactionCommitFailedException>() {
- @Nullable
- @Override
- public TransactionCommitFailedException apply(Exception input) {
- return new TransactionCommitFailedException("Transaction commit failed", input);
- }
- });
- submit.onComplete(new OnComplete<Void>() {
- @Override
- public void onComplete(Throwable throwable, Void aVoid) throws Throwable {
- if (throwable == null) {
- settableFuture.set(aVoid);
- } else {
- settableFuture.setException(throwable);
- }
- }
- }, actorSystem.dispatcher());
- return checkedFuture;
- }
-
- @Override
- public ListenableFuture<RpcResult<TransactionStatus>> commit () {
- final Future<RpcResult<TransactionStatus>> commit = delegate.commit();
- final SettableFuture<RpcResult<TransactionStatus>> settableFuture = SettableFuture.create();
- commit.onComplete(new OnComplete<RpcResult<TransactionStatus>>() {
- @Override
- public void onComplete(Throwable throwable, RpcResult<TransactionStatus> transactionStatusRpcResult) throws Throwable {
- if (throwable == null) {
- settableFuture.set(transactionStatusRpcResult);
- } else {
- settableFuture.setException(throwable);
- }
- }
- }, actorSystem.dispatcher());
- return settableFuture;
- }
-
- @Override
- public Object getIdentifier () {
- return this;
- }
-}
+++ /dev/null
-module clustered-netconf-topology {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology";
- prefix "nt";
-
- import config { prefix config; revision-date 2013-04-05; }
- import threadpool {prefix th;}
- import netty {prefix netty;}
- import opendaylight-md-sal-dom {prefix dom;}
- import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
- import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
- import shared-schema-repository { prefix sh; revision-date 2015-07-27; }
- import netconf-topology { prefix topo; revision-date 2015-07-27; }
- import opendaylight-entity-ownership-service { prefix eos; revision-date 2015-08-10; }
- import actor-system-provider-service { prefix asp; revision-date 2015-10-05; }
-
- description
- "Module definition for Netconf topolgy. Netconf topology provides a set of common configuration ";
-
- revision "2015-11-04" {
- description
- "Initial revision";
- }
-
- identity clustered-netconf-topology-impl {
- base config:module-type;
- config:java-name-prefix ClusteredNetconfTopology;
- config:provided-service topo:netconf-topology;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case clustered-netconf-topology-impl {
- when "/config:modules/config:module/config:type = 'clustered-netconf-topology-impl'";
-
- leaf topology-id {
- mandatory true;
- type string;
- }
-
- container dom-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dom:dom-broker-osgi-registry;
- }
- }
- }
-
- container binding-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity md-sal-binding:binding-broker-osgi-registry;
- }
- }
- }
-
- container event-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity netty:netty-event-executor;
- }
- }
- }
-
- container processing-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity th:threadpool;
- }
- }
-
- description "Makes up for flaws in netty threading design";
- }
-
- container client-dispatcher {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity cfg-net:netconf-client-dispatcher;
- }
- }
- }
-
- container keepalive-executor {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity th:scheduled-threadpool;
- }
- }
-
- description "Dedicated solely to keepalive execution";
- }
-
- container shared-schema-repository {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity sh:shared-schema-repository;
- }
- }
- }
-
- container entity-ownership-service {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity eos:entity-ownership-service;
- }
- }
- }
-
- container actor-system-provider-service {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity asp:actor-system-provider-service;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import io.netty.util.concurrent.EventExecutor;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.ImmediateEventExecutor;
-import io.netty.util.concurrent.SucceededFuture;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-
-public class AbstractNetconfTopologyTest {
-
- private static final NodeId NODE_ID = new NodeId("testing-node");
- private static final String TOPOLOGY_ID = "testing-topology";
-
- @Mock
- private Broker mockedDataBroker;
-
- @Mock
- private NetconfClientDispatcher mockedClientDispatcher;
-
- @Mock
- private BindingAwareBroker mockedBindingAwareBroker;
-
- @Mock
- private EventExecutor mockedEventExecutor;
-
- @Mock
- private ScheduledThreadPool mockedKeepaliveExecutor;
-
- @Mock
- private ThreadPool mockedProcessingExecutor;
-
- @Mock
- private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
-
-
- private TestingAbstractNetconfTopology topology;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- when(mockedSchemaRepositoryProvider.getSharedSchemaRepository()).thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
- when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
- Future<Void> future = new SucceededFuture<>(ImmediateEventExecutor.INSTANCE, null);
- when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class))).thenReturn(future);
-
- topology = new TestingAbstractNetconfTopology(TOPOLOGY_ID, mockedClientDispatcher, mockedBindingAwareBroker,
- mockedDataBroker, mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider);
- }
-
- @Test
- public void testCreateSalFacade() {
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setSchemaless(false)
- .build();
-
- AbstractNetconfTopology.NetconfConnectorDTO connectorDTO = topology.createDeviceCommunicator(NODE_ID, testingNode);
- assertSame(connectorDTO.getFacade(), topology.getFacade());
- }
-
- @Test
- public void testCreateKeepAliveSalFacade() {
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setKeepaliveDelay(1L)
- .setSchemaless(false)
- .build();
-
- AbstractNetconfTopology.NetconfConnectorDTO connectorDTO = topology.createDeviceCommunicator(NODE_ID, testingNode);
- assertTrue(connectorDTO.getFacade() instanceof KeepaliveSalFacade);
- }
-
- @Test
- public void testSetupSchemaResourceDTO() {
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setKeepaliveDelay(1000L).build();
-
- NetconfDevice.SchemaResourcesDTO resultDTO = topology.setupSchemaCacheDTO(NODE_ID, testingNode);
- SharedSchemaRepository repo = (SharedSchemaRepository) resultDTO.getSchemaRegistry();
- assertEquals(repo.getIdentifier(), "sal-netconf-connector");
-
- testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setKeepaliveDelay(1000L)
- .setSchemaCacheDirectory("test-directory")
- .build();
-
- resultDTO = topology.setupSchemaCacheDTO(NODE_ID, testingNode);
- repo = (SharedSchemaRepository) resultDTO.getSchemaRegistry();
- assertEquals(repo.getIdentifier(), "test-directory");
- }
-
- @Test
- public void testGetClientConfig() throws UnknownHostException {
- NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
- Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
- PortNumber portNumber = new PortNumber(9999);
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setConnectionTimeoutMillis(1000L)
- .setDefaultRequestTimeoutMillis(2000L)
- .setHost(host)
- .setPort(portNumber)
- .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
- .setTcpOnly(true)
- .build();
- NetconfReconnectingClientConfiguration defaultClientConfig = topology.getClientConfig(listener, testingNode);
-
- assertEquals(defaultClientConfig.getConnectionTimeoutMillis().longValue(), 1000L);
- assertEquals(defaultClientConfig.getAddress(), new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
- assertSame(defaultClientConfig.getSessionListener(), listener);
- assertEquals(defaultClientConfig.getAuthHandler().getUsername(), "testuser");
- assertEquals(defaultClientConfig.getProtocol(), NetconfClientConfiguration.NetconfClientProtocol.TCP);
- }
-
- @Test
- public void testGetClientConfigNotSupportedCredentialsFail() {
- NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
- Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
- PortNumber portNumber = new PortNumber(9999);
-
- Credentials notSupportedCredentials = new Credentials() {
- @Override
- public Class<? extends DataContainer> getImplementedInterface() {
- return Credentials.class;
- }
- };
-
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setConnectionTimeoutMillis(1000L)
- .setDefaultRequestTimeoutMillis(2000L)
- .setHost(host)
- .setPort(portNumber)
- .setCredentials(notSupportedCredentials)
- .setTcpOnly(true)
- .build();
- try {
- topology.getClientConfig(listener, testingNode);
- fail("Exception expected here.");
- } catch(Exception e) {
- assertTrue(e instanceof IllegalStateException);
- }
- }
-
- @Test
- public void testConnectNode() {
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setKeepaliveDelay(1000L)
- .setTcpOnly(true)
- .setSchemaless(false)
- .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
- .build();
- Node nd = mock(Node.class);
- when(nd.getAugmentation(NetconfNode.class)).thenReturn(testingNode);
- topology.connectNode(NODE_ID, nd);
- assertTrue(topology.activeConnectors.containsKey(NODE_ID));
- }
-
- @Test
- public void testDisconnectNode() {
- NetconfNode testingNode = new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(9999))
- .setReconnectOnChangedSchema(true)
- .setDefaultRequestTimeoutMillis(1000L)
- .setBetweenAttemptsTimeoutMillis(100)
- .setKeepaliveDelay(1000L)
- .setTcpOnly(true)
- .setSchemaless(false)
- .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
- .build();
- Node nd = mock(Node.class);
- when(nd.getAugmentation(NetconfNode.class)).thenReturn(testingNode);
- topology.connectNode(NODE_ID, nd);
- assertTrue(topology.activeConnectors.containsKey(NODE_ID));
- assertTrue(topology.disconnectNode(NODE_ID).isDone());
- assertTrue(!topology.activeConnectors.containsKey(NODE_ID));
- verify(topology.getFacade()).close();
- }
-
- @Test
- public void testDisconnectNotConnectedNode() throws ExecutionException, InterruptedException {
- ListenableFuture disconnectFuture = topology.disconnectNode(NODE_ID);
- assertTrue(disconnectFuture.isDone());
- try {
- disconnectFuture.get();
- fail("Exception expected!");
- } catch(Exception e) {
- assertTrue(e instanceof ExecutionException);
- assertTrue(e.getCause() instanceof IllegalStateException);
- }
- }
-
- public static class TestingAbstractNetconfTopology extends AbstractNetconfTopology {
-
- private RemoteDeviceHandler salFacade;
-
- protected TestingAbstractNetconfTopology(String topologyId, NetconfClientDispatcher clientDispatcher,
- BindingAwareBroker bindingAwareBroker, Broker domBroker,
- EventExecutor eventExecutor, ScheduledThreadPool keepaliveExecutor,
- ThreadPool processingExecutor,
- SchemaRepositoryProvider schemaRepositoryProvider) {
- super(topologyId, clientDispatcher, bindingAwareBroker, domBroker, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider);
- salFacade = mock(RemoteDeviceHandler.class);
- }
-
- public RemoteDeviceHandler<NetconfSessionPreferences> getFacade() {
- return salFacade;
- }
-
- @Override
- public void onSessionInitiated(BindingAwareBroker.ProviderContext session) {
-
- }
-
- @Override
- protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker) {
- return salFacade;
- }
-
- @Override
- public TopologyMountPointFacade.ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- return null;
- }
-
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId) {
-
- }
-
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
-
- }
-
- @Override
- public void unregisterMountPoint(NodeId nodeId) {
-
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import static com.jayway.awaitility.Awaitility.await;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import com.typesafe.config.ConfigFactory;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import javassist.ClassPool;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.example.ExampleNodeManagerCallback;
-import org.opendaylight.netconf.topology.example.ExampleTopologyManagerCallback;
-import org.opendaylight.netconf.topology.example.LoggingSalNodeWriter;
-import org.opendaylight.netconf.topology.impl.NetconfNodeOperationalDataAggregator;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.TopologyRoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ActorTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(ActorTest.class);
-
- private static final String TOPOLOGY_NETCONF = "TopologyNetconf";
-
- @Mock
- private EntityOwnershipService entityOwnershipService;
-
- @Mock
- private DataBroker dataBroker;
-
- @Mock
- private ReadOnlyTransaction mockedReadOnlyTx;
-
- private static final BindingNormalizedNodeCodecRegistry CODEC_REGISTRY;
-
- static {
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
- final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
- Preconditions.checkState(schemaContextOptional.isPresent());
- final SchemaContext topologySchemaCtx = schemaContextOptional.get();
-
- final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
- CODEC_REGISTRY = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
- CODEC_REGISTRY.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, topologySchemaCtx));
- }
-
- private static final String PATH_MASTER = "akka.tcp://NetconfNode@127.0.0.1:2552/user/TopologyNetconf";
- private static final String PATH_SLAVE1 = "akka.tcp://NetconfNode@127.0.0.1:2553/user/TopologyNetconf";
- private static final String PATH_SLAVE2 = "akka.tcp://NetconfNode@127.0.0.1:2554/user/TopologyNetconf";
-
- private static final List<String> PATHS_MASTER = Lists.newArrayList(PATH_SLAVE1, PATH_SLAVE2);
- private static final List<String> PATHS_SLAVE1 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE2);
- private static final List<String> PATHS_SLAVE2 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE1);
-
- private static final ActorSystem ACTOR_SYSTEM = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node1"));
- private static final ActorSystem ACTOR_SYSTEM_SLAVE1 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node2"));
- private static final ActorSystem ACTOR_SYSTEM_SLAVE2 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node3"));
-
- private static final ExecutorService callbackExecutor = Executors.newFixedThreadPool(8);
-
- private TopologyManager master = null;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- final SettableFuture<Optional<Topology>> settableFuture = SettableFuture.create();
- final CheckedFuture<Optional<Topology>, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
- @Nullable
- @Override
- public ReadFailedException apply(Exception input) {
- return new ReadFailedException("Dummy future should never return this");
- }
- });
- settableFuture.set(Optional.<Topology>absent());
- when(mockedReadOnlyTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(checkedFuture);
- when(dataBroker.registerDataChangeListener(
- any(LogicalDatastoreType.class),
- any(InstanceIdentifier.class),
- any(DataChangeListener.class),
- any(DataChangeScope.class))).thenReturn(null);
- when(dataBroker.newReadOnlyTransaction()).thenReturn(mockedReadOnlyTx);
- }
-
- private void setMaster(final TopologyManager manager) {
-
- }
-
- @Test
- public void testRealActors() throws Exception {
-
- EntityOwnershipService topoOwnership = new TestingEntityOwnershipService();
- // load from config
- final TopologyManager master = createManagerWithOwnership(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
- Thread.sleep(1000);
- final TopologyManager slave1 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
- final TopologyManager slave2 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
-
- await().atMost(30L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return master.hasAllPeersUp();
- }
- });
-
- final List<ListenableFuture<Node>> futures = new ArrayList<>();
- for (int i = 0; i <= 1; i++) {
- final String nodeid = "testing-node" + i;
- final Node testingNode = new NodeBuilder()
- .setNodeId(new NodeId(nodeid))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(10000 + i))
- .build())
- .build();
- final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
- futures.add(nodeListenableFuture);
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.warn("Node creation failed. ", t);
- }
- });
- }
-
- for (int i = 0; i <= 1; i++) {
- final String nodeid = "testing-node" + i;
- final Node testingNode = new NodeBuilder()
- .setNodeId(new NodeId(nodeid))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(10000 + i))
- .build())
- .build();
- final ListenableFuture<Node> nodeListenableFuture = master.onNodeUpdated(new NodeId(nodeid), testingNode);
- futures.add(nodeListenableFuture);
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- LOG.warn("Node {} updated succesfully on all nodes", result.getNodeId().getValue());
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.warn("Node update failed. ", t);
- }
- });
- }
- LOG.debug("Waiting for updates to finish");
- Futures.allAsList(futures).get();
-
-
- final List<ListenableFuture<Void>> deleteFutures = new ArrayList<>();
- for (int i = 0; i <= 1; i++) {
- final String nodeid = "testing-node" + i;
- final ListenableFuture<Void> nodeListenableFuture = master.onNodeDeleted(new NodeId(nodeid));
- deleteFutures.add(nodeListenableFuture);
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- LOG.warn("Node {} succesfully deleted on all nodes", nodeid);
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.warn("Node delete failed. ", t);
- }
- });
-
- }
- LOG.warn("All tasks submitted");
- Futures.allAsList(futures).get();
- Futures.allAsList(deleteFutures).get();
-
- TypedActor.get(ACTOR_SYSTEM).stop(master);
- TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
- TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
-
- }
-
- // TODO seems like stopping actors is not enough to create an actor with same name, split this into multiple classes?
- @Ignore
- @Test
- public void testWithDummyOwnershipService() throws Exception {
-
- final TestingEntityOwnershipService ownershipService = new TestingEntityOwnershipService();
- // load from config
- final TopologyManager master = createNoopRoleChangeNode(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoCallbackFactory(ownershipService));
- final TopologyManager slave1 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
- final TopologyManager slave2 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
-
- await().atMost(10L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return master.hasAllPeersUp();
- }
- });
-
- final List<ListenableFuture<Node>> futures = new ArrayList<>();
- for (int i = 0; i <= 0; i++) {
- final String nodeid = "testing-node" + i;
- final Node testingNode = new NodeBuilder()
- .setNodeId(new NodeId(nodeid))
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(10000 + i))
- .build())
- .build();
- final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
- futures.add(nodeListenableFuture);
- Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
- @Override
- public void onSuccess(Node result) {
- LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.warn("Node creation failed. ", t);
- }
- });
- }
-
- Futures.allAsList(futures).get();
- ownershipService.distributeOwnership();
-
- Thread.sleep(30000);
- TypedActor.get(ACTOR_SYSTEM).stop(master);
- TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
- TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
- }
-
- private TopologyManager createNoopRoleChangeNode(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
- final TopologyManagerCallbackFactory topologyManagerCallbackFactory) {
-
- final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
- return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
- @Override
- public BaseTopologyManager create() throws Exception {
- return new BaseTopologyManager(actorSystem,
- CODEC_REGISTRY,
- dataBroker,
- topologyId,
- topologyManagerCallbackFactory,
- new TestingSuccesfulStateAggregator(),
- new LoggingSalNodeWriter(),
- new NoopRoleChangeStrategy(),
- isMaster);
- }
- }), TOPOLOGY_NETCONF);
- }
-
- private TopologyManager createManagerWithOwnership(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
- final TopologyManagerCallbackFactory topologyManagerCallbackFactory, final RoleChangeStrategy roleChangeStrategy) {
- final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
- return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
- @Override
- public BaseTopologyManager create() throws Exception {
- return new BaseTopologyManager(actorSystem,
- CODEC_REGISTRY,
- dataBroker,
- topologyId,
- topologyManagerCallbackFactory,
- new NetconfNodeOperationalDataAggregator(),
- new LoggingSalNodeWriter(),
- roleChangeStrategy,
- isMaster);
- }
- }), TOPOLOGY_NETCONF);
- }
-
- private TopologyManagerCallbackFactory createRealTopoTestingNodeCallbackFactory() {
- final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
- @Override
- public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
- return new LoggingNodeManagerCallback();
- }
- };
-
- return new TopologyManagerCallbackFactory() {
- @Override
- public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
- return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory, new LoggingSalNodeWriter());
- }
- };
- }
-
- private TopologyManagerCallbackFactory createRealTopoCallbackFactory(final EntityOwnershipService entityOwnershipService) {
- final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
- @Override
- public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
- return new ExampleNodeManagerCallback();
- }
- };
-
- return new TopologyManagerCallbackFactory() {
- @Override
- public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
- return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory);
- }
- };
- }
-
- private TopologyManagerCallbackFactory createTestingTopoCallbackFactory() {
- return new TopologyManagerCallbackFactory() {
- @Override
- public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
- return new TestingTopologyManagerCallback();
- }
- };
- }
-
- public static class LoggingNodeManagerCallback implements NodeManagerCallback {
-
- @Nonnull
- @Override
- public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
- return new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setConnectionStatus(ConnectionStatus.Connecting)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Lists.newArrayList(
- new NodeStatusBuilder()
- .setNode("testing-node")
- .setStatus(Status.Unavailable)
- .build()))
- .build())
- .build())
- .build();
- }
-
- @Nonnull
- @Override
- public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
- return new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(netconfNode.getHost())
- .setPort(netconfNode.getPort())
- .setConnectionStatus(ConnectionStatus.UnableToConnect)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode("testing-node")
- .setStatus(Status.Failed)
- .build()))
- .build())
- .build())
- .build();
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> onNodeCreated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- LOG.debug("Creating node {} with config {}", nodeId, configNode);
- final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
- return Futures.immediateFuture(new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setHost(augmentation.getHost())
- .setPort(augmentation.getPort())
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode("testing-node")
- .setStatus(Status.Connected)
- .build()))
- .build())
- .build())
- .build());
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> onNodeUpdated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- LOG.debug("Updating node {} with config {}", nodeId, configNode);
- final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
- return Futures.immediateFuture(new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setHost(augmentation.getHost())
- .setPort(augmentation.getPort())
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Collections.singletonList(
- new NodeStatusBuilder()
- .setNode("testing-node")
- .setStatus(Status.Connected)
- .build()))
- .build())
- .build())
- .build());
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Void> onNodeDeleted(@Nonnull NodeId nodeId) {
- LOG.debug("Deleting node {}", nodeId);
- return Futures.immediateFuture(null);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- return null;
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
-
- }
-
- @Override
- public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
-
- }
-
- @Override
- public void onDeviceDisconnected() {
-
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
-
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
-
- }
-
- @Override
- public void close() {
-
- }
- }
-
- public static class TestingTopologyManagerCallback implements TopologyManagerCallback {
-
- public TestingTopologyManagerCallback() {
-
- }
-
- @Override
- public ListenableFuture<Node> onNodeCreated(NodeId nodeId, Node node) {
- LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
- return Futures.immediateFuture(new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(2555))
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build())
- .build());
- }
-
- @Override
- public ListenableFuture<Node> onNodeUpdated(NodeId nodeId, Node node) {
- LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
- LOG.debug("Update called on node {}, with config {}", nodeId.getValue(), node);
- return Futures.immediateFuture(new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connected)
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(65535))
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build())
- .build());
- }
-
- @Override
- public ListenableFuture<Void> onNodeDeleted(NodeId nodeId) {
- LOG.debug("Delete called on node {}", nodeId.getValue());
- return Futures.immediateFuture(null);
- }
-
- @Nonnull
- @Override
- public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
- return null;
- }
-
- @Override
- public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
- }
-
- @Override
- public void onReceive(Object o, ActorRef actorRef) {
-
- }
-
- @Nonnull
- @Override
- public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- return new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.Connecting)
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(65535))
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build())
- .build();
- }
-
- @Nonnull
- @Override
- public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
- return new NodeBuilder()
- .setNodeId(nodeId)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setConnectionStatus(ConnectionStatus.UnableToConnect)
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(65535))
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .build())
- .build();
- }
- }
-
- public class TestingSuccesfulStateAggregator implements StateAggregator {
-
- @Override
- public ListenableFuture<Node> combineCreateAttempts(List<ListenableFuture<Node>> stateFutures) {
- final SettableFuture<Node> future = SettableFuture.create();
- final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
- @Override
- public void onSuccess(List<Node> result) {
- for (int i = 0; i < result.size() - 1; i++) {
- if (!result.get(i).equals(result.get(i + 1))) {
- LOG.warn("Node 1 {}: {}", result.get(i).getClass(), result.get(i));
- LOG.warn("Node 2 {}: {}", result.get(i + 1).getClass(), result.get(i + 1));
- future.setException(new IllegalStateException("Create futures have different result"));
- LOG.warn("Future1 : {} Future2 : {}", result.get(i), result.get(i+1));
- }
- }
- future.set(result.get(0));
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("One of the combined create attempts failed {}", t);
- future.setException(t);
- }
- }, TypedActor.context().dispatcher());
-
- return future;
- }
-
- @Override
- public ListenableFuture<Node> combineUpdateAttempts(List<ListenableFuture<Node>> stateFutures) {
- final SettableFuture<Node> future = SettableFuture.create();
- final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
- @Override
- public void onSuccess(List<Node> result) {
- for (int i = 0; i < result.size() - 1; i++) {
- if (!result.get(i).equals(result.get(i + 1))) {
- future.setException(new IllegalStateException("Update futures have different result"));
- }
- }
- future.set(result.get(0));
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("One of the combined update attempts failed {}", t);
- future.setException(t);
- }
- });
- return future;
- }
-
- @Override
- public ListenableFuture<Void> combineDeleteAttempts(List<ListenableFuture<Void>> stateFutures) {
- final SettableFuture<Void> future = SettableFuture.create();
- final ListenableFuture<List<Void>> allAsList = Futures.allAsList(stateFutures);
- Futures.addCallback(allAsList, new FutureCallback<List<Void>>() {
- @Override
- public void onSuccess(List<Void> result) {
- future.set(null);
- }
-
- @Override
- public void onFailure(Throwable t) {
- LOG.error("One of the combined delete attempts failed {}", t);
- future.setException(t);
- }
- });
- return future;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import com.google.common.base.Optional;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestingEntityOwnershipService implements EntityOwnershipService{
-
- private static final Logger LOG = LoggerFactory.getLogger(TestingEntityOwnershipService.class);
-
- private final List<EntityOwnershipListener> listeners = new ArrayList<>();
- private final ExecutorService executorService = Executors.newFixedThreadPool(1);
-
- private Entity entity;
- private boolean masterSet = false;
-
- @Override
- public EntityOwnershipCandidateRegistration registerCandidate(final Entity entity) throws CandidateAlreadyRegisteredException {
- LOG.warn("Registering Candidate");
- this.entity = entity;
- return new EntityOwnershipCandidateRegistration() {
- @Override
- public void close() {
- LOG.debug("Closing candidate registration");
- }
-
- @Override
- public Entity getInstance() {
- return entity;
- }
- };
- }
-
- @Override
- public EntityOwnershipListenerRegistration registerListener(final String entityType, final EntityOwnershipListener listener) {
- listeners.add(listener);
- if (listeners.size() == 3) {
- distributeOwnership();
- }
- return new EntityOwnershipListenerRegistration() {
- @Nonnull
- @Override
- public String getEntityType() {
- return entityType;
- }
-
- @Override
- public void close() {
- listeners.remove(listener);
- }
-
- @Override
- public EntityOwnershipListener getInstance() {
- return listener;
- }
- };
- }
-
- @Override
- public Optional<EntityOwnershipState> getOwnershipState(final Entity forEntity) {
- return null;
- }
-
- @Override
- public boolean isCandidateRegistered(@Nonnull Entity entity) {
- return true;
- }
-
- public void distributeOwnership() {
- LOG.debug("Distributing ownership");
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- masterSet = false;
- LOG.debug("Distributing ownership for {} listeners", listeners.size());
- for (final EntityOwnershipListener listener : listeners) {
- if (!masterSet) {
- listener.ownershipChanged(new EntityOwnershipChange(entity, false, true, true));
- masterSet = true;
- } else {
- listener.ownershipChanged(new EntityOwnershipChange(entity, false, false, true));
- }
- }
-
- }
- });
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestingTopologyDispatcher implements NetconfTopology{
-
- private static final Logger LOG = LoggerFactory.getLogger(TestingTopologyDispatcher.class);
-
- private final String topologyId;
-
- private final ExecutorService executorService = Executors.newSingleThreadExecutor();
- private final Set<NodeId> connected = new HashSet<>();
- private final Map<NodeId, RemoteDeviceHandler<NetconfSessionPreferences>> listeners = new HashMap<>();
-
-
- public TestingTopologyDispatcher(final String topologyId) {
-
- this.topologyId = topologyId;
- }
-
- @Override
- public String getTopologyId() {
- return topologyId;
- }
-
- @Override
- public DataBroker getDataBroker() {
- return null;
- }
-
- // log the current connection attempt and return a successful future asynchronously
- @Override
- public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
- final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
- LOG.debug("Connecting node {}, with config: {} ", nodeId.getValue(),
- augmentation.getHost().getIpAddress().toString() + ":" + augmentation.getPort());
- connected.add(nodeId);
- final SettableFuture<NetconfDeviceCapabilities> future = SettableFuture.create();
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(4000);
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- future.set(new NetconfDeviceCapabilities());
- }
- });
- } catch (InterruptedException e) {
- LOG.error("Cannot sleep thread", e);
- }
- }
- });
- return future;
- }
-
- @Override
- public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
- Preconditions.checkState(connected.contains(nodeId), "Node is not connected yet");
- LOG.debug("Disconnecting node {}", nodeId.getValue());
- final SettableFuture<Void> future = SettableFuture.create();
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(4000);
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- connected.remove(nodeId);
- future.set(null);
- }
- });
- } catch (InterruptedException e) {
- LOG.error("Cannot sleep thread", e);
- }
-
- }
- });
- return future;
- }
-
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId) {
- LOG.debug("Registering mount point for node {}", nodeId.getValue());
- }
-
- @Override
- public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
- LOG.debug("Registering mount point for node {}", nodeId.getValue());
- }
-
- @Override
- public void unregisterMountPoint(NodeId nodeId) {
- LOG.debug("Unregistering mount point for node {}", nodeId.getValue());
- }
-
- @Override
- public ConnectionStatusListenerRegistration registerConnectionStatusListener(final NodeId node, final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
- Preconditions.checkState(connected.contains(node), "Node is not connected yet");
-
- LOG.debug("Registering a connection status listener for node {}", node.getValue());
- listeners.put(node, listener);
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(10000);
-
- boolean up = false;
- for (int i = 0; i < 20; i++) {
- if (up) {
- LOG.debug("Device has connected {}", node.getValue());
- listener.onDeviceConnected(null, null, null);
- up = false;
- } else {
- LOG.debug("Device has diconnected {}", node.getValue());
- listener.onDeviceDisconnected();
- up = true;
- }
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- LOG.error("Cannot sleep thread", e);
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- }
- });
-
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-
-public class NetconfNodeOperationalDataAggregatorTest {
-
- private List<ListenableFuture<Node>> stateFutures;
-
- private NetconfNodeOperationalDataAggregator aggregator;
-
- @Before
- public void setUp() {
- aggregator = new NetconfNodeOperationalDataAggregator();
- stateFutures = Lists.newArrayList();
- }
-
- @Test
- public void testCombineCreateAttempts() throws ExecutionException, InterruptedException {
- NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
- new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<AvailableCapability>newArrayList()).build())
- .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
- new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
- .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
- stateFutures.add(Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class, testingNode).build()));
-
- ListenableFuture<Node> aggregatedCreateFuture = aggregator.combineCreateAttempts(stateFutures);
- assertTrue(aggregatedCreateFuture.isDone());
-
- NetconfNode aggregatedNode = aggregatedCreateFuture.get().getAugmentation(NetconfNode.class);
- assertEquals(aggregatedNode.getClusteredConnectionStatus().getNodeStatus().get(0).getStatus(),
- NodeStatus.Status.Connected);
- }
-
- @Test
- public void testSuccessfulCombineUpdateAttempts() throws ExecutionException, InterruptedException {
- NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
- new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<AvailableCapability>newArrayList()).build())
- .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
- new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
- .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
- stateFutures.add(Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class, testingNode).build()));
-
- ListenableFuture<Node> aggregatedUpdateFuture = aggregator.combineUpdateAttempts(stateFutures);
- assertTrue(aggregatedUpdateFuture.isDone());
-
- NetconfNode aggregatedNode = aggregatedUpdateFuture.get().getAugmentation(NetconfNode.class);
- assertEquals(aggregatedNode.getClusteredConnectionStatus().getNodeStatus().get(0).getStatus(),
- NodeStatus.Status.Connected);
- }
-
- @Test
- public void testSuccessfulCombineDeleteAttempts() throws ExecutionException, InterruptedException {
- List deleteStateFutures = Lists.newArrayList(Futures.immediateFuture(null), Futures.immediateFuture(null));
-
- ListenableFuture<Void> deleteFuture = aggregator.combineDeleteAttempts(deleteStateFutures);
- assertTrue(deleteFuture.isDone());
- assertEquals(deleteFuture.get(), null);
- }
-
- @Test
- public void testFailedCombineDeleteAttempts() {
- Exception cause = new Exception("Fail");
- List deleteStateFutures = Lists.newArrayList(Futures.immediateFuture(null), Futures.immediateFuture(null),
- Futures.immediateFailedFuture(cause));
-
- ListenableFuture<Void> deleteFuture = aggregator.combineDeleteAttempts(deleteStateFutures);
- assertTrue(deleteFuture.isDone());
-
- try {
- deleteFuture.get();
- fail("Exception expected");
- } catch(Exception e) {
- assertSame(e.getCause(), cause);
- }
- }
-}
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import akka.actor.ActorContext;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.sal.core.api.Broker;
import org.opendaylight.netconf.client.NetconfClientDispatcher;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
spyTopology = spy(topology);
}
- @Test(expected = UnsupportedOperationException.class)
- public void testRegisterMountPointNotSupported() {
- ActorContext context = mock(ActorContext.class);
- topology.registerMountPoint(context, NODE_ID);
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testUnregisterMountPointNotSupported() {
- topology.unregisterMountPoint(NODE_ID);
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testRegisterConnectionStatusListener() {
- RemoteDeviceHandler<NetconfSessionPreferences> listener = mock(RemoteDeviceHandler.class);
- topology.registerConnectionStatusListener(NODE_ID, listener);
- }
-
@Test
public void testOnSessionInitiated() {
BindingAwareBroker.ProviderContext session = mock(BindingAwareBroker.ProviderContext.class);
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.impl;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-
-public class TopologyNodeWriterTest {
-
- private static final NodeId NODE_ID = new NodeId("testing-node");
- private static final String TOPOLOGY_ID = "testing-topology";
-
- private static final InstanceIdentifier<NetworkTopology> NETWORK_TOPOLOGY_IID = InstanceIdentifier.builder(NetworkTopology.class).build();
- private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_LIST_IID;
-
- private static final KeyedInstanceIdentifier<Node, NodeKey> OPERATIONAL_NODE_IID;
-
- static {
- TOPOLOGY_LIST_IID = NETWORK_TOPOLOGY_IID.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)));
- OPERATIONAL_NODE_IID = TOPOLOGY_LIST_IID.child(Node.class, new NodeKey(new NodeId(NODE_ID)));
- }
-
- @Mock
- private DataBroker dataBroker;
-
- @Mock
- private BindingTransactionChain txChain;
-
- @Mock
- private WriteTransaction wtx;
-
- private Node operationalNode;
-
- private TopologyNodeWriter writer;
-
- @Before
- public void setUp() throws Exception {
- initMocks(this);
- doReturn(txChain).when(dataBroker).createTransactionChain(any(TransactionChainListener.class));
- doReturn(wtx).when(txChain).newWriteOnlyTransaction();
- doNothing().when(wtx).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
- doReturn(Futures.immediateCheckedFuture(null)).when(wtx).submit();
- writer = new TopologyNodeWriter(TOPOLOGY_ID, dataBroker);
-
- operationalNode = new NodeBuilder()
- .setNodeId(NODE_ID)
- .addAugmentation(NetconfNode.class,
- new NetconfNodeBuilder()
- .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
- .setPort(new PortNumber(17830))
- .setConnectionStatus(ConnectionStatus.Connected)
- .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<AvailableCapability>()).build())
- .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
- .setClusteredConnectionStatus(
- new ClusteredConnectionStatusBuilder()
- .setNodeStatus(
- Lists.newArrayList(
- new NodeStatusBuilder()
- .setNode("10.10.10.10")
- .setStatus(Status.Connected)
- .build()))
- .build())
- .build())
- .build();
-
- }
-
- @Test
- public void testInit() throws Exception {
- writer.init(NODE_ID, operationalNode);
- // once in constructor + once in init
- verify(txChain, times(2)).newWriteOnlyTransaction();
- verify(wtx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
- verify(wtx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
- // actual write
- verify(wtx, times(1)).put(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID), eq(operationalNode));
-
- // once in constructor + once in init()
- verify(wtx, times(2)).submit();
- }
-
- @Test
- public void testUpdate() throws Exception {
- writer.update(NODE_ID, operationalNode);
-
- verify(txChain, times(2)).newWriteOnlyTransaction();
- verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
- verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
- // actual write
- verify(wtx, times(1)).put(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID), eq(operationalNode));
- verify(wtx, times(2)).submit();
-
- }
-
- @Test
- public void testDelete() throws Exception {
- writer.delete(NODE_ID);
- verify(txChain, times(2)).newWriteOnlyTransaction();
- verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
- verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
- verify(wtx, times(1)).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID));
- verify(wtx, times(2)).submit();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-
-public class ClusteredNetconfDeviceCommunicatorTest {
-
- private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-
- @Mock
- private ClusteredNetconfDevice remoteDevice;
-
- @Mock
- private EntityOwnershipService ownershipService;
-
- @Mock
- private NetconfClientSession session;
-
- @Mock
- private NetconfClientSessionListener listener1;
-
- @Mock
- private NetconfClientSessionListener listener2;
-
- @Mock
- private EntityOwnershipListenerRegistration ownershipListenerRegistration;
-
- private ClusteredNetconfDeviceCommunicator communicator;
-
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- doReturn(ownershipListenerRegistration).when(ownershipService).registerListener(
- "netconf-node/" + REMOTE_DEVICE_ID.getName(), remoteDevice);
-
- communicator = new ClusteredNetconfDeviceCommunicator(REMOTE_DEVICE_ID, remoteDevice, ownershipService, 10);
- communicator.registerNetconfClientSessionListener(listener1);
- communicator.registerNetconfClientSessionListener(listener2);
- }
-
- @Test
- public void testOnSessionDown() {
- communicator.onSessionUp(session);
-
- Exception exception = mock(Exception.class);
- communicator.onSessionDown(session, exception);
-
- verify(ownershipListenerRegistration).close();
-
- verify(listener1).onSessionDown(eq(session), eq(exception));
- verify(listener2).onSessionDown(eq(session), eq(exception));
- }
-
- @Test
- public void testOnSessionUp() {
- communicator.onSessionUp(session);
-
- verify(ownershipService).registerListener("netconf-node/" + REMOTE_DEVICE_ID.getName(), remoteDevice);
-
- verify(listener1).onSessionUp(eq(session));
- verify(listener2).onSessionUp(eq(session));
- }
-
- @Test
- public void testOnSessionTerminated() {
- communicator.onSessionUp(session);
-
- NetconfTerminationReason reason = mock(NetconfTerminationReason.class);
- communicator.onSessionTerminated(session, reason);
-
- verify(ownershipListenerRegistration).close();
-
- verify(listener1).onSessionTerminated(eq(session), eq(reason));
- verify(listener2).onSessionTerminated(eq(session), eq(reason));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import akka.actor.ActorSystem;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class NetconfDeviceSlaveDataBrokerTest {
-
- private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-
- @Mock
- private ProxyNetconfDeviceDataBroker mockedDataBroker;
-
- @Mock
- private ActorSystem mockedActorSystem;
-
- private NetconfDeviceSlaveDataBroker slaveDataBroker;
-
- @Before
- public void setUp() {
- slaveDataBroker = new NetconfDeviceSlaveDataBroker(mockedActorSystem, REMOTE_DEVICE_ID, mockedDataBroker);
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testRegisterDataChangeListener() {
- slaveDataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY,
- mock(DOMDataChangeListener.class), AsyncDataBroker.DataChangeScope.SUBTREE);
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testCreateTransactionChain() {
- slaveDataBroker.createTransactionChain(mock(TransactionChainListener.class));
- }
-
- @Test
- public void testGetSupportedExtensions() {
- assertTrue(slaveDataBroker.getSupportedExtensions().isEmpty());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline;
-
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class TopologyMountPointFacadeTest {
-
- private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
- private static final String TOPOLOGY_ID = "testing-topology";
-
- @Mock
- Broker domBroker;
-
- @Mock
- BindingAwareBroker bindingBroker;
-
- @Mock
- RemoteDeviceHandler<NetconfSessionPreferences> connectionStatusListener1;
-
- @Mock
- RemoteDeviceHandler<NetconfSessionPreferences> connectionStatusListener2;
-
-
- private TopologyMountPointFacade mountPointFacade;
-
- @Before
- public void setUp() {
-
- MockitoAnnotations.initMocks(this);
-
- mountPointFacade = new TopologyMountPointFacade(TOPOLOGY_ID, REMOTE_DEVICE_ID, domBroker, bindingBroker);
-
- mountPointFacade.registerConnectionStatusListener(connectionStatusListener1);
- mountPointFacade.registerConnectionStatusListener(connectionStatusListener2);
-
- }
-
- @Test
- public void testOnDeviceConnected() {
- SchemaContext mockedContext = Mockito.mock(SchemaContext.class);
- NetconfSessionPreferences mockedPreferences = NetconfSessionPreferences.fromStrings(Collections.<String>emptyList());
- DOMRpcService mockedRpcService = Mockito.mock(DOMRpcService.class);
- mountPointFacade.onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
-
- Mockito.verify(connectionStatusListener1).onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
- Mockito.verify(connectionStatusListener2).onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
- }
-
- @Test
- public void testOnDeviceDisconnected() {
- mountPointFacade.onDeviceDisconnected();
-
- Mockito.verify(connectionStatusListener1).onDeviceDisconnected();
- Mockito.verify(connectionStatusListener2).onDeviceDisconnected();
- }
-
- @Test
- public void testOnDeviceFailed() {
- Throwable mockedException = Mockito.mock(Throwable.class);
- mountPointFacade.onDeviceFailed(mockedException);
-
- Mockito.verify(connectionStatusListener1).onDeviceFailed(mockedException);
- Mockito.verify(connectionStatusListener2).onDeviceFailed(mockedException);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.tx;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.ExecutionContexts;
-import akka.dispatch.Futures;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ProxyReadOnlyTransactionTest {
- private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
- private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
-
- @Mock
- private ProxyNetconfDeviceDataBroker mockedProxyDataBroker;
-
- @Mock
- private ActorSystem mockedActorSystem;
-
- @Mock
- private NormalizedNodeMessage mockedNodeMessage;
-
- @Mock
- private NormalizedNode mockedNode;
-
- private ProxyReadOnlyTransaction proxyReadOnlyTx;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- when(mockedActorSystem.dispatcher()).thenReturn(ExecutionContexts.fromExecutorService(MoreExecutors.newDirectExecutorService()));
- when(mockedNodeMessage.getNode()).thenReturn(mockedNode);
-
- proxyReadOnlyTx = new ProxyReadOnlyTransaction(mockedActorSystem, REMOTE_DEVICE_ID, mockedProxyDataBroker);
- }
-
- @Test
- public void testSuccessfulRead() throws ReadFailedException {
- when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(Futures.successful(Optional.of(mockedNodeMessage)));
- CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture = proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
- verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
- assertTrue(readResultFuture.isDone());
- assertEquals(readResultFuture.checkedGet().get(), mockedNode);
- }
-
- @Test
- public void testFailedRead() {
- when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(Futures.<Optional<NormalizedNodeMessage>>failed(new ReadFailedException("Test read failed!")));
- CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture = proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
- verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
- assertTrue(readResultFuture.isDone());
- try {
- readResultFuture.checkedGet();
- fail("Exception expected");
- } catch(Exception e) {
- assertTrue(e instanceof ReadFailedException);
- }
- }
-
- @Test
- public void testDataOnPathDoesNotExistPathRead() throws ReadFailedException {
- when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(Futures.successful(Optional.absent()));
- CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture = proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
- verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
- assertTrue(readResultFuture.isDone());
- assertTrue(!readResultFuture.checkedGet().isPresent());
- }
-
- @Test
- public void testFailedExists() {
- when(mockedProxyDataBroker.exists(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(Futures.<Boolean>failed(new ReadFailedException("Test read failed!")));
- CheckedFuture existsFuture = proxyReadOnlyTx.exists(LogicalDatastoreType.OPERATIONAL, path);
- verify(mockedProxyDataBroker).exists(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
- assertTrue(existsFuture.isDone());
- try {
- existsFuture.checkedGet();
- fail("Exception expected");
- } catch(Exception e) {
- assertTrue(e instanceof ReadFailedException);
- }
- }
-
- @Test
- public void testExists() throws Exception {
- when(mockedProxyDataBroker.exists(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(Futures.successful(true));
- CheckedFuture<Boolean, ReadFailedException> existsFuture = proxyReadOnlyTx.exists(LogicalDatastoreType.OPERATIONAL, path);
- verify(mockedProxyDataBroker).exists(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
- assertTrue(existsFuture.isDone());
- assertTrue(existsFuture.checkedGet());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.pipeline.tx;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.ExecutionContexts;
-import akka.dispatch.Futures;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ProxyWriteOnlyTransactionTest {
- private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
- private ArgumentCaptor<NormalizedNodeMessage> nodeMessageArgumentCaptor;
-
- @Mock
- private ProxyNetconfDeviceDataBroker mockedDelegate;
-
- @Mock
- private ActorSystem mockedActorSystem;
-
- @Mock
- private NormalizedNode<?, ?> normalizedNode;
-
- private ProxyWriteOnlyTransaction tx;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- when(mockedActorSystem.dispatcher()).thenReturn(ExecutionContexts.fromExecutorService(MoreExecutors.newDirectExecutorService()));
-
- nodeMessageArgumentCaptor = ArgumentCaptor.forClass(NormalizedNodeMessage.class);
- tx = new ProxyWriteOnlyTransaction(mockedActorSystem, mockedDelegate);
- }
-
- @Test
- public void testPut() {
- doNothing().when(mockedDelegate).put(any(LogicalDatastoreType.class), any(NormalizedNodeMessage.class));
- tx.put(LogicalDatastoreType.OPERATIONAL, path, normalizedNode);
- verify(mockedDelegate).put(eq(LogicalDatastoreType.OPERATIONAL), nodeMessageArgumentCaptor.capture());
- assertEquals(path, nodeMessageArgumentCaptor.getValue().getIdentifier());
- assertEquals(normalizedNode, nodeMessageArgumentCaptor.getValue().getNode());
- }
-
- @Test
- public void testMerge() {
- doNothing().when(mockedDelegate).merge(any(LogicalDatastoreType.class), any(NormalizedNodeMessage.class));
- tx.merge(LogicalDatastoreType.CONFIGURATION, path, normalizedNode);
- verify(mockedDelegate).merge(eq(LogicalDatastoreType.CONFIGURATION), nodeMessageArgumentCaptor.capture());
- assertEquals(path, nodeMessageArgumentCaptor.getValue().getIdentifier());
- assertEquals(normalizedNode, nodeMessageArgumentCaptor.getValue().getNode());
- }
-
- @Test
- public void testCancel() {
- when(mockedDelegate.cancel()).thenReturn(true);
- assertTrue(tx.cancel());
- verify(mockedDelegate).cancel();
- }
-
- @Test
- public void testDelete() {
- doNothing().when(mockedDelegate).delete(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
- tx.delete(LogicalDatastoreType.OPERATIONAL, path);
- verify(mockedDelegate).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
- }
-
- @Test
- public void testSuccessfulSubmit() throws Exception {
- when(mockedDelegate.submit()).thenReturn(Futures.<Void>successful(null));
- CheckedFuture submitFuture = tx.submit();
- verify(mockedDelegate).submit();
- assertTrue(submitFuture.isDone());
- assertEquals(submitFuture.checkedGet(), null);
- }
-
- @Test
- public void testFailedSubmit() {
- when(mockedDelegate.submit()).thenReturn(Futures.<Void>failed(new TransactionCommitFailedException("fail")));
- CheckedFuture submitFuture = tx.submit();
- verify(mockedDelegate).submit();
- assertTrue(submitFuture.isDone());
- try {
- submitFuture.checkedGet();
- fail("Exception expected");
- } catch(Exception e) {
- assertTrue(e instanceof TransactionCommitFailedException);
- }
- }
-
- @Test
- public void testSuccessfulCommit() throws ExecutionException, InterruptedException {
- RpcResult<TransactionStatus> rpcResult = mock(RpcResult.class);
- when(mockedDelegate.commit()).thenReturn(Futures.successful(rpcResult));
- ListenableFuture<RpcResult<TransactionStatus>> submitFuture = tx.commit();
- verify(mockedDelegate).commit();
- assertTrue(submitFuture.isDone());
- assertEquals(submitFuture.get(), rpcResult);
- }
-
- @Test
- public void testFailedCommit() {
- when(mockedDelegate.commit()).thenReturn(Futures.<RpcResult<TransactionStatus>>failed(new TransactionCommitFailedException("faile")));
- ListenableFuture<RpcResult<TransactionStatus>> submitFuture = tx.commit();
- verify(mockedDelegate).commit();
- assertTrue(submitFuture.isDone());
- try {
- submitFuture.get();
- fail("Exception expected");
- } catch(Exception e) {
- assertTrue(e.getCause() instanceof TransactionCommitFailedException);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-include "test.conf"
-
-akka {
- # LISTEN on tcp port 2552
- remote.netty.tcp.port = 2552
-
- cluster {
- seed-nodes = [
- "akka.tcp://NetconfNode@127.0.0.1:2553",
- "akka.tcp://NetconfNode@127.0.0.1:2554"]
-
- auto-down-unreachable-after = 10s
- }
-}
+++ /dev/null
-include "test.conf"
-
-akka {
- # LISTEN on tcp port 2553
- remote.netty.tcp.port = 2553
-
- cluster {
- seed-nodes = [
- "akka.tcp://NetconfNode@127.0.0.1:2552",
- "akka.tcp://NetconfNode@127.0.0.1:2554"]
-
- auto-down-unreachable-after = 10s
- }
-}
+++ /dev/null
-include "test.conf"
-
-akka {
- # LISTEN on tcp port 2554
- remote.netty.tcp.port = 2554
-
- cluster {
- seed-nodes = [
- "akka.tcp://NetconfNode@127.0.0.1:2552",
- "akka.tcp://NetconfNode@127.0.0.1:2553"]
-
- auto-down-unreachable-after = 10s
- }
-}
+++ /dev/null
-akka {
-
- actor {
- provider = "akka.cluster.ClusterActorRefProvider"
-
- serializers {
- java = "akka.serialization.JavaSerializer"
- }
-
- serialization-bindings {
- "[B" = bytes
- "java.io.Serializable" = java
- }
- }
-
- remote {
- enabled-transports = ["akka.remote.netty.tcp"]
- netty.tcp {
- hostname = "127.0.0.1"
- }
- }
-}
<module>netconf-notifications-api</module>
<module>netconf-topology</module>
<module>netconf-topology-singleton</module>
- <module>abstract-topology</module>
<module>netconf-topology-config</module>
<module>sal-netconf-connector</module>
<module>messagebus-netconf</module>
return new NetconfDeviceRpc(baseSchema.getSchemaContext(), listener, new NetconfMessageTransformer(baseSchema.getSchemaContext(), false, baseSchema));
}
- protected NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+ public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
final ExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
this.id = id;
this.reconnectOnSchemasChange = reconnectOnSchemasChange;
return remoteSessionCapabilities.isNotificationsSupported() && reconnectOnSchemasChange;
}
- protected void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
+ void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
final BaseSchema baseSchema =
remoteSessionCapabilities.isNotificationsSupported() ?
BaseSchema.BASE_NETCONF_CTX_WITH_NOTIFICATIONS :
LOG.info("{}: Netconf connector initialized successfully", id);
}
- protected void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
+ void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
LOG.error("{}: Initialization in sal failed, disconnecting from device", id, t);
listener.close();
onRemoteSessionDown();