import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations.InterfaceConfiguration;
import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations.InterfaceConfigurationKey;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.ETH;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortRole;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePoint;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePointBuilder;
ServiceInterfacePoint sip = new ServiceInterfacePointBuilder()
.setUuid(new Uuid("sip:" + nep.getUuid().getValue()))
// .setState(St)
-// TODO donaldh .setDirection(TerminationDirection.Bidirectional)
.setLayerProtocol(Collections.singletonList(new LayerProtocolBuilder()
.setLocalId("eth")
.setLayerProtocolName(ETH.class)
return tpBuilder
.setUuid(tpId)
.setKey(new OwnedNodeEdgePointKey(tpId))
+ .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
+ .setLinkPortRole(PortRole.SYMMETRIC)
.build();
}).collect(Collectors.toList());
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.ConnectivityServiceEndPoint;
+import java.util.Objects;
/**
* @see ConnectivityServiceEndPoint
* @author bartosz.michalik@amartus.com
this.systemNepUuid = systemNepUuid;
return this;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ EndPoint endPoint = (EndPoint) o;
+ return Objects.equals(endpoint, endPoint.endpoint) &&
+ Objects.equals(attrs, endPoint.attrs) &&
+ Objects.equals(systemNepUuid, endPoint.systemNepUuid);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(endpoint, attrs, systemNepUuid);
+ }
}
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.connectivity.context.ConnectivityService;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.connectivity.context.ConnectivityServiceKey;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.Context1;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.get.node.edge.point.details.output.NodeEdgePoint;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePoint;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePointKey;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.Topology;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.TopologyKey;
public NrpDao(ReadWriteTransaction tx) {
+ if(tx == null) throw new NullPointerException();
this.tx = tx;
this.rtx = tx;
}
this.tx = null;
}
- private Function<NodeEdgePoint, OwnedNodeEdgePoint> toNep = nep -> new OwnedNodeEdgePointBuilder(nep).build();
-
public Node createSystemNode(String nodeId, List<OwnedNodeEdgePoint> neps) {
verifyTx();
Uuid uuid = new Uuid(nodeId);
}
public void updateNep(Uuid nodeId, OwnedNodeEdgePoint nep) {
+ verifyTx();
InstanceIdentifier<OwnedNodeEdgePoint> nodeIdent = node(nodeId).child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nep.getUuid()));
tx.put(LogicalDatastoreType.OPERATIONAL, nodeIdent, nep);
}
return topo(TapiConstants.PRESTO_EXT_TOPO).child(Node.class, new NodeKey(new Uuid(TapiConstants.PRESTO_ABSTRACT_NODE)));
}
+ public void removeSip(Uuid uuid) {
+ removeSips(Stream.of(uuid));
+ }
+
public void removeSips(Stream<Uuid> uuids) {
verifyTx();
if (uuids == null) {
public List<ConnectivityService> getConnectivityServiceList() {
try {
- return rtx.read(LogicalDatastoreType.OPERATIONAL,
+ org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.Context1 connections = rtx.read(LogicalDatastoreType.OPERATIONAL,
ctx().augmentation(org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.Context1.class))
- .checkedGet().orNull().getConnectivityService();
+ .checkedGet().orNull();
+ return connections == null ? null : connections.getConnectivityService();
} catch (ReadFailedException e) {
LOG.warn("reading connectivity services failed", e);
return null;
public void init() {
registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NRP_TOPOLOGY_SYSTEM_IID), this);
+
+ LOG.debug("AbstractNodeHandler registered: {}", registration);
}
public void close() {
if (registration != null) {
registration.close();
+ LOG.debug("AbstractNodeHandler closed");
}
}
@Override
public void onSuccess(@Nullable Void result) {
- LOG.info("Abstract TAPI node upadate successful");
+ LOG.info("Abstract TAPI node updated successful");
}
@Override
package org.opendaylight.unimgr.mef.nrp.impl.decomposer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;
-import org.jgrapht.graph.SimpleGraph;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.unimgr.mef.nrp.api.TapiConstants;
import org.opendaylight.unimgr.mef.nrp.common.NrpDao;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.OperationalState;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortDirection;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.Node;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.Topology;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
/**
* @author bartosz.michalik@amartus.com
*/
-public class DecompositionAction {
+class DecompositionAction {
private static final Logger LOG = LoggerFactory.getLogger(DecompositionAction.class);
private final List<EndPoint> endpoints;
private final DataBroker broker;
- private HashMap<Uuid, Vertex> sipToNep = new HashMap<>();
+ private final HashMap<Uuid, Vertex> sipToNep = new HashMap<>();
- public DecompositionAction(List<EndPoint> endpoints, DataBroker broker) {
+ DecompositionAction(List<EndPoint> endpoints, DataBroker broker) {
Objects.requireNonNull(endpoints);
Objects.requireNonNull(broker);
if (endpoints.size() < 2) {
List<Subrequrest> decompose() throws FailureResult {
Graph<Vertex, DefaultEdge> graph = prepareData();
- List<Vertex> vertexes = endpoints.stream().map(e -> sipToNep.get(e.getEndpoint().getServiceInterfacePoint())).collect(Collectors.toList());
+ List<Vertex> vertices = endpoints.stream().map(e -> {
+ Vertex v = sipToNep.get(e.getEndpoint().getServiceInterfacePoint());
+ if((v.dir == PortDirection.OUTPUT && e.getEndpoint().getDirection() != PortDirection.OUTPUT) ||
+ (v.dir == PortDirection.INPUT && e.getEndpoint().getDirection() != PortDirection.INPUT)) {
+ throw new IllegalArgumentException("Port direction for " + e.getEndpoint().getLocalId() + " incompatible with NEP." +
+ "CEP " + e.getEndpoint().getDirection() + " NEP " + v.dir);
+ }
+ return new Vertex(v, e.getEndpoint().getDirection());
+ }).collect(Collectors.toList());
- assert vertexes.size() > 1;
+ assert vertices.size() > 1;
- if (vertexes.size() > 2) {
- throw new IllegalStateException("currently only point to point is supported");
- }
+ Set<GraphPath<Vertex, DefaultEdge>> paths = new HashSet<>();
+
+ Set<Vertex> inV = vertices.stream().filter(isInput).collect(Collectors.toSet());
+ Set<Vertex> outV = vertices.stream().filter(isOutput).collect(Collectors.toSet());
- GraphPath<Vertex, DefaultEdge> path = DijkstraShortestPath.findPathBetween(graph, vertexes.get(0), vertexes.get(1));
+ //do the verification whether it is possible to connect two nodes.
+ inV.forEach(i ->
+ outV.stream().filter(o -> i != o).forEach(o -> {
+ GraphPath<Vertex, DefaultEdge> path = DijkstraShortestPath.findPathBetween(graph, i, o);
+ if(path != null) {
+ LOG.debug("Couldn't find path between {} and {}", i, o);
+ }
+ paths.add(path);
+ })
+ );
- if (path == null) {
+ if(paths.stream().anyMatch(Objects::isNull)) {
+ LOG.info("At least single path between endpoints not found");
return null;
}
- return path.getVertexList().stream().collect(Collectors.groupingBy(v -> v.getNodeUuid()))
- .entrySet().stream().map(e -> {
- return new Subrequrest(e.getKey(), e.getValue().stream().map(v -> toEndPoint(v)).collect(Collectors.toList()));
+ List<Subrequrest> result = paths.stream()
+ .flatMap(gp -> gp.getVertexList().stream()).collect(Collectors.groupingBy(Vertex::getNodeUuid))
+ .entrySet().stream()
+ .map(e -> {
+ Set<EndPoint> endpoints = e.getValue().stream().map(this::toEndPoint).collect(Collectors.toSet());
+ return new Subrequrest(e.getKey(), new ArrayList<>(endpoints));
}).collect(Collectors.toList());
+ return result.isEmpty() ? null : result;
}
private EndPoint toEndPoint(Vertex v) {
return ep;
}
- private void connected(Graph<Vertex, DefaultEdge> graph, List<Vertex> vertices) {
- for (int i = 0; i < vertices.size(); ++i) {
- Vertex f = vertices.get(i);
- //its OK if the vertex is added in internal loop nothing will happen
- graph.addVertex(f);
- for (int j = i + 1; j < vertices.size(); ++j) {
- Vertex t = vertices.get(j);
- graph.addVertex(t);
- graph.addEdge(f,t);
- }
- }
+ private final Predicate<Vertex> isInput = v -> v.getDir() == PortDirection.BIDIRECTIONAL|| v.getDir() == PortDirection.INPUT;
+ private final Predicate<Vertex> isOutput = v -> v.getDir() == PortDirection.BIDIRECTIONAL || v.getDir() == PortDirection.OUTPUT;
+
+ private void interconnectNode(Graph<Vertex, DefaultEdge> graph, List<Vertex> vertices) {
+ vertices.forEach(graph::addVertex);
+ Set<Vertex> inV = vertices.stream().filter(isInput).collect(Collectors.toSet());
+ Set<Vertex> outV = vertices.stream().filter(isOutput).collect(Collectors.toSet());
+ interconnect(graph, inV, outV);
+ }
+
+ private void interconnectLink(Graph<Vertex, DefaultEdge> graph, List<Vertex> vertices) {
+ vertices.forEach(graph::addVertex);
+ Set<Vertex> inV = vertices.stream().filter(isInput).collect(Collectors.toSet());
+ Set<Vertex> outV = vertices.stream().filter(isOutput).collect(Collectors.toSet());
+ interconnect(graph, outV, inV);
+
+
}
- protected Graph<Vertex, DefaultEdge> prepareData() throws FailureResult {
+ private void interconnect(Graph<Vertex, DefaultEdge> graph, Collection<Vertex> from, Collection<Vertex> to) {
+ from.forEach(iV ->
+ to.stream().filter(oV -> iV != oV).forEach(oV -> graph.addEdge(iV,oV)));
+ }
+
+
+ private Graph<Vertex, DefaultEdge> prepareData() throws FailureResult {
ReadWriteTransaction tx = broker.newReadWriteTransaction();
try {
Topology topo = new NrpDao(tx).getTopology(TapiConstants.PRESTO_SYSTEM_TOPO);
throw new FailureResult("There are no nodes in {0} topology", TapiConstants.PRESTO_SYSTEM_TOPO);
}
- Graph<Vertex, DefaultEdge> graph = new SimpleGraph<>(DefaultEdge.class);
+ Graph<Vertex, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);
+
topo.getNode().stream().map(this::nodeToGraph).forEach(vs -> {
List<Vertex> vertices = vs.collect(Collectors.toList());
vertices.forEach(v -> sipToNep.put(v.getSip(), v));
- connected(graph, vertices);
+ interconnectNode(graph, vertices);
});
if (topo.getLink() != null) {
topo.getLink().stream()
.filter(l -> l.getState() != null && OperationalState.ENABLED == l.getState().getOperationalState())
.forEach(l -> {
+ //we probably need to take link bidir/unidir into consideration as well
List<Vertex> vertices = l.getNodeEdgePoint().stream()
.map(nep -> graph.vertexSet().stream().filter(v -> v.getUuid().equals(nep)).findFirst())
.filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
- connected(graph, vertices);
+ interconnectLink(graph, vertices);
});
}
}
}
- protected Stream<Vertex> nodeToGraph(Node n) {
+ private Stream<Vertex> nodeToGraph(Node n) {
Uuid nodeUuid = n.getUuid();
- return n.getOwnedNodeEdgePoint().stream().map(nep -> {
+
+
+ return n.getOwnedNodeEdgePoint().stream()
+ .filter(ep -> ep.getLinkPortDirection() != null && ep.getLinkPortDirection() != PortDirection.UNIDENTIFIEDORUNKNOWN)
+ .map(nep -> {
List<Uuid> sips = nep.getMappedServiceInterfacePoint();
if (sips == null || sips.isEmpty()) {
- return new Vertex(nodeUuid, nep.getUuid(), null);
+ return new Vertex(nodeUuid, nep.getUuid(), null, nep.getLinkPortDirection());
}
if (sips.size() > 1) {
LOG.warn("NodeEdgePoint {} have multiple ServiceInterfacePoint mapped, selecting first one", nep.getUuid());
}
- return new Vertex(nodeUuid, nep.getUuid(), sips.get(0));
+ return new Vertex(nodeUuid, nep.getUuid(), sips.get(0), nep.getLinkPortDirection());
});
}
- public class Vertex implements Comparable<Vertex> {
+ class Vertex implements Comparable<Vertex> {
private final Uuid nodeUuid;
private final Uuid uuid;
private final Uuid sip;
+ private final PortDirection dir;
+
+ Vertex(Vertex px, PortDirection csDir) {
+ this.nodeUuid = px.nodeUuid;
+ this.uuid = px.uuid;
+ this.sip = px.sip;
+ this.dir = csDir;
+ }
- public Vertex(Uuid nodeUuid, Uuid uuid, Uuid sip) {
+ Vertex(Uuid nodeUuid, Uuid uuid, Uuid sip, PortDirection dir) {
this.sip = sip;
+ this.dir = dir;
Objects.requireNonNull(nodeUuid);
Objects.requireNonNull(uuid);
this.nodeUuid = nodeUuid;
this.uuid = uuid;
}
- public Uuid getNodeUuid() {
+ Uuid getNodeUuid() {
return nodeUuid;
}
- public Uuid getUuid() {
+ Uuid getUuid() {
return uuid;
}
- public Uuid getSip() {
+ Uuid getSip() {
return sip;
}
return Objects.equals(uuid, vertex.uuid);
}
+ PortDirection getDir() {
+ return dir;
+ }
+
@Override
public int hashCode() {
return Objects.hash(uuid);
*/
package org.opendaylight.unimgr.mef.nrp.impl;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
+import com.google.common.util.concurrent.CheckedFuture;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.unimgr.mef.nrp.api.TapiConstants;
import org.opendaylight.unimgr.mef.nrp.common.NrpDao;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Context;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.TerminationDirection;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.Context1;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePoint;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePointKey;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.Topology;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import com.google.common.base.Optional;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.*;
/**
* @author marek.ryznar@amartus.com
*/
public class AbstractNodeHandlerTest extends AbstractTestWithTopo {
- private static final InstanceIdentifier NRP_ABSTRACT_NODE_IID = InstanceIdentifier
- .create(Context.class)
- .augmentation(Context1.class)
- .child(Topology.class, new TopologyKey(new Uuid(TapiConstants.PRESTO_EXT_TOPO)))
- .child(Node.class,new NodeKey(new Uuid(TapiConstants.PRESTO_ABSTRACT_NODE)));
+
private AbstractNodeHandler abstractNodeHandler;
- private NrpDao nrpDao;
private static final String testSystemNodeName = "testSystemNode";
private static final String testNepName = "testNep";
private static final String sipPrefix = "sip:";
//given
dataBroker = getDataBroker();
- NrpInitializer nrpInitializer = new NrpInitializer(dataBroker);
- try {
- nrpInitializer.init();
- } catch (Exception e) {
- fail("Could not initialize NRP topology.");
- }
-
abstractNodeHandler = new AbstractNodeHandler(dataBroker);
abstractNodeHandler.init();
}
+ @After
+ public void tearDown() throws Exception {
+
+ abstractNodeHandler.close();
+ removeContext();
+
+ }
+
+ private void removeContext() throws Exception {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+
+ tx.delete(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
+ .create(Context.class));
+ tx.submit().get();
+ }
+
@Test
- public void testNodeAddition() {
+ public void testNodeAddition() throws TransactionCommitFailedException {
//when
- performNrpDaoAction(addNode,null);
+ performNrpDaoAction(addNode,null).checkedGet();
//then
- Node node = getAbstractNode();
- assertTrue(node.getOwnedNodeEdgePoint().containsAll(createTestOwnedNodeEdgePointList()));
+ Node node = getAbstractNodeNotNullNep();
+
+ assertEquals(
+ node.getOwnedNodeEdgePoint().stream().map(nep -> nep.getUuid().getValue()).collect(Collectors.toSet()),
+ new HashSet(Arrays.asList(testNepName+"0", testNepName+"1", testNepName+"2", testNepName+"3"))
+ );
+
}
@Test
- public void testNepAddition() {
+ public void testNepAddition() throws TransactionCommitFailedException {
//given
String newNepName = "newNep";
- performNrpDaoAction(addNode,null);
+ performNrpDaoAction(addNode,null).checkedGet();
//when
OwnedNodeEdgePoint newNep = createNep(newNepName,TerminationDirection.BIDIRECTIONAL);
- performNrpDaoAction(update, newNep);
+ performNrpDaoAction(update, newNep).checkedGet();
//then
- Node node = getAbstractNode();
+ Node node = getAbstractNode(n -> n.getOwnedNodeEdgePoint().size() == init_neps_count + 1);
+
assertTrue(node.getOwnedNodeEdgePoint().contains(newNep));
}
@Test
- public void testNepUpdate() {
+ public void testNepUpdate() throws TransactionCommitFailedException {
//given
- performNrpDaoAction(addNode,null);
+ performNrpDaoAction(addNode, null).checkedGet();
//when changing not sip related attribute
OwnedNodeEdgePoint toUpdateNep = createNep(testNepName + "1", TerminationDirection.UNDEFINEDORUNKNOWN);
- performNrpDaoAction(update, toUpdateNep);
+ performNrpDaoAction(update, toUpdateNep).checkedGet();
- Node node = getAbstractNode();
+ Node node = getAbstractNodeNotNullNep();
//There could be more neps if our node was added insted of updated
assertEquals(init_neps_count,node.getOwnedNodeEdgePoint().size());
assertTrue(node.getOwnedNodeEdgePoint().contains(toUpdateNep));
tx.submit().checkedGet();
//then
- node = getAbstractNode();
+ node = getAbstractNodeNotNullNep();
//There could be more neps if our node was added instead of updated
assertEquals(1,node.getOwnedNodeEdgePoint().size());
//given we have sips
ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
Node n1 = n(tx, true, "n1", "n1:1", "n1:2");
- tx.submit().get();
+ tx.submit().checkedGet();
//assert
- Node node = getAbstractNode();
+ Node node = getAbstractNodeNotNullNep();
assertEquals(2,node.getOwnedNodeEdgePoint().size());
//when
new NrpDao(tx).updateNep("n1", n11);
tx.submit().checkedGet();
- //then
- node = getAbstractNode();
- //a nep was removed
- assertEquals(1,node.getOwnedNodeEdgePoint().size());
-
+ //then a nep was removed
+ getAbstractNode(n -> n.getOwnedNodeEdgePoint().size() == 1);
}
@Test
- public void testNodeRemoval() {
+ public void testNodeRemoval() throws TransactionCommitFailedException {
//given
- performNrpDaoAction(addNode,null);
+ performNrpDaoAction(addNode,null).checkedGet();
//when
- performNrpDaoAction(removeNode,null);
+ performNrpDaoAction(removeNode,null).checkedGet();
//then
- Node node = getAbstractNode();
- assertEquals(0,node.getOwnedNodeEdgePoint().size());
+ Node node = getAbstractNode(n -> n.getOwnedNodeEdgePoint() != null && n.getOwnedNodeEdgePoint().isEmpty());
+ assertTrue(node.getOwnedNodeEdgePoint().isEmpty());
}
@Test
- public void testNepRemoval() {
+ public void testNepRemoval() throws TransactionCommitFailedException {
//given
- performNrpDaoAction(addNode,null);
+ performNrpDaoAction(addNode,null).checkedGet();
String nepNameToRemove = testNepName + "0";
//when
- performNrpDaoAction(removeNep,nepNameToRemove);
+ performNrpDaoAction(removeNep,nepNameToRemove).checkedGet();
//then
- Node node = getAbstractNode();
- assertEquals(init_neps_count - 1, node.getOwnedNodeEdgePoint().size());
+ Node node = getAbstractNode(n -> n.getOwnedNodeEdgePoint().size() == init_neps_count - 1);
+
assertFalse(node.getOwnedNodeEdgePoint().stream()
.anyMatch(nep -> nep.getUuid().getValue().equals(nepNameToRemove)));
}
- BiConsumer<NrpDao,String> removeNep = (dao,nepId) -> dao.removeNep(testSystemNodeName,nepId,false);
- BiConsumer<NrpDao,String> removeNode = (dao,nepId) -> dao.removeNode(testSystemNodeName,false);
- BiConsumer<NrpDao,String> addNode = (dao,nepId) -> dao.createSystemNode(testSystemNodeName,createTestOwnedNodeEdgePointList());
- BiConsumer<NrpDao,OwnedNodeEdgePoint> update = (dao,nep) -> dao.updateNep(testSystemNodeName,nep);
+ private BiConsumer<NrpDao,String> removeNep = (dao, nepId) -> dao.removeNep(testSystemNodeName,nepId,false);
+ private BiConsumer<NrpDao,String> removeNode = (dao, nepId) -> dao.removeNode(testSystemNodeName,false);
+ private BiConsumer<NrpDao,String> addNode = (dao, nepId) -> dao.createSystemNode(testSystemNodeName,createTestOwnedNodeEdgePointList());
+ private BiConsumer<NrpDao,OwnedNodeEdgePoint> update = (dao, nep) -> dao.updateNep(testSystemNodeName,nep);
- private <T extends Object> void performNrpDaoAction(BiConsumer<NrpDao,T> action, T attr) {
+ private <T extends Object> CheckedFuture<Void, TransactionCommitFailedException> performNrpDaoAction(BiConsumer<NrpDao,T> action, T attr) {
ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
- nrpDao = new NrpDao(tx);
+ NrpDao nrpDao = new NrpDao(tx);
action.accept(nrpDao,attr);
- tx.submit();
+ return tx.submit();
}
private List<OwnedNodeEdgePoint> createTestOwnedNodeEdgePointList() {
// TODO donaldh .setTerminationDirection(td);
if (associateSip) {
- builder.setMappedServiceInterfacePoint(Arrays.asList(new Uuid(sipPrefix + nepName)));
+ builder.setMappedServiceInterfacePoint(Collections.singletonList(new Uuid(sipPrefix + nepName)));
}
return builder.build();
}
- private Node getAbstractNode() {
- ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction();
- try {
- Optional<Node> opt =
- (Optional<Node>) tx.read(LogicalDatastoreType.OPERATIONAL,NRP_ABSTRACT_NODE_IID).checkedGet();
- if (opt.isPresent()) {
- return opt.get();
- } else {
- return null;
- }
- } catch (Exception e) {
- fail(e.getMessage());
- }
- return null;
+
+ private Node getAbstractNodeNotNullNep() {
+
+ return getAbstractNode(n -> n.getOwnedNodeEdgePoint() != null);
}
}
package org.opendaylight.unimgr.mef.nrp.impl;
+import static org.junit.Assert.fail;
import static org.opendaylight.unimgr.mef.nrp.api.TapiConstants.PRESTO_SYSTEM_TOPO;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import com.google.common.base.Optional;
import org.junit.Before;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.unimgr.mef.nrp.api.EndPoint;
+import org.opendaylight.unimgr.mef.nrp.api.TapiConstants;
import org.opendaylight.unimgr.mef.nrp.common.NrpDao;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.ETH;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.ForwardingDirection;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.OperationalState;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.*;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.ConnectivityServiceEndPoint;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.create.connectivity.service.input.EndPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.Context1;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.link.StateBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.node.OwnedNodeEdgePointBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.Link;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.LinkBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.LinkKey;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.Node;
-
-import com.google.common.base.Optional;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.*;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.*;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.topology.rev171113.topology.context.TopologyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
* @author bartosz.michalik@amartus.com
*/
-public abstract class AbstractTestWithTopo extends AbstractDataBrokerTest {
-
+public abstract class AbstractTestWithTopo extends AbstractConcurrentDataBrokerTest {
+ protected static final InstanceIdentifier<Node> NRP_ABSTRACT_NODE_IID = InstanceIdentifier
+ .create(Context.class)
+ .augmentation(Context1.class)
+ .child(Topology.class, new TopologyKey(new Uuid(TapiConstants.PRESTO_EXT_TOPO)))
+ .child(Node.class,new NodeKey(new Uuid(TapiConstants.PRESTO_ABSTRACT_NODE)));
protected DataBroker dataBroker;
new NrpInitializer(dataBroker).init();
}
- protected EndPoint ep(String nepId) {
+ protected EndPoint ep(String nepId) {
+ return ep(nepId, PortDirection.BIDIRECTIONAL);
+ }
+
+ protected EndPoint ep(String nepId, PortDirection pd) {
ConnectivityServiceEndPoint ep = new EndPointBuilder()
.setLocalId("ep_" + nepId)
+ .setDirection(pd)
.setServiceInterfacePoint(new Uuid("sip:" + nepId))
.build();
}
protected void l(ReadWriteTransaction tx, String nA, String nepA, String nB, String nepB, OperationalState state) {
+ l(tx, nA, nepA, nB, nepB, state, ForwardingDirection.BIDIRECTIONAL);
+ }
+
+ protected void l(ReadWriteTransaction tx, String nA, String nepA, String nB, String nepB, OperationalState state, ForwardingDirection dir) {
Uuid uuid = new Uuid(nepA + "-" + nepB);
+
+ NrpDao dao = new NrpDao(tx);
+
+ if(dao.hasSip(nepA)) {
+ dao.removeSip(new Uuid("sip:" + nepA));
+ }
+
+ if(dao.hasSip(nepB)) {
+ dao.removeSip(new Uuid("sip:" + nepB));
+ }
+
Link link = new LinkBuilder()
.setUuid(uuid)
.setKey(new LinkKey(uuid))
- .setDirection(ForwardingDirection.BIDIRECTIONAL)
+ .setDirection(dir)
.setLayerProtocolName(Collections.singletonList(ETH.class))
.setNode(toIds(nA, nB).collect(Collectors.toList()))
.setNodeEdgePoint(toIds(nepA, nepB).collect(Collectors.toList()))
}
protected Node n(ReadWriteTransaction tx, boolean addSips, String node, String ... endpoints) {
+ return n(tx, addSips, node, Arrays.stream(endpoints).map(i -> new Pair(i, PortDirection.BIDIRECTIONAL)));
+ }
+
+ protected Node n(ReadWriteTransaction tx, boolean addSips, String node, Stream<Pair> endpoints) {
+ List<Pair> eps = endpoints.collect(Collectors.toList());
NrpDao nrpDao = new NrpDao(tx);
if (addSips) {
- Arrays.stream(endpoints).map(e -> new ServiceInterfacePointBuilder()
- .setUuid(new Uuid("sip:" + e))
- .build())
- .forEach(nrpDao::addSip);
+ eps.stream().map(e -> new ServiceInterfacePointBuilder()
+ .setUuid(new Uuid("sip:" + e.getId()))
+ .build())
+ .forEach(nrpDao::addSip);
}
- return nrpDao.createSystemNode(node, Arrays.stream(endpoints)
+ return nrpDao.createSystemNode(node, eps.stream()
.map(e-> {
- OwnedNodeEdgePointBuilder builder = new OwnedNodeEdgePointBuilder().setUuid(new Uuid(e));
+ OwnedNodeEdgePointBuilder builder = new OwnedNodeEdgePointBuilder()
+ .setLinkPortDirection(e.getDir())
+ .setUuid(new Uuid(e.getId()));
if (addSips) {
- builder.setMappedServiceInterfacePoint(Collections.singletonList(new Uuid("sip:" + e)));
+ builder.setMappedServiceInterfacePoint(Collections.singletonList(new Uuid("sip:" + e.getId())));
}
return builder.build();
}).collect(Collectors.toList()));
}
+ protected Node getAbstractNode() {
+
+ try(ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
+ Optional<Node> opt = tx.read(LogicalDatastoreType.OPERATIONAL,NRP_ABSTRACT_NODE_IID).checkedGet();
+ if (opt.isPresent()) {
+ return opt.get();
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ return null;
+ }
+
+
+ protected Node getAbstractNode(Predicate<Node> nodePredicate) {
+
+ for(int i = 0; i < 5; ++i) {
+ Node node = getAbstractNode();
+ if(node != null && nodePredicate.test(node)) {
+ return node;
+ }
+ try {
+ TimeUnit.MILLISECONDS.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ throw new IllegalStateException("No NEPs matching predicate");
+ }
+
+
+
+ protected static class Pair {
+ private String id;
+ private PortDirection dir;
+
+ public Pair(String id, PortDirection dir) {
+ this.id = id;
+ this.dir = dir;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public PortDirection getDir() {
+ return dir;
+ }
+ }
+
protected Node n(ReadWriteTransaction tx, String node, String ... endpoints) {
return n(tx,true, node, endpoints);
}
package org.opendaylight.unimgr.mef.nrp.impl.connectivityservice;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.unimgr.mef.nrp.impl.ConnectivityServiceIdResourcePool;
import org.opendaylight.unimgr.mef.nrp.impl.decomposer.BasicDecomposer;
import org.opendaylight.unimgr.utils.ActivationDriverMocks;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortDirection;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortRole;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.TerminationDirection;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.Context1;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.connectivity.rev171113.CreateConnectivityServiceInput;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
+
/**
* @author bartosz.michalik@amartus.com
*/
return Arrays.stream(uuids).map(uuid -> new EndPointBuilder()
.setLocalId("e:" + uuid)
.setRole(PortRole.SYMMETRIC)
+ .setDirection(PortDirection.BIDIRECTIONAL)
.setServiceInterfacePoint(new Uuid("sip:" + uuid))
.build()).collect(Collectors.toList());
}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.unimgr.mef.nrp.impl.decomposer;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.unimgr.mef.nrp.api.FailureResult;
+import org.opendaylight.unimgr.mef.nrp.api.Subrequrest;
+import org.opendaylight.unimgr.mef.nrp.impl.AbstractTestWithTopo;
+import org.opendaylight.unimgr.mef.nrp.impl.NrpInitializer;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.ForwardingDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.OperationalState;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.PortDirection;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author bartosz.michalik@amartus.com
+ */
+public class BasicDecomposerForDirectedTopologyTest extends AbstractTestWithTopo {
+
+ private BasicDecomposer decomposer;
+
+ @Before
+ public void setUp() throws Exception {
+ dataBroker = getDataBroker();
+ new NrpInitializer(dataBroker).init();
+ decomposer = new BasicDecomposer(dataBroker);
+
+ }
+
+ @Rule
+ public ExpectedException expected = ExpectedException.none();
+
+ @Test
+ public void twoNodesTestDirection() throws FailureResult, OperationFailedException {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, true, "n1", Stream.of(pI("n1:1"), pO("n1:2")));
+ n(tx, true, "n2", Stream.of(pO("n2:1"), pI("n2:2")));
+ n(tx, true, "n3", Stream.of(pI("n3:1")));
+ l(tx, "n1", "n1:1", "n2", "n2:1", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ tx.submit().checkedGet();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:2", PortDirection.OUTPUT), ep("n2:2", PortDirection.INPUT)), null);
+ assertNotNull(decomposed);
+ assertEquals(2, decomposed.size());
+ }
+
+ @Test
+ public void threeNodesTestAll() throws FailureResult, OperationFailedException {
+ //having
+ threeNodesTopo();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:2", PortDirection.OUTPUT), ep("n3:3", PortDirection.INPUT)), null);
+ assertNotNull(decomposed);
+ assertEquals(3, decomposed.size());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void threeNodesTestIncompatible() throws FailureResult, OperationFailedException {
+ //having
+ threeNodesTopo();
+ //when
+ decomposer.decompose(Arrays.asList(ep("n1:2", PortDirection.INPUT), ep("n3:3", PortDirection.OUTPUT)), null);
+ fail();
+ }
+
+ @Test
+ public void fourNodesTestThreeSelected() throws FailureResult, OperationFailedException {
+ //having
+ fourNodesTopo();
+
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n2:2"), ep("n3:2")), null);
+ assertNotNull(decomposed);
+ assertEquals(3, decomposed.size());
+ }
+
+
+ @Test
+ public void fourNodesTestNone() throws FailureResult, OperationFailedException {
+ //having
+ fourNodesTopo();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n2:1", PortDirection.INPUT), ep("n1:1")), null);
+ assertNull(decomposed);
+
+ }
+
+ @Test
+ public void fourTestPartialPath() throws FailureResult {
+ //having
+ fourNodesTopo();
+
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:1", PortDirection.OUTPUT), ep("n2:1"), ep("n4:1")), null);
+ assertNull(decomposed);
+ }
+
+ @Test
+ public void fourTestSingleSink() throws FailureResult {
+ //having
+ fourNodesTopo();
+
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:1", PortDirection.INPUT), ep("n2:1", PortDirection.INPUT), ep("n4:1", PortDirection.OUTPUT)),
+ null);
+ assertNotNull(decomposed);
+ }
+
+
+
+ @Test
+ public void fiveNodesTestAll() throws FailureResult, OperationFailedException {
+ //having
+ fiveNodesTopo();
+
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:2"), ep("n5:3")), null);
+ assertNotNull(decomposed);
+ assertEquals(5, decomposed.size());
+ }
+
+ @Test
+ public void fiveNodesTestDirected() throws FailureResult {
+ //having
+ fiveNodesTopo();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:2", PortDirection.OUTPUT), ep("n5:3", PortDirection.INPUT)), null);
+ assertNotNull(decomposed);
+ assertEquals(3, decomposed.size());
+ }
+
+
+ /*
+
+ n2--(1)-->--(3)--n1
+ n3--(1)-->--(2)--n2
+
+ */
+ private void threeNodesTopo() {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, true, "n1", Stream.of(pI("n1:1"), pO("n1:2"), pI("n1:3")));
+ n(tx, true, "n2", Stream.of(pO("n2:1"), pI("n2:2")));
+ n(tx, true, "n3", Stream.of(pO("n3:1"), pO("n3:2"), pI("n3:3")));
+ l(tx, "n1", "n1:3", "n2", "n2:1", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n2", "n2:2", "n3", "n3:1", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ try {
+ tx.submit().checkedGet();
+ } catch (TransactionCommitFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /*
+
+ n1--(5)-->--(5)--n2
+ n1--(4)-->--(4)--n4
+ n2--(3)-->--(3)--n4
+ n3--(3)-->--(4)--n2
+ n4--(5)-->--(5)--n3
+
+ */
+ private void fourNodesTopo() {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, true, "n1", Stream.of(pB("n1:1"), pB("n1:2"), pI("n1:3"), pO("n1:4"), pO("n1:5")));
+ n(tx, true, "n2", Stream.of(pB("n2:1"), pB("n2:2"), pO("n2:3"), pI("n2:4"), pI("n2:5")));
+ n(tx, true, "n3", Stream.of(pB("n3:1"), pB("n3:2"), pO("n3:3"), pO("n3:4"), pI("n3:5")));
+ n(tx, true, "n4", Stream.of(pB("n4:1"), pB("n4:2"), pI("n4:3"), pI("n4:4"), pO("n4:5")));
+ l(tx, "n1", "n1:5", "n2", "n2:5", OperationalState.ENABLED, ForwardingDirection.UNIDIRECTIONAL);
+ l(tx, "n1", "n1:4", "n4", "n4:4", OperationalState.ENABLED, ForwardingDirection.UNIDIRECTIONAL);
+ l(tx, "n2", "n2:3", "n4", "n4:3", OperationalState.ENABLED, ForwardingDirection.UNIDIRECTIONAL);
+ l(tx, "n3", "n3:4", "n2", "n2:4", OperationalState.ENABLED, ForwardingDirection.UNIDIRECTIONAL);
+ l(tx, "n4", "n4:5", "n3", "n3:5", OperationalState.ENABLED, ForwardingDirection.UNIDIRECTIONAL);
+ try {
+ tx.submit().checkedGet();
+ } catch (TransactionCommitFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /*
+
+ n1--(4)-->--(4)--n2
+ n1--(3)-->--(1)--n4
+ n2--(3)-->--(4)--n3
+ n3--(1)-->--(1)--n1
+ n3--(3)-->--(1)--n5
+ n5--(4)-->--(2)--n4
+
+ */
+ private void fiveNodesTopo() {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, true, "n1", Stream.of(pI("n1:1"), pB("n1:2"), pI("n1:3"), pO("n1:4")));
+ n(tx, true, "n2", Stream.of(pI("n2:1"), pB("n2:2"), pO("n2:3"), pI("n2:4")));
+ n(tx, true, "n3", Stream.of(pO("n3:1"), pB("n3:2"), pO("n3:3"), pI("n3:4")));
+ n(tx, true, "n4", Stream.of(pO("n4:1"), pI("n4:2"), pB("n4:3"), pB("n4:4")));
+ n(tx, true, "n5", Stream.of(pI("n5:1"), pB("n5:2"), pB("n5:3"), pO("n5:4")));
+ l(tx, "n2", "n2:3", "n3", "n3:4", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n3", "n3:1", "n1", "n1:1", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n3", "n3:3", "n5", "n5:1", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n4", "n4:1", "n1", "n1:3", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n1", "n1:4", "n2", "n2:4", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ l(tx, "n5", "n5:4", "n4", "n4:2", OperationalState.ENABLED, ForwardingDirection.BIDIRECTIONAL);
+ try {
+ tx.submit().checkedGet();
+ } catch (TransactionCommitFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private AbstractTestWithTopo.Pair pO(String id) {
+ return new Pair(id, PortDirection.OUTPUT);
+ }
+
+ private AbstractTestWithTopo.Pair pI(String id) {
+ return new Pair(id, PortDirection.INPUT);
+ }
+
+ private AbstractTestWithTopo.Pair pB(String id) {
+ return new Pair(id, PortDirection.BIDIRECTIONAL);
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.unimgr.mef.nrp.impl.decomposer;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.unimgr.mef.nrp.api.FailureResult;
+import org.opendaylight.unimgr.mef.nrp.api.Subrequrest;
+import org.opendaylight.unimgr.mef.nrp.impl.AbstractTestWithTopo;
+import org.opendaylight.unimgr.mef.nrp.impl.NrpInitializer;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.OperationalState;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+/**
+ * @author bartosz.michalik@amartus.com
+ */
+public class BasicDecomposerMultipointTest extends AbstractTestWithTopo {
+ private BasicDecomposer decomposer;
+
+ @Before
+ public void setUp() throws Exception {
+ dataBroker = getDataBroker();
+ new NrpInitializer(dataBroker).init();
+ decomposer = new BasicDecomposer(dataBroker);
+
+ }
+
+ @Rule
+ public ExpectedException expected = ExpectedException.none();
+
+ @Test
+ public void singleNodeTest() throws FailureResult, OperationFailedException {
+ //having
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, "n1", "n1:1", "n1:2", "n1:3", "n1:4");
+ n(tx, "n2", "n2:1", "n2:2", "n2:3", "n2:4");
+ tx.submit().checkedGet();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:1"), ep("n1:2"), ep("n1:4")), null);
+
+ assertEquals(1, decomposed.size());
+ }
+
+ @Test
+ public void twoConnectedNodesTest() throws FailureResult, OperationFailedException {
+ //having
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, "n1", "n1:1", "n1:2", "n1:3","n1:4");
+ n(tx, "n2", "n2:1", "n2:2", "n2:3","n2:4");
+ n(tx, "n3", "n3:1", "n3:2", "n3:3","n3:4");
+ l(tx, "n1", "n1:1", "n2", "n2:1", OperationalState.ENABLED);
+ l(tx, "n2", "n2:3", "n3", "n3:3", OperationalState.ENABLED);
+ tx.submit().checkedGet();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:2"), ep("n2:2"), ep("n2:3")), null);
+ assertNotNull(decomposed);
+ assertEquals(2, decomposed.size());
+ assertEquals(Stream.of(2,3).collect(Collectors.toSet()), decomposed.stream().map(s -> s.getEndpoints().size()).collect(Collectors.toSet()));
+
+ }
+
+ @Test
+ public void fourNodesTopology() throws FailureResult, OperationFailedException {
+ //having
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ n(tx, "n1", "n1:1", "n1:2", "n1:3", "n1:4");
+ n(tx, "n2", "n2:1", "n2:2", "n2:3");
+ n(tx, "n3", "n3:1", "n3:2", "n3:3");
+ n(tx, "n3", "n3:1", "n3:2", "n3:3");
+ l(tx, "n1", "n1:1", "n2", "n2:1", OperationalState.ENABLED);
+ l(tx, "n1", "n1:2", "n3", "n3:2", OperationalState.ENABLED);
+ l(tx, "n4", "n4:1", "n3", "n3:1", OperationalState.ENABLED);
+ l(tx, "n4", "n4:2", "n2", "n2:2", OperationalState.ENABLED);
+
+ tx.submit().checkedGet();
+ //when
+ List<Subrequrest> decomposed = decomposer.decompose(Arrays.asList(ep("n1:3"), ep("n1:4"), ep("n2:3")), null);
+ assertNotNull(decomposed);
+ assertEquals(2, decomposed.size());
+ assertEquals(Stream.of(2,3).collect(Collectors.toSet()), decomposed.stream().map(s -> s.getEndpoints().size()).collect(Collectors.toSet()));
+ List<String> uuids = decomposed.stream().map(s -> s.getNodeUuid().getValue()).collect(Collectors.toList());
+ Assert.assertThat(uuids, CoreMatchers.not(CoreMatchers.hasItems("n3", "n4")));
+ }
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.unimgr.mef.nrp.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.Arrays;
-import java.util.List;
+package org.opendaylight.unimgr.mef.nrp.impl.decomposer;
import org.junit.Before;
import org.junit.Rule;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.unimgr.mef.nrp.api.FailureResult;
import org.opendaylight.unimgr.mef.nrp.api.Subrequrest;
-import org.opendaylight.unimgr.mef.nrp.impl.decomposer.BasicDecomposer;
+import org.opendaylight.unimgr.mef.nrp.impl.AbstractTestWithTopo;
+import org.opendaylight.unimgr.mef.nrp.impl.NrpInitializer;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.OperationalState;
import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
/**
* @author bartosz.michalik@amartus.com
*/
@Test
public void twoNodesTest() throws FailureResult, OperationFailedException {
- //having
+ //having three nodes, but only two nodes connected
ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
n(tx, "n1", "n1:1", "n1:2", "n1:3");
n(tx, "n2", "n2:1", "n2:2", "n2:3");
*/
@Override
public void activate(List<EndPoint> endPoints, String serviceName) throws ResourceNotAvailableException, TransactionCommitFailedException {
- for (EndPoint endPoint:endPoints)
+ for (EndPoint endPoint:endPoints) {
activateEndpoint(endPoint, serviceName);
+ }
+
}
.map(link -> ovsActivatorHelper.getTpNameFromOpenFlowPortName(link.getLinkId().getValue()))
.collect(Collectors.toList());
- //Create egress qos
- OvsdbUtils.createEgressQos(dataBroker, portName, outputPortNames, ovsActivatorHelper.getQosMinRate(),
- ovsActivatorHelper.getQosMaxRate(), serviceName, queueNumber);
+ if(ovsActivatorHelper.isIBwpConfigured()) {
+ //Create egress qos
+ OvsdbUtils.createEgressQos(dataBroker, portName, outputPortNames, ovsActivatorHelper.getQosMinRate(),
+ ovsActivatorHelper.getQosMaxRate(), serviceName, queueNumber);
+ }
+
+
}
- @Override
+ @Override
public void deactivate(List<EndPoint> endPoints, String serviceName) throws TransactionCommitFailedException, ResourceNotAvailableException {
- for (EndPoint endPoint:endPoints)
- deactivateEndpoint(endPoint, serviceName);
+
+ for (EndPoint endPoint:endPoints) {
+ deactivateEndpoint(endPoint, serviceName);
+ }
}
private void deactivateEndpoint(EndPoint endPoint, String serviceName) throws ResourceNotAvailableException, TransactionCommitFailedException {
}
public long getQosMinRate() throws ResourceNotAvailableException {
- if ( (endPoint.getAttrs() != null) && (endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource() != null) ) {
- NrpCarrierEthConnectivityEndPointResource attr = endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource();
- IngressBwpFlow ingressBwpFlow = attr.getIngressBwpFlow();
- if(ingressBwpFlow != null) {
- //TODO add validation
- return ingressBwpFlow.getCir().getValue();
- } else {
- LOG.warn(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
- throw new ResourceNotAvailableException(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
- }
- }
- return 0;
+ IngressBwpFlow ingressBwpFlow = getIngressBwpFlow();
+ if(ingressBwpFlow != null) {
+ //TODO add validation
+ return ingressBwpFlow.getCir().getValue();
+ }
+
+ LOG.warn(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
+ throw new ResourceNotAvailableException(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
+
}
public long getQosMaxRate() throws ResourceNotAvailableException {
- if ( (endPoint.getAttrs() != null) && (endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource() != null) ) {
- NrpCarrierEthConnectivityEndPointResource attr = endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource();
- IngressBwpFlow ingressBwpFlow = attr.getIngressBwpFlow();
- if(ingressBwpFlow != null) {
- //TODO add validation
- return ingressBwpFlow.getCir().getValue() + ingressBwpFlow.getEir().getValue();
- } else {
- LOG.warn(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
- throw new ResourceNotAvailableException(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
- }
- }
- return 0;
+
+ IngressBwpFlow ingressBwpFlow = getIngressBwpFlow();
+ if(ingressBwpFlow != null) {
+ //TODO add validation
+ return ingressBwpFlow.getCir().getValue() + ingressBwpFlow.getEir().getValue();
+ }
+
+ LOG.warn(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
+ throw new ResourceNotAvailableException(String.format(INGRESS_BWP_FLOW_NOT_SET_ERROR_MESSAGE, tpName));
}
+
+ private IngressBwpFlow getIngressBwpFlow() {
+ if ( (endPoint.getAttrs() == null) || (endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource() == null) )
+ return null;
+ return endPoint.getAttrs().getNrpCarrierEthConnectivityEndPointResource().getIngressBwpFlow();
+ }
+
+ protected boolean isIBwpConfigured() {
+ return getIngressBwpFlow() != null;
+ }
}
import org.opendaylight.unimgr.mef.nrp.common.ResourceNotAvailableException;
import org.opendaylight.unimgr.mef.nrp.ovs.transaction.TopologyTransaction;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.LifecycleState;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.TerminationDirection;
-import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.*;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePoint;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.context.attrs.ServiceInterfacePointKey;
return new OwnedNodeEdgePointBuilder()
.setUuid(uuid)
.setKey(new OwnedNodeEdgePointKey(uuid))
+ .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
+ .setLinkPortRole(PortRole.SYMMETRIC)
.setMappedServiceInterfacePoint(Collections.singletonList(sipUuid))
.build();
}
.setUuid(uuid)
.setKey(new ServiceInterfacePointKey(uuid))
.setState(new StateBuilder().setLifecycleState(LifecycleState.INSTALLED).build())
-// TODO donaldh .setDirection(TerminationDirection.Bidirectional)
.build();
}
import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder;
import org.opendaylight.unimgr.mef.nrp.api.EndPoint;
import org.opendaylight.unimgr.mef.nrp.common.ResourceActivatorException;
+import org.opendaylight.unimgr.mef.nrp.template.TemplateConstants;
import org.opendaylight.yang.gen.v1.urn.mef.yang.nrp._interface.rev171221.NrpConnectivityServiceAttrs;
import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.tapi.common.rev171113.Uuid;
import org.slf4j.Logger;
@Override
public void deactivate() throws TransactionCommitFailedException, ResourceActivatorException {
// method can fail if you wish
- LOG.info("adectivate was triggered for {}", serviceId);
+ LOG.info("dectivate was triggered for {}", serviceId);
+ }
+
+ @Override
+ public void update() throws TransactionCommitFailedException, ResourceActivatorException {
+ LOG.info("update was triggered for {}", serviceId);
}
@Override
@Override
public Uuid getNodeUuid() {
- return null;
+ return new Uuid(TemplateConstants.DRIVER_ID);
}
}
//add sip for one of these endpoints
//create sid and add it to model
- ServiceInterfacePoint someSid = createSomeSid("some-sid-id");
- nrpDao.addSip(someSid);
+ ServiceInterfacePoint someSip1 = createSomeSid("some-sip-1");
+ ServiceInterfacePoint someSip2 = createSomeSid("some-sip-2");
+ nrpDao.addSip(someSip1);
+ nrpDao.addSip(someSip2);
+
+ //update an existing nep with mapping to sip
+ OwnedNodeEdgePoint updatedNep1 = new OwnedNodeEdgePointBuilder(someEndpoints.get(1))
+ .setMappedServiceInterfacePoint(Collections.singletonList(someSip1.getUuid()))
+ .build();
- //update an existing nep wit mapping to sip
- OwnedNodeEdgePoint updatedNep = new OwnedNodeEdgePointBuilder(someEndpoints.get(1))
- .setMappedServiceInterfacePoint(Collections.singletonList(someSid.getUuid()))
+ OwnedNodeEdgePoint updatedNep2 = new OwnedNodeEdgePointBuilder(someEndpoints.get(2))
+ .setMappedServiceInterfacePoint(Collections.singletonList(someSip2.getUuid()))
.build();
- nrpDao.updateNep(TemplateConstants.DRIVER_ID, updatedNep);
+ nrpDao.updateNep(TemplateConstants.DRIVER_ID, updatedNep1);
+ nrpDao.updateNep(TemplateConstants.DRIVER_ID, updatedNep2);
tx.submit().checkedGet();