private static final Logger LOG = LoggerFactory.getLogger(BaseNodeManager.class);
private final String nodeId;
- private final String topologyId;
- private final ActorSystem actorSystem;
-
- private boolean isMaster = false;
- private NodeManagerCallback delegate;
+ private final NodeManagerCallback delegate;
private BaseNodeManager(final String nodeId,
final String topologyId,
final RoleChangeStrategy roleChangeStrategy) {
LOG.debug("Creating BaseNodeManager, id: {}, {}", topologyId, nodeId );
this.nodeId = nodeId;
- this.topologyId = topologyId;
- this.actorSystem = actorSystem;
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
(roleChangeDTO.wasOwner() ? "master" : "slave"),
(roleChangeDTO.isOwner() ? "master" : "slave"));
- isMaster = roleChangeDTO.isOwner();
delegate.onRoleChanged(roleChangeDTO);
}
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.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;
-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.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
implements TopologyManager {
private static final Logger LOG = LoggerFactory.getLogger(BaseTopologyManager.class);
- private static final InstanceIdentifier<NetworkTopology> NETWORK_TOPOLOGY_PATH = InstanceIdentifier.builder(NetworkTopology.class).build();
private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
private final Set<NodeId> created = new HashSet<>();
private final Map<Address, TopologyManager> peers = new HashMap<>();
- private TopologyManager masterPeer = null;
private final int id = new Random().nextInt();
private boolean isMaster;
// election has not yet happened
this.isMaster = isMaster;
- this.topologyListPath = NETWORK_TOPOLOGY_PATH.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
+ this.topologyListPath = TopologyUtil.createTopologyListPath(topologyId);
LOG.debug("Base manager started ", +id);
}
// 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(getNodeIid(topologyId), node);
+ final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), node);
LOG.debug("YangInstanceIdentifier {}", normalizedNodeEntry.getKey());
LOG.debug("Value {}", normalizedNodeEntry.getValue());
return delegateTopologyHandler.onNodeUpdated(nodeId, node);
}
- private static InstanceIdentifier<Node> getNodeIid(final String topologyId) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
- return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId))).child(Node.class);
- }
-
@Override
public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
final ArrayList<ListenableFuture<Void>> futures = new ArrayList<>();
Futures.addCallback(listenableFuture, new FutureCallback<Node>() {
@Override
public void onSuccess(Node result) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(getNodeIid(topologyId), result);
+ final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), result);
promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
}
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(getNodeIid(topologyId), node);
+ 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
}
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.TransactionCommitFailedException;
-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;
-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.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.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final DataBroker dataBroker;
private final String topologyId;
- private final InstanceIdentifier<Topology> topologyListPath;
-
public SalNodeWriter(final DataBroker dataBroker, final String topologyId) {
this.dataBroker = dataBroker;
this.topologyId = topologyId;
- this.topologyListPath = createTopologyId(this.topologyId);
}
//FIXME change to txChains
@Override public void init(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode) {
// put into Datastore
final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
- wTx.put(LogicalDatastoreType.OPERATIONAL, createBindingPathForTopology(id), operationalDataNode);
+ 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 = dataBroker.newWriteOnlyTransaction();
- wTx.put(LogicalDatastoreType.OPERATIONAL, createBindingPathForTopology(id), operationalDataNode);
+ 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 = dataBroker.newWriteOnlyTransaction();
- wTx.delete(LogicalDatastoreType.OPERATIONAL, createBindingPathForTopology(id));
+ wTx.delete(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId));
commitTransaction(wTx, id, "delete");
}
}
});
}
-
- private InstanceIdentifier<Node> createBindingPathForTopology(final NodeId id) {
- return topologyListPath.child(Node.class, new NodeKey(id));
- }
-
- private InstanceIdentifier<Topology> createTopologyId(final String topologyId) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
- return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
- }
}
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.NetworkTopology;
-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.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.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
LOG.warn("Gained ownership of entity, registering datastore listener");
if (datastoreListenerRegistration == null) {
- LOG.debug("Listener on path {}", createTopologyId(entityType).child(Node.class).getPathArguments());
+ LOG.debug("Listener on path {}", TopologyUtil.createTopologyListPath(entityType).child(Node.class).getPathArguments());
datastoreListenerRegistration = dataBroker.registerDataTreeChangeListener(
- new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, createTopologyId(entityType).child(Node.class)), this);
+ 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");
switch (rootNode.getModificationType()) {
case WRITE:
LOG.debug("Data was Created {}, {}", rootNode.getIdentifier(), rootNode.getDataAfter());
- ownershipCandidate.onNodeCreated(getNodeId(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(getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
+ ownershipCandidate.onNodeUpdated(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
break;
case DELETE:
LOG.debug("Data was Deleted {}", rootNode.getIdentifier());
- ownershipCandidate.onNodeDeleted(getNodeId(rootNode.getIdentifier()));
+ ownershipCandidate.onNodeDeleted(TopologyUtil.getNodeId(rootNode.getIdentifier()));
}
}
}
-
- /**
- * Determines the Netconf Node Node ID, given the node's instance
- * identifier.
- *
- * @param pathArgument Node's path arument
- * @return NodeId for the node
- */
- private NodeId getNodeId(final PathArgument pathArgument) {
- if (pathArgument instanceof InstanceIdentifier.IdentifiableItem<?, ?>) {
-
- final Identifier key = ((InstanceIdentifier.IdentifiableItem) pathArgument).getKey();
- if(key instanceof NodeKey) {
- return ((NodeKey) key).getNodeId();
- }
- }
- throw new IllegalStateException("Unable to create NodeId from: " + pathArgument);
- }
-
- private static InstanceIdentifier<Topology> createTopologyId(final String topologyId) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
- return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
- }
}
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.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.Identifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
public final class TopologyUtil {
throw new IllegalStateException("Unable to create NodeId from: " + pathArgument);
}
- public static InstanceIdentifier<Topology> createTopologyId(final String topologyId) {
+ public static KeyedInstanceIdentifier<Topology, TopologyKey> createTopologyListPath(final String topologyId) {
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);
+ }
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
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.netconf.node.credentials.Credentials;
-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;
-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.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.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = null;
final String moduleSchemaCacheDirectory = node.getSchemaCacheDirectory();
// Only checks to ensure the String is not empty or null; further checks related to directory accessibility and file permissions
- // are handled during the FilesystemScehamSourceCache initialization.
+ // are handled during the FilesystemSchemaSourceCache initialization.
if (!Strings.isNullOrEmpty(moduleSchemaCacheDirectory)) {
// If a custom schema cache directory is specified, create the backing DTO; otherwise, the SchemaRegistry and
// SchemaContextFactory remain the default values.
// Look for the cached DTO to reuse SchemaRegistry and SchemaContextFactory variables if they already exist
schemaResourcesDTO = schemaResourcesDTOs.get(moduleSchemaCacheDirectory);
if (schemaResourcesDTO == null) {
- schemaResourcesDTO = createSchemaResourcesDTO(moduleSchemaCacheDirectory, nodeId.getValue());
+ schemaResourcesDTO = createSchemaResourcesDTO(moduleSchemaCacheDirectory);
schemaResourcesDTO.getSchemaRegistry().registerSchemaSourceListener(
TextToASTTransformer.create((SchemaRepository) schemaResourcesDTO.getSchemaRegistry(), schemaResourcesDTO.getSchemaRegistry())
);
* @param moduleSchemaCacheDirectory The string directory relative to "cache"
* @return A DTO containing the Schema classes for the Netconf mount.
*/
- private NetconfDevice.SchemaResourcesDTO createSchemaResourcesDTO(final String moduleSchemaCacheDirectory,
- final String instanceName) {
-
+ private NetconfDevice.SchemaResourcesDTO createSchemaResourcesDTO(final String moduleSchemaCacheDirectory) {
final SharedSchemaRepository repository = new SharedSchemaRepository(moduleSchemaCacheDirectory);
final SchemaContextFactory schemaContextFactory
= repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
@Override
public void onSessionInitiated(ProviderSession session) {
- mountPointService = session.getService(DOMMountPointService.class);
+ mountPointService = session.getService(DOMMountPointService.class);
}
@Override
return Collections.emptySet();
}
- //TODO this needs to be an util method, since netconf clustering uses this aswell
- /**
- * Determines the Netconf Node Node ID, given the node's instance
- * identifier.
- *
- * @param pathArgument Node's path arument
- * @return NodeId for the node
- */
- protected NodeId getNodeId(final PathArgument pathArgument) {
- if (pathArgument instanceof InstanceIdentifier.IdentifiableItem<?, ?>) {
-
- final Identifier key = ((InstanceIdentifier.IdentifiableItem) pathArgument).getKey();
- if(key instanceof NodeKey) {
- return ((NodeKey) key).getNodeId();
- }
- }
- throw new IllegalStateException("Unable to create NodeId from: " + pathArgument);
- }
-
- protected static InstanceIdentifier<Topology> createTopologyId(final String topologyId) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
- return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
- }
-
private InetSocketAddress getSocketAddress(final Host host, int port) {
if(host.getDomainName() != null) {
return new InetSocketAddress(host.getDomainName().getValue(), port);
return ((TopologyMountPointFacade) activeConnectors.get(node).getFacade()).registerConnectionStatusListener(listener);
}
- @Override
public Collection<ProviderFunctionality> getProviderFunctionality() {
return Collections.emptySet();
}
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;
LOG.debug("Registering datastore listener");
datastoreListenerRegistration =
dataBroker.registerDataTreeChangeListener(
- new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, createTopologyId(topologyId).child(Node.class)), this);
+ new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ TopologyUtil.createTopologyListPath(topologyId).child(Node.class)), this);
}
final DataObjectModification<Node> rootNode = change.getRootNode();
switch (rootNode.getModificationType()) {
case SUBTREE_MODIFIED:
- LOG.debug("Config for node {} updated", getNodeId(rootNode.getIdentifier()));
- disconnectNode(getNodeId(rootNode.getIdentifier()));
- connectNode(getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
+ LOG.debug("Config for node {} updated", TopologyUtil.getNodeId(rootNode.getIdentifier()));
+ disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
+ connectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
break;
case WRITE:
- LOG.debug("Config for node {} created", getNodeId(rootNode.getIdentifier()));
- if (activeConnectors.containsKey(getNodeId(rootNode.getIdentifier()))) {
- LOG.warn("RemoteDevice{{}} was already configured, reconfiguring..", getNodeId(rootNode.getIdentifier()));
- disconnectNode(getNodeId(rootNode.getIdentifier()));
+ LOG.debug("Config for node {} created", TopologyUtil.getNodeId(rootNode.getIdentifier()));
+ if (activeConnectors.containsKey(TopologyUtil.getNodeId(rootNode.getIdentifier()))) {
+ LOG.warn("RemoteDevice{{}} was already configured, reconfiguring..", TopologyUtil.getNodeId(rootNode.getIdentifier()));
+ disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
}
- connectNode(getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
+ connectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
break;
case DELETE:
- LOG.debug("Config for node {} deleted", getNodeId(rootNode.getIdentifier()));
- disconnectNode(getNodeId(rootNode.getIdentifier()));
+ LOG.debug("Config for node {} deleted", TopologyUtil.getNodeId(rootNode.getIdentifier()));
+ disconnectNode(TopologyUtil.getNodeId(rootNode.getIdentifier()));
break;
}
}
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;
final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
createNetworkTopologyIfNotPresent(writeTx, LogicalDatastoreType.OPERATIONAL);
- final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
+ 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);
try {
final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
- final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
+ 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);
try {
final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
- final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
+ final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
LOG.trace(
"{}: Close device state transaction {} removing all data started. Path: {}",
Topology.QNAME, writeTx.getIdentifier());
writeTx.merge(datastoreType, topologyListPath, topology);
}
-
- private static InstanceIdentifier<Node> createBindingPathForTopology(final NodeKey key, final String topologyId) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
- final KeyedInstanceIdentifier<Topology, TopologyKey> topology = networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
- return topology
- .child(Node.class, new NodeKey(new NodeId(key.getNodeId().getValue())));
- }
}
@Override
public void onComplete(Throwable throwable, Optional<NormalizedNodeMessage> normalizedNodeMessage) throws Throwable {
if (throwable == null) {
- settableFuture.set(normalizedNodeMessage.transform(new Function<NormalizedNodeMessage, NormalizedNode<?, ?>>() {
- @Nullable
- @Override
- public NormalizedNode<?, ?> apply(NormalizedNodeMessage input) {
- return input.getNode();
- }
- }));
+ 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);
}
--- /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.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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)
+ .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)
+ .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)
+ .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)
+ .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, long defaultRequestTimeoutMillis) {
+ 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) {
+
+ }
+ }
+}
\ No newline at end of file
when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
InstanceIdentifier.PathArgument pa = null;
- for (InstanceIdentifier.PathArgument p : TopologyUtil.createTopologyId(TOPOLOGY_ID).child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
+
+ for (InstanceIdentifier.PathArgument p : TopologyUtil.createTopologyListPath(TOPOLOGY_ID).child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
pa = p;
}
--- /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
}
}
+ @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() {