Priyanka B
Committed by Priyankab-Huawei

[ONOS] Cherry picked from master 1.7

Change-Id: I74a0c1634f9c425af2bcb646edc3d9170b3c087c
Showing 73 changed files with 5086 additions and 757 deletions
......@@ -22,6 +22,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pce</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-pce</artifactId>
<packaging>bundle</packaging>
......
......@@ -26,6 +26,12 @@ import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
......@@ -35,6 +41,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TCP;
import org.onlab.util.Bandwidth;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
......@@ -52,6 +59,7 @@ import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.Device;
......@@ -63,6 +71,7 @@ import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
......@@ -76,6 +85,9 @@ import org.onosproject.net.resource.Resources;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pcestore.PcePathInfo;
import org.onosproject.pce.pcestore.PceccTunnelInfo;
......@@ -131,6 +143,7 @@ public class PceManager implements PceService {
private static final String TRUE = "true";
private static final String FALSE = "false";
private static final String END_OF_SYNC_IP_PREFIX = "0.0.0.0/32";
public static final int PCEP_PORT = 4189;
private IdGenerator localLspIdIdGen;
protected DistributedSet<Short> localLspIdFreeList;
......@@ -171,12 +184,23 @@ public class PceManager implements PceService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowObjectiveService flowObjectiveService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
private TunnelListener listener = new InnerTunnelListener();
private BasicPceccHandler crHandler;
private PceccSrTeBeHandler srTeHandler;
private ApplicationId appId;
private final PcepPacketProcessor processor = new PcepPacketProcessor();
private final TopologyListener topologyListener = new InternalTopologyListener();
private ScheduledExecutorService executor;
public static final int INITIAL_DELAY = 30;
public static final int PERIODIC_DELAY = 30;
/**
* Creates new instance of PceManager.
......@@ -204,6 +228,10 @@ public class PceManager implements PceService {
.asDistributedSet();
packetService.addProcessor(processor, PacketProcessor.director(4));
topologyService.addListener(topologyListener);
executor = Executors.newSingleThreadScheduledExecutor();
//Start a timer when the component is up, with initial delay of 30min and periodic delays at 30min
executor.scheduleAtFixedRate(new GlobalOptimizationTimer(), INITIAL_DELAY, PERIODIC_DELAY, TimeUnit.MINUTES);
log.info("Started");
}
......@@ -211,6 +239,9 @@ public class PceManager implements PceService {
protected void deactivate() {
tunnelService.removeListener(listener);
packetService.removeProcessor(processor);
topologyService.removeListener(topologyListener);
//Shutdown the thread when component is deactivated
executor.shutdown();
log.info("Stopped");
}
......@@ -395,6 +426,7 @@ public class PceManager implements PceService {
List<Link> links = tunnel.path().links();
String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE);
double bwConstraintValue = 0;
String costType = null;
SharedBandwidthConstraint shBwConstraint = null;
BandwidthConstraint bwConstraint = null;
CostConstraint costConstraint = null;
......@@ -409,6 +441,7 @@ public class PceManager implements PceService {
bwConstraintValue = bwConstraint.bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
costType = costConstraint.type().name();
}
}
......@@ -454,6 +487,9 @@ public class PceManager implements PceService {
Builder annotationBuilder = DefaultAnnotations.builder();
annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
if (costType != null) {
annotationBuilder.set(COST_TYPE, costType);
}
annotationBuilder.set(LSP_SIG_TYPE, lspSigType);
annotationBuilder.set(PCE_INIT, TRUE);
annotationBuilder.set(DELEGATE, TRUE);
......@@ -594,8 +630,66 @@ public class PceManager implements PceService {
}
}
//TODO: annotations used for temporarily later projection/network config will be used
private class InternalTopologyListener implements TopologyListener {
@Override
public void event(TopologyEvent event) {
event.reasons().forEach(e -> {
//If event type is link removed, get the impacted tunnel
if (e instanceof LinkEvent) {
LinkEvent linkEvent = (LinkEvent) e;
if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) {
tunnelService.queryTunnel(MPLS).forEach(t -> {
if (t.path().links().contains((e.subject()))) {
// Check whether this ONOS instance is master for ingress device if yes,
// recompute and send update
checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
}
});
}
}
});
}
}
// Allocates the bandwidth locally for PCECC tunnels.
private boolean checkForMasterAndUpdateTunnel(DeviceId src, Tunnel tunnel) {
/**
* Master of ingress node will recompute and also delegation flag must be set.
*/
if (mastershipService.isLocalMaster(src)
&& Boolean.valueOf(tunnel.annotations().value(DELEGATE)) != null) {
LinkedList<Constraint> constraintList = new LinkedList<>();
if (tunnel.annotations().value(BANDWIDTH) != null) {
//Requested bandwidth will be same as previous allocated bandwidth for the tunnel
BandwidthConstraint localConst = new BandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
.annotations().value(BANDWIDTH))));
constraintList.add(localConst);
}
if (tunnel.annotations().value(COST_TYPE) != null) {
constraintList.add(CostConstraint.of(CostConstraint.Type.valueOf(tunnel.annotations().value(
COST_TYPE))));
}
/*
* If tunnel was UP after recomputation failed then store failed path in PCE store send PCIntiate(remove)
* and If tunnel is failed and computation fails nothing to do because tunnel status will be same[Failed]
*/
if (!updatePath(tunnel.tunnelId(), constraintList) && !tunnel.state().equals(Tunnel.State.FAILED)) {
// If updation fails store in PCE store as failed path
// then PCInitiate (Remove)
pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
.path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
//Release that tunnel calling PCInitiate
releasePath(tunnel.tunnelId());
}
}
return false;
}
// Allocates the bandwidth locally for PCECC tunnels.
private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint,
SharedBandwidthConstraint shBwConstraint) {
checkNotNull(computedPath);
......@@ -860,14 +954,72 @@ public class PceManager implements PceService {
public void process(PacketContext context) {
// Stop processing if the packet has been handled, since we
// can't do any more to it.
if (context.isHandled()) {
return;
}
InboundPacket pkt = context.inPacket();
if (pkt == null) {
return;
}
Ethernet ethernet = pkt.parsed();
if (ethernet == null || ethernet.getEtherType() != Ethernet.TYPE_IPV4) {
return;
}
IPv4 ipPacket = (IPv4) ethernet.getPayload();
if (ipPacket == null || ipPacket.getProtocol() != IPv4.PROTOCOL_TCP) {
return;
}
TCP tcp = (TCP) ipPacket.getPayload();
if (tcp == null || tcp.getDestinationPort() != PCEP_PORT) {
return;
}
syncLabelDb(pkt.receivedFrom().deviceId());
}
}
//Computes path from tunnel store and also path failed to setup.
private void callForOptimization() {
//Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]
for (PcePathInfo failedPathInfo : pceStore.getFailedPathInfos()) {
checkForMasterAndSetupPath(failedPathInfo);
}
//Recompute the LSPs for which it was delegated [LSPs stored in tunnel store]
tunnelService.queryTunnel(MPLS).forEach(t -> {
checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
});
}
private boolean checkForMasterAndSetupPath(PcePathInfo failedPathInfo) {
/**
* Master of ingress node will setup the path failed stored in PCE store.
*/
if (mastershipService.isLocalMaster(failedPathInfo.src())) {
if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(),
failedPathInfo.constraints(), failedPathInfo.lspType())) {
// If computation is success remove that path
pceStore.removeFailedPathInfo(failedPathInfo);
return true;
}
}
return false;
}
//Timer to call global optimization
private class GlobalOptimizationTimer implements Runnable {
public GlobalOptimizationTimer() {
}
@Override
public void run() {
callForOptimization();
}
}
}
\ No newline at end of file
......
......@@ -19,7 +19,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.onosproject.net.Link.Type.DIRECT;
import java.util.Iterator;
......@@ -29,7 +28,6 @@ import java.util.LinkedList;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
......@@ -165,6 +163,7 @@ public class BasicPceccHandlerTest {
@After
public void tearDown() throws Exception {
PceManagerTest.flowsDownloaded = 0;
}
/**
......
......@@ -15,13 +15,17 @@ import static org.onosproject.pce.pceservice.PathComputationTest.D1;
import static org.onosproject.pce.pceservice.PathComputationTest.D2;
import static org.onosproject.pce.pceservice.PathComputationTest.D3;
import static org.onosproject.pce.pceservice.PathComputationTest.D4;
import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE1;
import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE2;
import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE3;
import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE4;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
import static org.onosproject.net.MastershipRole.MASTER;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
......@@ -35,14 +39,18 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.graph.GraphPathSearch;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.TCP;
import org.onlab.util.Bandwidth;
import org.onosproject.common.DefaultTopologyGraph;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.event.Event;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
......@@ -52,6 +60,7 @@ import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
......@@ -60,6 +69,7 @@ import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.DeviceId;
......@@ -71,6 +81,7 @@ import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
......@@ -86,7 +97,9 @@ import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyServiceAdapter;
import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService;
......@@ -97,7 +110,9 @@ import org.onosproject.pce.util.PceStoreAdapter;
import org.onosproject.pce.util.TunnelServiceAdapter;
import org.onosproject.pce.util.FlowObjServiceAdapter;
import org.onosproject.store.service.TestStorageService;
import com.google.common.collect.ImmutableSet;
import static org.onosproject.pce.pceservice.PceManager.PCEP_PORT;
/**
* Tests the functions of PceManager.
......@@ -107,6 +122,7 @@ public class PceManagerTest {
private PathComputationTest pathCompTest = new PathComputationTest();
private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService();
private MockTopologyService topologyService = new MockTopologyService();
private MockMastershipService mastershipService = new MockMastershipService();
private MockPathService pathService = new MockPathService();
private PceManager pceManager = new PceManager();
private MockCoreService coreService = new MockCoreService();
......@@ -129,13 +145,19 @@ public class PceManagerTest {
private Device deviceD1, deviceD2, deviceD3, deviceD4;
private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
private Link link1, link2, link3, link4;
private static int flowsDownloaded;
protected static int flowsDownloaded;
private TunnelListener tunnelListener;
private TopologyListener listener;
private Topology topology;
private Set<TopologyEdge> edges;
private Set<TopologyVertex> vertexes;
@Before
public void startUp() {
public void startUp() throws TestUtilsException {
listener = TestUtils.getField(pceManager, "topologyListener");
pceManager.pathService = pathService;
pceManager.resourceService = resourceService;
pceManager.topologyService = topologyService;
pceManager.tunnelService = tunnelService;
pceManager.coreService = coreService;
pceManager.storageService = storageService;
......@@ -144,34 +166,52 @@ public class PceManagerTest {
pceManager.labelRsrcService = labelResourceService;
pceManager.flowObjectiveService = flowObjectiveService;
pceManager.pceStore = pceStore;
pceManager.mastershipService = mastershipService;
pceManager.activate();
}
private class MockMastershipService extends MastershipServiceAdapter {
@Override
public MastershipRole getLocalRole(DeviceId deviceId) {
return MASTER;
}
@Override
public boolean isLocalMaster(DeviceId deviceId) {
return getLocalRole(deviceId) == MASTER;
}
}
private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap,
boolean setLabelStackCap, int bandwidth) {
link1 = PathComputationTest.addLink(DEVICE1, 10, DEVICE2, 20, setCost, 50);
link2 = PathComputationTest.addLink(DEVICE2, 30, DEVICE4, 40, setCost, 20);
link3 = PathComputationTest.addLink(DEVICE1, 80, DEVICE3, 70, setCost, 100);
link4 = PathComputationTest.addLink(DEVICE3, 60, DEVICE4, 50, setCost, 80);
Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
vertexes.add(D1);
vertexes.add(D2);
vertexes.add(D3);
vertexes.add(D4);
this.vertexes = vertexes;
Set<TopologyEdge> edges = new HashSet<TopologyEdge>();
link1 = PathComputationTest.addLink(D1.deviceId().toString(), 10, D2.deviceId().toString(), 20, setCost, 50);
TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1);
edges.add(edge1);
link2 = PathComputationTest.addLink(D2.deviceId().toString(), 30, D4.deviceId().toString(), 40, setCost, 20);
TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2);
edges.add(edge2);
link3 = PathComputationTest.addLink(D1.deviceId().toString(), 80, D3.deviceId().toString(), 70, setCost, 100);
TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3);
edges.add(edge3);
link4 = PathComputationTest.addLink(D3.deviceId().toString(), 60, D4.deviceId().toString(), 50, setCost, 80);
TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
edges.add(edge4);
this.edges = edges;
graph = new DefaultTopologyGraph(vertexes, edges);
DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
......@@ -636,21 +676,18 @@ public class PceManagerTest {
* Tests packet in to trigger label DB sync.
*/
@Test
public void packetProcessingTest() throws URISyntaxException {
public void packetProcessingTest1() throws URISyntaxException {
build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
final int srcHost = 2;
final int dstHost = 5;
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost));
ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(dstHost));
ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(1));
ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(2));
Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
.providerId(new ProviderId("eth", "1")).build();
......@@ -658,24 +695,66 @@ public class PceManagerTest {
LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link1, link1Label);
Ethernet eth;
IPv4 ipv4;
TCP tcp = new TCP();
tcp.setDestinationPort(PCEP_PORT);
ipv4 = new IPv4();
eth = new Ethernet();
IPv4 ipv4 = new IPv4();
ipv4.setProtocol(IPv4.PROTOCOL_TCP);
ipv4.setPayload(tcp);
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
eth.setSourceMACAddress("00:00:00:10:00:0" + srcHost).setDestinationMACAddress("00:00:00:10:00:0" + dstHost);
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost)),
eth, ByteBuffer.wrap(eth.serialize()));
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(),
PortNumber.portNumber(PCEP_PORT)),
eth, null);
pktProcessor.process(new MockPcepPacketContext(inPkt, null));
assertThat(flowsDownloaded, is(4));
}
/**
* Tests faulty packet in to trigger label DB sync.
*/
@Test
public void packetProcessingTest2() throws URISyntaxException {
build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(1));
ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(2));
Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
.providerId(new ProviderId("eth", "1")).build();
LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link1, link1Label);
TCP tcp = new TCP(); // Not set the pcep port.
IPv4 ipv4 = new IPv4();
ipv4.setProtocol(IPv4.PROTOCOL_TCP);
ipv4.setPayload(tcp);
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(),
PortNumber.portNumber(PCEP_PORT)),
eth, null);
pktProcessor.process(new MockPcepPacketContext(inPkt, null));
assertThat(flowsDownloaded, is(0));
}
/**
* Tests tunnel events added and removed.
*/
@Test
......@@ -800,6 +879,390 @@ public class PceManagerTest {
assertThat(pceStore.getFailedPathInfoCount(), is(1));
}
/**
* Tests resilency when L2 link is down.
*/
@Test
public void resilencyTest1() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
assertThat(pceStore.getTunnelInfoCount(), is(1));
assertThat(pceStore.getFailedPathInfoCount(), is(0));
List<Event> reasons = new LinkedList<>();
final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove link2
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
topologyService.changeInTopology(getGraph(null, tempEdges));
listener.event(event);
List<Link> links = new LinkedList<>();
links.add(link3);
links.add(link4);
//Path is D1-D3-D4
assertThat(pathService.paths().iterator().next().links(), is(links));
assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
}
/**
* Tests resilency when L2 and L4 link is down.
*/
@Test
public void resilencyTest2() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove link2 and link4
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
topologyService.changeInTopology(getGraph(null, tempEdges));
listener.event(event);
//No Path
assertThat(pathService.paths().size(), is(0));
}
/**
* Tests resilency when D2 device is down.
*/
@Test
public void resilencyTest3() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove link2 and link1
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
topologyService.changeInTopology(getGraph(null, tempEdges));
listener.event(event);
List<Link> links = new LinkedList<>();
links.add(link3);
links.add(link4);
//Path is D1-D3-D4
assertThat(pathService.paths().iterator().next().links(), is(links));
assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
}
/**
* Tests resilency when ingress device is down.
*/
@Test
public void resilencyTest4() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove link2 and link1
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
topologyService.changeInTopology(getGraph(null, tempEdges));
listener.event(event);
//No path
assertThat(pathService.paths().size(), is(0));
}
/**
* Tests resilency when D2 and D3 devices are down.
*/
@Test
public void resilencyTest5() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove device2, device3 and all links
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
Set<TopologyVertex> tempVertexes = new HashSet<>();
tempVertexes.add(D2);
tempVertexes.add(D3);
topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
listener.event(event);
//No path
assertThat(pathService.paths().size(), is(0));
}
/**
* Tests resilency when egress device is down.
*/
@Test
public void resilencyTest6() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove device4 , link2 and link4
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
Set<TopologyVertex> tempVertexes = new HashSet<>();
tempVertexes.add(D4);
topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
listener.event(event);
//No path
assertThat(pathService.paths().size(), is(0));
}
/**
* Tests resilency when egress device is down.
*/
@Test
public void resilencyTest7() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove device4 , link2 and link4
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
Set<TopologyVertex> tempVertexes = new HashSet<>();
tempVertexes.add(D4);
topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
listener.event(event);
//No path
assertThat(pathService.paths().size(), is(0));
}
/**
* Tests resilency when D2 device is suspended.
*/
@Test
public void resilencyTest8() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove device2 , link1 and link2
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
Set<TopologyVertex> tempVertexes = new HashSet<>();
tempVertexes.add(D2);
topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
listener.event(event);
List<Link> links = new LinkedList<>();
links.add(link3);
links.add(link4);
//Path is D1-D3-D4
assertThat(pathService.paths().iterator().next().links(), is(links));
assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
}
/**
* Tests resilency when D2 device availability is changed.
*/
@Test
public void resilencyTest11() {
build4RouterTopo(true, false, false, false, 10);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
constraints.add(localBwConst);
//Setup the path , tunnel created
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
List<Event> reasons = new LinkedList<>();
LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
reasons.add(linkEvent);
linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
reasons.add(linkEvent);
final TopologyEvent event = new TopologyEvent(
TopologyEvent.Type.TOPOLOGY_CHANGED,
topology,
reasons);
//Change Topology : remove device2 , link1 and link2
Set<TopologyEdge> tempEdges = new HashSet<>();
tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
Set<TopologyVertex> tempVertexes = new HashSet<>();
tempVertexes.add(D2);
topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
listener.event(event);
List<Link> links = new LinkedList<>();
links.add(link3);
links.add(link4);
//Path is D1-D3-D4
assertThat(pathService.paths().iterator().next().links(), is(links));
assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
}
@After
public void tearDown() {
pceManager.deactivate();
......@@ -813,10 +1276,16 @@ public class PceManagerTest {
pceManager.labelRsrcService = null;
pceManager.flowObjectiveService = null;
pceManager.pceStore = null;
pceManager.topologyService = null;
pceManager.mastershipService = null;
flowsDownloaded = 0;
}
private class MockTopologyService extends TopologyServiceAdapter {
private void changeInTopology(TopologyGraph graphModified) {
graph = graphModified;
}
@Override
public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
......@@ -837,8 +1306,27 @@ public class PceManagerTest {
}
}
private class MockPathService extends PathServiceAdapter {
private TopologyGraph getGraph(Set<TopologyVertex> removedVertex, Set<TopologyEdge> removedEdges) {
if (removedVertex != null) {
vertexes.remove(removedVertex);
removedVertex.forEach(v ->
{
vertexes.remove(v);
});
}
if (removedEdges != null) {
removedEdges.forEach(e ->
{
edges.remove(e);
});
}
return new DefaultTopologyGraph(vertexes, edges);
}
private class MockPathService extends PathServiceAdapter {
Set<Path> computedPaths;
@Override
public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
// If either edge is null, bail with no paths.
......@@ -848,7 +1336,12 @@ public class PceManagerTest {
// Otherwise get all paths between the source and destination edge
// devices.
return topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
computedPaths = topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
return computedPaths;
}
private Set<Path> paths() {
return computedPaths;
}
}
......@@ -946,6 +1439,31 @@ public class PceManagerTest {
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public Collection<Tunnel> queryAllTunnels() {
Collection<Tunnel> result = new HashSet<Tunnel>();
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
result.add(tunnelIdAsKeyStore.get(tunnelId));
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
List<Tunnel> tunnelList = new LinkedList<>();
for (Tunnel t : tunnelIdAsKeyStore.values()) {
for (Link l : t.path().links()) {
if (l.src().deviceId().equals(deviceId) || l.dst().deviceId().equals(deviceId)) {
tunnelList.add(t);
break;
}
}
}
return tunnelList;
}
}
public static class MockCoreService extends CoreServiceAdapter {
......
......@@ -158,6 +158,7 @@ public class PceccSrTeBeHandlerTest {
@After
public void tearDown() throws Exception {
PceManagerTest.flowsDownloaded = 0;
}
/**
......

7.44 KB | W: | H:

23.3 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
......@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pce</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-pceweb</artifactId>
......@@ -42,6 +43,11 @@
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-pce</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<properties>
......
......@@ -17,33 +17,48 @@
package org.onosproject.pceweb;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onlab.util.DataRateUnit;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.DisjointPath;
import org.onosproject.net.ElementId;
import org.onosproject.net.HostId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.topo.DeviceHighlight;
import org.onosproject.ui.topo.Highlights;
import org.onosproject.ui.topo.HostHighlight;
import org.onosproject.ui.topo.NodeBadge;
import org.onosproject.ui.topo.TopoJson;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.Constraint;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelService;
import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
......@@ -56,47 +71,66 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
private static final String PCEWEB_SET_SRC = "pceTopovSetSrc";
private static final String PCEWEB_SET_DST = "pceTopovSetDst";
private static final String PCEWEB_SET_PATH = "pceTopovSetMode";
private static final String PCEWEB_UPDATE_PATH_QUERY = "pceTopovUpdateQuery";
private static final String PCEWEB_UPDATE_PATH = "pceTopovUpdate";
private static final String PCEWEB_REMOVE_PATH_QUERY = "pceTopovRemQuery";
private static final String PCEWEB_REMOVE_PATH = "pceTopovRem";
private static final String PCEWEB_QUERY_TUNNELS = "pceTopovTunnelDisplay";
private static final String PCEWEB_SHOW_TUNNEL = "pceTopovShowTunnels";
private static final String PCEWEB_SHOW_TUNNEL_REMOVE = "pceTopovShowTunnelsRem";
private static final String ID = "id";
private static final String MODE = "mode";
private static final String TYPE = "type";
private static final String SWITCH = "switch";
private static final String ENDSTATION = "endstation";
public static final String DST = "Dst";
public static final String SRC = "Src";
private static final String ROUTER = "router";
private static final String DST = "Egress";
private static final String SRC = "Ingress";
private static final String BANDWIDTH = "bw";
private static final String BANDWIDTHTYPE = "bwtype";
private static final String COSTTYPE = "ctype";
private static final String LSPTYPE = "lsptype";
private static final String SRCID = "srid";
private static final String DSTID = "dsid";
private static final String TUNNEL_ID = "tunnelid";
private static final String TUNNEL_NAME = "tunnelname";
private static final String COST_TYPE_IGP = "igp";
private static final String COST_TYPE_TE = "te";
private static final String BANDWIDTH_TYPE_KBPS = "kbps";
private static final String BUFFER_ARRAY = "a";
private static final String BANDWIDTH_BPS = "BPS";
private static final String LSP_TYPE_CR = "cr";
private static final String LSP_TYPE_SRBE = "srbe";
private static final String LSP_TYPE_SRTE = "srte";
private static final String STRING_NULL = "null";
// Delay for showHighlights event processing on GUI client side to
// account for addLink animation.
public static final int DELAY_MS = 1100;
private static final String CLASS = "class";
private static final String UNKNOWN = "unknown";
private static final String DEVICE = "device";
private static final int DELAY_MS = 1100;
private static final double BANDWIDTH_KBPS = 1_000;
private static final double BANDWIDTH_MBPS = 1_000_000;
private Set<Link> allPathLinks;
private boolean listenersRemoved;
private LinkWeight linkData;
private int highlightDelay;
private final Logger log = LoggerFactory.getLogger(getClass());
private PathService pathService;
private ElementId src, dst;
private String srcType, dstType;
private List<Path> paths;
private int pathIndex;
private final Logger log = LoggerFactory.getLogger(getClass());
private final TopologyListener topologyListener = new InternalTopologyListener();
private final TunnelListener tunnelListener = new InnerPceWebTunnelListener();
protected TopologyService topologyService;
protected TunnelService tunnelService;
protected PceService pceService;
protected DeviceService deviceService;
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
//TODO: Need add listeners.
//topologyService = directory.get(TopologyService.class);
//addListeners();
topologyService = directory.get(TopologyService.class);
tunnelService = directory.get(TunnelService.class);
pceService = directory.get(PceService.class);
deviceService = directory.get(DeviceService.class);
topologyService.addListener(topologyListener);
tunnelService.addListener(tunnelListener);
}
@Override
......@@ -105,7 +139,19 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
new ClearHandler(),
new SetSrcHandler(),
new SetDstHandler(),
new SetPathHandler());
new SetPathHandler(),
new UpdatePathQueryHandler(),
new UpdatePathHandler(),
new RemovePathQueryHandler(),
new RemovePathHandler(),
new ShowTunnelHandler());
}
@Override
public void destroy() {
topologyService.removeListener(topologyListener);
tunnelService.removeListener(tunnelListener);
super.destroy();
}
// Handler classes
......@@ -137,7 +183,6 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
@Override
public void process(long sid, ObjectNode payload) {
log.info("PCE WEB Set source process method invoked");
String id = string(payload, ID);
src = elementId(id);
srcType = string(payload, TYPE);
......@@ -146,7 +191,6 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
}
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
srcType, src.toString(), SRC)));
}
}
......@@ -167,7 +211,6 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
if (src.equals(dst)) {
src = null;
}
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
dstType, dst.toString(), DST)));
......@@ -175,7 +218,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
}
/**
* Handles the 'patchcalculation' event received from the client.
* Handles the 'path calculation' event received from the client.
*/
private final class SetPathHandler extends RequestHandler {
......@@ -185,15 +228,168 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
@Override
public void process(long sid, ObjectNode payload) {
String mode = string(payload, MODE);
String bandWidth = string(payload, BANDWIDTH);
String bandWidthType = string(payload, BANDWIDTHTYPE);
String costType = string(payload, COSTTYPE);
String lspType = string(payload, LSPTYPE);
String tunnelName = string(payload, TUNNEL_NAME);
if (tunnelName.equals(STRING_NULL)) {
log.error("tunnel name should not be empty");
return;
}
if (pceService == null) {
log.error("PCE service is not active");
return;
}
// TODO: Read user input[constraints] and call the path calculation based on
//given constrainsts.
findAndSendPaths();
if (lspType == null) {
log.error("PCE setup path is failed.");
}
if ((src != null) && (dst != null)) {
findAndSendPaths(src, dst, bandWidth, bandWidthType, costType, lspType, tunnelName);
}
}
}
/**
* Handles the 'update path query' event received from the client.
*/
private final class UpdatePathQueryHandler extends RequestHandler {
public UpdatePathQueryHandler() {
super(PCEWEB_UPDATE_PATH_QUERY);
}
@Override
public void process(long sid, ObjectNode payload) {
String srcId = string(payload, SRCID);
ElementId src = elementId(srcId);
String dstId = string(payload, DSTID);
ElementId dst = elementId(dstId);
Device srcDevice = deviceService.getDevice((DeviceId) src);
Device dstDevice = deviceService.getDevice((DeviceId) dst);
TunnelEndPoint tunSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(srcDevice.annotations().value("lsrId")));
TunnelEndPoint tunDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(dstDevice.annotations().value("lsrId")));
Collection<Tunnel> tunnelSet = tunnelService.queryTunnel(tunSrc, tunDst);
ObjectNode result = objectNode();
ArrayNode arrayNode = arrayNode();
for (Tunnel tunnel : tunnelSet) {
if (tunnel.type() == MPLS) {
arrayNode.add(tunnel.tunnelId().toString());
}
}
result.putArray(BUFFER_ARRAY).addAll(arrayNode);
sendMessage(PCEWEB_SHOW_TUNNEL, sid, result);
}
}
/**
* Handles the 'update path' event received from the client.
*/
private final class UpdatePathHandler extends RequestHandler {
public UpdatePathHandler() {
super(PCEWEB_UPDATE_PATH);
}
@Override
public void process(long sid, ObjectNode payload) {
String bandWidth = string(payload, BANDWIDTH);
String bandWidthType = string(payload, BANDWIDTHTYPE);
String costType = string(payload, COSTTYPE);
String tunnelId = string(payload, TUNNEL_ID);
if (tunnelId == null) {
log.error("PCE update path is failed.");
}
findAndSendPathsUpdate(bandWidth, bandWidthType, costType, tunnelId);
}
}
/**
* Handles the 'remove path query' event received from the client.
*/
private final class RemovePathQueryHandler extends RequestHandler {
public RemovePathQueryHandler() {
super(PCEWEB_REMOVE_PATH_QUERY);
}
@Override
public void process(long sid, ObjectNode payload) {
String srcId = string(payload, SRCID);
ElementId src = elementId(srcId);
String dstId = string(payload, DSTID);
ElementId dst = elementId(dstId);
Device srcDevice = deviceService.getDevice((DeviceId) src);
Device dstDevice = deviceService.getDevice((DeviceId) dst);
TunnelEndPoint tunSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(srcDevice.annotations().value("lsrId")));
TunnelEndPoint tunDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(dstDevice.annotations().value("lsrId")));
Collection<Tunnel> tunnelSet = tunnelService.queryTunnel(tunSrc, tunDst);
ObjectNode result = objectNode();
ArrayNode arrayNode = arrayNode();
for (Tunnel tunnel : tunnelSet) {
if (tunnel.type() == MPLS) {
arrayNode.add(tunnel.tunnelId().toString());
}
}
result.putArray(BUFFER_ARRAY).addAll(arrayNode);
sendMessage(PCEWEB_SHOW_TUNNEL_REMOVE, sid, result);
}
}
/**
* Handles the 'remove path' event received from the client.
*/
private final class RemovePathHandler extends RequestHandler {
public RemovePathHandler() {
super(PCEWEB_REMOVE_PATH);
}
@Override
public void process(long sid, ObjectNode payload) {
String tunnelId = string(payload, TUNNEL_ID);
if (tunnelId == null) {
log.error("PCE update path is failed.");
}
findAndSendPathsRemove(tunnelId);
}
}
/**
* Handles the 'show the existed tunnels' event received from the client.
*/
private final class ShowTunnelHandler extends RequestHandler {
public ShowTunnelHandler() {
super(PCEWEB_QUERY_TUNNELS);
}
@Override
public void process(long sid, ObjectNode payload) {
findTunnelAndHighlights();
}
}
// === ------------
/**
* provides the element id.
*/
......@@ -204,45 +400,170 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
return HostId.hostId(id);
}
}
//TODO: Need to pass constraints to this method
private void findAndSendPaths() {
log.info("src={}; dst={};", src, dst);
if (src != null && dst != null) {
//TBD: Need to call pathcalulation API here
hilightAndSendPaths();
/**
* Handles the setup path and highlights the path.
*
* @param bandWidth
* @param bandWidthType is the kbps or mbps
* @param costType is igp or te
* @param lspType is WITH_SIGNALLING,WITHOUT_SIGNALLING_AND_WITHOUT_SR or SR_WITHOUT_SIGNALLING
* @param tunnelName tunnel id
*/
private void findAndSendPaths(ElementId src, ElementId dst, String bandWidth, String bandWidthType,
String costType, String lspType, String tunnelName) {
log.debug("src={}; dst={};", src, dst);
boolean path;
List<Constraint> listConstrnt;
listConstrnt = addBandwidthCostTypeConstraints(bandWidth, bandWidthType, costType);
//LSP type
LspType lspTypeVal = null;
switch (lspType) {
case LSP_TYPE_CR:
lspTypeVal = LspType.WITH_SIGNALLING;
break;
case LSP_TYPE_SRBE:
lspTypeVal = LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
break;
case LSP_TYPE_SRTE:
lspTypeVal = LspType.SR_WITHOUT_SIGNALLING;
break;
default:
log.error("Invalid LSP type");
break;
}
path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal);
if (!path) {
log.error("setup path is failed");
return;
}
return;
}
/**
* Handles the update path and highlights the path.
*
* @param bandWidth bandWidth
* @param bandWidthType is the kbps or mbps
* @param costType is igp or te
* @param tunnelName tunnel id
*/
private void findAndSendPathsUpdate(String bandWidth, String bandWidthType, String costType, String tunnelIdStr) {
if (tunnelIdStr != null) {
List<Constraint> listConstrnt;
if (tunnelIdStr.equals(STRING_NULL)) {
log.error("update path is failed");
return;
}
if (pceService == null) {
log.error("PCE service is not active");
return;
}
listConstrnt = addBandwidthCostTypeConstraints(bandWidth, bandWidthType, costType);
TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
boolean path = pceService.updatePath(tunnelId, listConstrnt);
if (!path) {
log.error("update path is failed");
return;
}
}
return;
}
/**
* Handles the remove path and highlights the paths if existed.
*
* @param tunnelIdName tunnelId
*/
private void findAndSendPathsRemove(String tunnelIdStr) {
if (tunnelIdStr != null) {
if (pceService == null) {
log.error("PCE service is not active");
return;
}
TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
boolean path = pceService.releasePath(tunnelId);
if (!path) {
log.error("remove path is failed");
return;
}
}
return;
}
//TODO: The below code is not used. Once get path from PCE app then below code will be use.
// the below code will get path and it will highlight the selected path.
//Currently primary path in use, there is no use of secondary path.
//secondary path need to remove based on path received by PCE app.
private ImmutableSet.Builder<Link> buildPaths(
ImmutableSet.Builder<Link> pathBuilder) {
private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) {
paths.forEach(path -> path.links().forEach(pathBuilder::add));
return pathBuilder;
}
private ImmutableSet.Builder<Link> buildDisjointPaths(
ImmutableSet.Builder<Link> pathBuilder) {
paths.forEach(path -> {
DisjointPath dp = (DisjointPath) path;
pathBuilder.addAll(dp.primary().links());
pathBuilder.addAll(dp.backup().links());
});
return pathBuilder;
/**
* Handles the preparation of constraints list with given bandwidth and cost-type.
*
* @param bandWidth bandWidth
* @param bandWidthType is the kbps or mbps
* @param costType is igp or te
* @param listConstrnt list of constraints
* @return
*/
private List<Constraint> addBandwidthCostTypeConstraints(String bandWidth,
String bandWidthType,
String costType) {
List<Constraint> listConstrnt = new LinkedList<>();
//bandwidth
double bwValue = 0.0;
if (!bandWidth.equals(STRING_NULL)) {
bwValue = Double.parseDouble(bandWidth);
}
if (bandWidthType.equals(BANDWIDTH_TYPE_KBPS)) {
bwValue = bwValue * BANDWIDTH_KBPS;
} else {
bwValue = bwValue * BANDWIDTH_MBPS;
}
//Cost type
CostConstraint.Type costTypeVal = null;
switch (costType) {
case COST_TYPE_IGP:
costTypeVal = CostConstraint.Type.COST;
break;
case COST_TYPE_TE:
costTypeVal = CostConstraint.Type.TE_COST;
break;
default:
log.error("Invalid cost type");
break;
}
if (bwValue != 0.0) {
listConstrnt.add(BandwidthConstraint.of(bwValue, DataRateUnit.valueOf(BANDWIDTH_BPS)));
}
if (costTypeVal != null) {
listConstrnt.add(CostConstraint.of(costTypeVal));
}
return listConstrnt;
}
/**
* Handles the highlights of selected path.
*/
private void hilightAndSendPaths() {
PceWebLinkMap linkMap = new PceWebLinkMap();
allPathLinks.forEach(linkMap::add);
Set<Link> selectedPathLinks;
selectedPathLinks = paths.isEmpty() ? ImmutableSet.of()
: ImmutableSet.copyOf(paths.get(pathIndex).links());
selectedPathLinks = paths.isEmpty() ?
ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
Highlights highlights = new Highlights();
if (highlightDelay > 0) {
......@@ -261,16 +582,32 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
sendMessage(TopoJson.highlightsMessage(highlights));
}
/**
* Handles the addition of badge and highlights.
*
* @param highlights highlights
* @param type device type
* @param elemId device to be add badge
* @param src device to be add badge
* @return
*/
private Highlights addBadge(Highlights highlights, String type,
String elemId, String src) {
if (SWITCH.equals(type)) {
if (ROUTER.equals(type)) {
highlights = addDeviceBadge(highlights, elemId, src);
} else if (ENDSTATION.equals(type)) {
highlights = addHostBadge(highlights, elemId, src);
}
return highlights;
}
/**
* Handles the badge add and highlights.
*
* @param h highlights
* @param elemId device to be add badge
* @param type device type
* @return highlights
*/
private Highlights addDeviceBadge(Highlights h, String elemId, String type) {
DeviceHighlight dh = new DeviceHighlight(elemId);
dh.setBadge(createBadge(type));
......@@ -278,18 +615,59 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
return h;
}
private Highlights addHostBadge(Highlights h, String elemId, String type) {
HostHighlight hh = new HostHighlight(elemId);
hh.setBadge(createBadge(type));
h.add(hh);
return h;
}
/**
* Handles the node badge add and highlights.
*
* @param type device type
* @return badge of given node
*/
private NodeBadge createBadge(String type) {
return NodeBadge.text(type);
}
//TODO: Listeners need to add.
//If topology changes then path need to be re calculate.
/**
* Handles the event of topology listeners.
*/
private class InternalTopologyListener implements TopologyListener {
@Override
public void event(TopologyEvent event) {
highlightDelay = DELAY_MS;
findTunnelAndHighlights();
highlightDelay = 0;
}
}
/**
* Handles the event of tunnel listeners.
*/
private class InnerPceWebTunnelListener implements TunnelListener {
@Override
public void event(TunnelEvent event) {
Tunnel tunnel = event.subject();
if (tunnel.type() == MPLS) {
highlightDelay = DELAY_MS;
findTunnelAndHighlights();
highlightDelay = 0;
}
}
}
/**
* Handles the event of topology listeners.
*/
private void findTunnelAndHighlights() {
Collection<Tunnel> tunnelSet = null;
tunnelSet = tunnelService.queryTunnel(MPLS);
for (Tunnel tunnel : tunnelSet) {
if (tunnel.path() == null) {
log.info("path does not exist");
return;
}
paths.add(tunnel.path());
}
ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
allPathLinks = buildPaths(builder).build();
hilightAndSendPaths();
}
}
......
......@@ -63,7 +63,6 @@ public class PceWebTopovOverlay extends UiTopoOverlay {
public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
pp.title(MY_TITLE);
log.info("Modify device details called.");
DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
......
......@@ -21,16 +21,23 @@
// injected refs
var $log, fs, flash, wss, tps, ns, tds, ds;
var tunnelNameData, tunnelNameDataRemove;
// constants
var srcMessage = 'pceTopovSetSrc',
dstMessage = 'pceTopovSetDst',
clearMessage = 'pceTopovClear',
setModemsg = 'pceTopovSetMode',
L3dev = 'requestIpDevDetails';
setPathmsg = 'pceTopovSetMode',
updatePathmsgQuery = 'pceTopovUpdateQuery',
remPathmsgQuery = 'pceTopovRemQuery',
updatePathmsg = 'pceTopovUpdate',
remPathmsg = 'pceTopovRem',
showTunnelInfoMsg = 'pceTopovShowTunnels',
queryDisplayTunnelMsg = 'pceTopovTunnelDisplay',
showTunnelInfoRemoveMsg = 'pceTopovShowTunnelsRem';
// internal state
var currentMode = null;
var handlerMap = {},
handlerMapRem = {};
// === ---------------------------
// === Helper functions
......@@ -58,153 +65,326 @@
flash.flash('Cleared source and destination');
}
function dOk() {
var bandWidth = d3.select('#band-width-box').property("checked");
var bandValue = null;
var bandType = null;
if (bandWidth) {
bandValue = d3.select('#band-width-value').property("value");
function dClose() {
$log.debug('Dialog Close button clicked (or Esc pressed)');
}
if (d3.select("#band-kpbs-val").property("checked")) {
bandType = 'kbps';
} else if (d3.select('#band-mpbs-val').property("checked")) {
bandType = 'mbps';
}
function createUserText() {
var content = ds.createDiv('constraints-input'),
form = content.append('form'),
p = form.append('p');
function addAttribute(name, id, nameField, type) {
p.append('input').attr({
type: type,
name: name,
id: id
});
p.append('span').text(nameField);
p.append('br');
}
var costType = d3.select('#pce-cost-type').property("checked");
var costTypeVal = null;
//Add the bandwidth related inputs.
addAttribute('band-width-name', 'band-width-box', 'Band Width', 'checkbox');
addAttribute('band-width-value-name', 'band-width-value', null, 'number');
addAttribute('pce-band-type', 'band-kpbs-val', 'kbps', 'radio');
addAttribute('pce-band-type', 'band-mpbs-val', 'mbps', 'radio');
//Add the cost type related inputs.
addAttribute('pce-cost-type-name', 'pce-cost-type', 'Cost Type', 'checkbox');
addAttribute('pce-cost-type-valname', 'pce-cost-type-igp', 'IGP', 'radio');
addAttribute('pce-cost-type-valname', 'pce-cost-type-te', 'TE', 'radio');
//Add the LSP type related inputs.
addAttribute('pce-lsp-type-name', 'pce-lsp-type', 'Lsp Type', 'checkbox');
addAttribute('pce-lsp-type-valname', 'pce-lsp-type-cr', 'WITH SIGNALLING', 'radio');
addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srbe', 'WITHOUT SR WITHOUT SIGNALLING', 'radio');
addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srte', 'WITH SR WITHOUT SIGNALLING', 'radio');
//Add the tunnel name
addAttribute('pce-tunnel-name', 'pce-tunnel-name-id', 'Tunnel Name', 'text');
if (costType) {
return content;
}
if (d3.select("#pce-cost-type-igp").property("checked")) {
costTypeVal = 'igp';
} else if (d3.select('#pce-cost-type-te').property("checked")) {
costTypeVal = 'te';
}
}
function createUserTextUpdate(data) {
var content = ds.createDiv(),
form = content.append('form'),
p = form.append('p');
var lspType = d3.select('#pce-lsp-type').property("checked");
var lspTypeVal = null;
p.append('span').text('Tunnel IDs');
p.append('br');
if (lspType) {
data.a.forEach( function (val, idx) {
p.append('input').attr({
id: 'tunnel-id-'+idx,
type: 'radio',
name: 'tunnel-id-name',
value: val
});
if (d3.select("#pce-lsp-type-cr").property("checked")) {
lspTypeVal = 'cr';
} else if (d3.select('#pce-lsp-type-srbe').property("checked")) {
lspTypeVal = 'srbe';
} else if (d3.select('#pce-lsp-type-srte').property("checked")) {
lspTypeVal = 'srte';
}
}
p.append('span').text(val);
p.append('br');
//TBD: Read the user inputs and need to send the event for calculating the path based on constrainsts.
// TBD: Need to read IGP cost type and LSP type.
//wss.sendEvent(setModemsg);
//flash.flash('creat path message');
} );
$log.debug('Dialog OK button clicked');
return content;
}
function dClose() {
$log.debug('Dialog Close button clicked (or Esc pressed)');
}
function createUserTextUpdatePathEvent() {
var content = ds.createDiv(),
form = content.append('form'),
p = form.append('p');
function createUserText() {
var content = ds.createDiv();
var form = content.append('form');
var p = form.append('p');
function addAttribute(name, id, nameField, type) {
p.append('input').attr({
type: type,
name: name,
id: id
});
//Add the bandwidth related inputs.
p.append('input').attr({
id: 'band-width-box',
type: 'checkbox',
name: 'band-width-name'
});
p.append('span').text('Band Width');
p.append('br');
p.append('input').attr({
id: 'band-width-value',
type: 'number',
name: 'band-width-value-name'
});
p.append('input').attr({
id: 'band-kpbs-val',
type: 'radio',
name: 'pce-band-type'
});
p.append('span').text('kpbs');
p.append('input').attr({
id: 'band-mpbs-val',
type: 'radio',
name: 'pce-band-type'
});
p.append('span').text('mpbs');
p.append('br');
p.append('span').text(nameField);
p.append('br');
}
//Add the bandwidth related inputs.
addAttribute('band-width-name', 'update-band-width-box', 'Band Width', 'checkbox');
addAttribute('band-width-value-name', 'update-band-width-value', null, 'number');
addAttribute('pce-band-type', 'update-band-kpbs-val', 'kbps', 'radio');
addAttribute('pce-band-type', 'update-band-mpbs-val', 'mbps', 'radio');
//Add the cost type related inputs.
p.append('input').attr({
id: 'pce-cost-type',
type: 'checkbox',
name: 'pce-cost-type-name'
});
p.append('span').text('Cost Type');
p.append('br');
p.append('input').attr({
id: 'pce-cost-type-igp',
type: 'radio',
name: 'pce-cost-type-valname'
});
p.append('span').text('IGP');
p.append('input').attr({
id: 'pce-cost-type-te',
type: 'radio',
name: 'pce-cost-type-valname'
});
p.append('span').text('TE');
p.append('br');
addAttribute('pce-cost-type', 'update-pce-cost-type', 'Cost Type', 'checkbox');
addAttribute('pce-cost-type-value', 'update-pce-cost-type-igp', 'IGP', 'radio');
addAttribute('pce-cost-type-value', 'update-pce-cost-type-te', 'TE', 'radio');
//Add the LSP type related inputs.
p.append('input').attr({
id: 'pce-lsp-type',
type: 'checkbox',
name: 'pce-lsp-type-name'
});
p.append('span').text('Lsp Type');
return content;
}
function createUserTextRemove(data) {
var content = ds.createDiv(),
form = content.append('form'),
p = form.append('p');
p.append('span').text('Tunnel IDs');
p.append('br');
p.append('input').attr({
id: 'pce-lsp-type-cr',
type: 'radio',
name: 'pce-lsp-type-valname'
});
p.append('span').text('CR');
p.append('input').attr({
id: 'pce-lsp-type-srbe',
type: 'radio',
name: 'pce-lsp-type-valname'
});
p.append('span').text('SR BE');
p.append('input').attr({
id: 'pce-lsp-type-srte',
type: 'radio',
name: 'pce-lsp-type-valname'
});
p.append('span').text('SR TE');
data.a.forEach( function (val, idx) {
p.append('input').attr({
id: 'tunnel-id-remove-'+idx,
type: 'checkbox',
name: 'tunnel-id-name-remove',
value: val
});
p.append('span').text(val);
p.append('br');
} );
return content;
}
function isChecked(viewId) {
return d3.select('#' + viewId).property('checked');
}
function getCheckedValue(viewId) {
return d3.select('#' + viewId).property('value');
}
function showTunnelInformation(data) {
wss.unbindHandlers(handlerMap);
tunnelNameData = data;
function dOkUpdate() {
var tdString = '' ;
tunnelNameData.a.forEach( function (val, idx) {
var tunnelName = isChecked('tunnel-id-'+idx);
if (tunnelName)
{
tdString = val;
}
} );
if (tdString) {
constraintsUpdateDialog(tdString);
} else {
$log.debug("No tunnel id is selected.");
}
$log.debug('Dialog OK button clicked');
}
tds.openDialog()
.setTitle('Available LSPs with selected device')
.addContent(createUserTextUpdate(data))
.addOkChained(dOkUpdate, 'GOTO Selection of constraints')
.addCancel(dClose, 'Close')
.bindKeys();
}
function constraintsUpdateDialog(tunnelId) {
// invoked when the OK button is pressed on this dialog
function dOkUpdateEvent() {
$log.debug('Select constraints for update path Dialog OK button pressed');
var bandWidth = isChecked('update-band-width-box'),
bandValue = null,
bandType = null;
if (bandWidth) {
bandValue = d3.select('#update-band-width-value');
if (isChecked('update-band-kpbs-val')) {
bandType = 'kbps';
} else if (isChecked('update-band-mpbs-val')) {
bandType = 'mbps';
}
}
var costType = isChecked('update-pce-cost-type'),
costTypeVal = null;
if (costType) {
if (isChecked('update-pce-cost-type-igp')) {
costTypeVal = 'igp';
} else if (isChecked('update-pce-cost-type-te')) {
costTypeVal = 'te';
}
}
wss.sendEvent(updatePathmsg, {
bw: bandValue,
ctype: costTypeVal,
tunnelname: tunnelId
});
flash.flash('update path message');
}
tds.openDialog()
.setTitle('Select constraints for update path')
.addContent(createUserTextUpdatePathEvent())
.addCancel()
.addOk(dOkUpdateEvent, 'Update Path') // NOTE: NOT the "chained" version!
.bindKeys();
}
function showTunnelInformationRemove(data) {
wss.unbindHandlers(handlerMapRem);
tunnelNameDataRemove = data;
tds.openDialog()
.setTitle('Available Tunnels for remove')
.addContent(createUserTextRemove(data))
.addOk(dOkRemove, 'Remove')
.addCancel(dClose, 'Close')
.bindKeys();
}
//setup path
function setMode() {
function dOk() {
var bandWidth = isChecked('band-width-box'),
bandValue = null,
bandType = null;
if (bandWidth) {
bandValue = getCheckedValue('band-width-value');
if (isChecked('band-kpbs-val')) {
bandType = 'kbps';
} else if (isChecked('band-mpbs-val')) {
bandType = 'mbps';
}
}
var costType = isChecked('pce-cost-type'),
costTypeVal = null;
if (costType) {
if (isChecked('pce-cost-type-igp')) {
costTypeVal = 'igp';
} else if (isChecked('pce-cost-type-te')) {
costTypeVal = 'te';
}
}
var lspType = isChecked('pce-lsp-type'),
lspTypeVal = null;
if (lspType) {
if (isChecked('pce-lsp-type-cr')) {
lspTypeVal = 'cr';
} else if (isChecked('pce-lsp-type-srbe')) {
lspTypeVal = 'srbe';
} else if (isChecked('pce-lsp-type-srte')) {
lspTypeVal = 'srte';
}
}
wss.sendEvent(setPathmsg, {
bw: bandValue,
bwtype: bandType,
ctype: costTypeVal,
lsptype: lspTypeVal,
tunnelname: getCheckedValue('pce-tunnel-name-id')
});
flash.flash('create path message');
$log.debug('Dialog OK button clicked');
}
tds.openDialog()
.setTitle('constraints user')
.setTitle('constraints selection')
.addContent(createUserText())
.addOk(dOk, 'OK')
.addCancel(dClose, 'Close')
.bindKeys();
}
function updatePath(node) {
wss.sendEvent(updatePathmsgQuery, {
srid: node[0],
dsid: node[1]
});
handlerMap[showTunnelInfoMsg] = showTunnelInformation;
wss.bindHandlers(handlerMap);
flash.flash('update path message');
}
function dOkRemove() {
tunnelNameDataRemove.a.forEach( function (val, idx) {
var tunnelNameVal = isChecked('tunnel-id-remove-'+idx);
if (tunnelNameVal) {
wss.sendEvent(remPathmsg, {
tunnelid: val
});
}
} );
flash.flash('remove path message');
}
function remPath(node) {
wss.sendEvent(remPathmsgQuery, {
srid: node[0],
dsid: node[1]
});
handlerMapRem[showTunnelInfoRemoveMsg] = showTunnelInformationRemove;
wss.bindHandlers(handlerMapRem);
}
function queryTunnelDisplay() {
wss.sendEvent(queryDisplayTunnelMsg);
}
// === ---------------------------
// === Module Factory Definition
......@@ -227,8 +407,10 @@
setSrc: setSrc,
setDst: setDst,
clear: clear,
setMode: setMode
setMode: setMode,
updatePath: updatePath,
remPath: remPath,
queryTunnelDisplay: queryTunnelDisplay
};
}]);
}());
......
......@@ -34,7 +34,6 @@
glyphId: 'topo',
tooltip: 'PCE web Topo Overlay',
activate: function () {
$log.debug("PCE web topology overlay ACTIVATED");
},
......@@ -112,11 +111,32 @@
},
1: {
cb: function () {
pps.setMode("shortest");
pps.setMode();
},
tt: 'Setup path',
gid: 'plus'
},
2: {
cb: function () {
pps.updatePath(selection);
},
tt: 'Select constraints for LSP',
tt: 'Update path',
gid: '*jp'
},
3: {
cb: function () {
pps.remPath(selection);
},
tt: 'Remove path',
gid: 'minus'
},
4: {
cb: function () {
pps.queryTunnelDisplay();
},
tt: 'Show Tunnels',
gid: 'checkMark'
},
0: {
cb: function () {
pps.clear();
......@@ -126,7 +146,7 @@
},
_keyOrder: [
'openBracket', 'closeBracket', '1', '0'
'openBracket', 'closeBracket', '1', '2', '3', '4', '0'
]
},
hooks: {
......@@ -145,6 +165,9 @@
},
single: function (data) {
selectionCallback(data);
},
multi: function (selectOrder) {
selectionCallback(selectOrder);
}
}
};
......
......@@ -21,6 +21,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-bgp</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-bgp-api</artifactId>
......
......@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-bgp</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-bgpio</artifactId>
......
......@@ -241,12 +241,11 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg {
afi = mpUnReach.afi();
safi = mpUnReach.safi();
}
}
if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
|| (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
//unfeasible route length
cb.writeShort(0);
}
if ((afi == Constants.AFI_FLOWSPEC_VALUE) || (afi == Constants.AFI_VALUE)) {
//unfeasible route length
cb.writeShort(0);
}
}
......
......@@ -171,15 +171,17 @@ public class As4Path implements BgpValueType {
if ((as4pathSet != null) && (as4pathSeq != null)) {
int iAsLenIndex = cb.writerIndex();
cb.writeByte(0);
cb.writeByte(AsPath.ASPATH_SEQ_TYPE);
cb.writeByte(as4pathSeq.size());
if (as4pathSeq.size() != 0) {
cb.writeByte(AsPath.ASPATH_SEQ_TYPE);
cb.writeByte(as4pathSeq.size());
for (int j = 0; j < as4pathSeq.size(); j++) {
cb.writeInt(as4pathSeq.get(j));
}
for (int j = 0; j < as4pathSeq.size(); j++) {
cb.writeInt(as4pathSeq.get(j));
}
int asLen = cb.writerIndex() - iAsLenIndex;
cb.setByte(iAsLenIndex, (byte) (asLen - 1));
int asLen = cb.writerIndex() - iAsLenIndex;
cb.setByte(iAsLenIndex, (byte) (asLen - 1));
}
} else {
cb.writeByte(0);
}
......
......@@ -208,15 +208,16 @@ public class AsPath implements BgpValueType {
if (isaspathSet()) {
int iAsLenIndex = cb.writerIndex();
cb.writeByte(0);
cb.writeByte(ASPATH_SEQ_TYPE);
cb.writeByte(aspathSeq.size());
if (aspathSeq.size() != 0) {
cb.writeByte(ASPATH_SEQ_TYPE);
cb.writeByte(aspathSeq.size());
for (int j = 0; j < aspathSeq.size(); j++) {
cb.writeShort(aspathSeq.get(j));
for (int j = 0; j < aspathSeq.size(); j++) {
cb.writeShort(aspathSeq.get(j));
}
int asLen = cb.writerIndex() - iAsLenIndex;
cb.setByte(iAsLenIndex, (byte) (asLen - 1));
}
int asLen = cb.writerIndex() - iAsLenIndex;
cb.setByte(iAsLenIndex, (byte) (asLen - 1));
} else {
cb.writeByte(0);
}
......
......@@ -106,7 +106,7 @@ public class LinkStateAttributes implements BgpValueType {
*
* @param linkStateAttribList Linked list of Link, Node and Prefix TLVs
*/
LinkStateAttributes(List<BgpValueType> linkStateAttribList) {
public LinkStateAttributes(List<BgpValueType> linkStateAttribList) {
this.linkStateAttribList = linkStateAttribList;
this.isLinkStateAttribute = true;
}
......
......@@ -163,7 +163,6 @@ public class WideCommunityAttrHeader implements BgpValueType {
c.writeShort(TYPE);
c.writeByte(flag);
c.writeByte(hopCount);
c.writeShort(length);
return c.writerIndex() - iLenStartIndex;
}
......
......@@ -97,8 +97,8 @@ public class WideCommunityIpV4Neighbour implements BgpValueType {
while (listIterator.hasNext()) {
IpV4Neighbour speaker = listIterator.next();
if (speaker instanceof IpV4Neighbour) {
c.writeInt(Integer.valueOf(speaker.localSpeaker.toString()));
c.writeInt(Integer.valueOf(speaker.remoteSpeaker.toString()));
c.writeBytes(speaker.localSpeaker().toOctets());
c.writeBytes(speaker.remoteSpeaker().toOctets());
}
}
......
......@@ -96,7 +96,7 @@ public final class BgpLinkAttrMaxLinkBandwidth implements BgpValueType {
*
* @return Maximum link bandwidth
*/
float linkAttrMaxLinkBandwidth() {
public float linkAttrMaxLinkBandwidth() {
return maxBandwidth;
}
......
......@@ -43,10 +43,10 @@ import java.util.Objects;
public class WideCommunity implements BgpValueType {
private static final Logger log = LoggerFactory.getLogger(WideCommunity.class);
public static final byte TYPE = (byte) 254; /* TODO: IANA Assigned */
public static final byte TYPE = (byte) 129;
public static final short LENGTH = 4;
public static final byte TYPE_LENGTH_SIZE = 3;
public static final byte FLAGS = (byte) 0x40;
public static final byte FLAGS = (byte) 0x90;
private WideCommunityAttrHeader wideCommunityHeader;
private int community;
private int localAsn;
......@@ -238,6 +238,9 @@ public class WideCommunity implements BgpValueType {
wideCommunityHeader.write(c);
int iComLengthIndex = c.writerIndex();
c.writeShort(0);
c.writeInt(community);
c.writeInt(localAsn);
c.writeInt(contextAsn);
......@@ -275,6 +278,9 @@ public class WideCommunity implements BgpValueType {
c.setShort(iTargetLenIndex, (short) (length - 2));
}
length = c.writerIndex() - iComLengthIndex;
c.setShort(iComLengthIndex, (short) (length - 2));
length = c.writerIndex() - iLengthIndex;
c.setShort(iLengthIndex, (short) (length - 2));
......
......@@ -46,6 +46,11 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>4.0.36.Final</version>
</dependency>
</dependencies>
<build>
......
......@@ -205,7 +205,7 @@ public class BgpConfig implements BgpCfg {
lspeer.setSelfInnitConnection(true);
if (lspeer.connectPeer() == null) {
connectPeer = new BgpConnectPeerImpl(bgpController, routerid, Controller.getBgpPortNum());
connectPeer = new BgpConnectPeerImpl(bgpController, routerid, Controller.BGP_PORT_NUM);
lspeer.setConnectPeer(connectPeer);
connectPeer.connectPeer();
}
......
......@@ -135,7 +135,7 @@ public class BgpLocalRibImpl implements BgpLocalRib {
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(nodeTree.get(nodeLsIdentifier), detailsLocRib);
if (decisionResult < 0) {
if (decisionResult <= 0) {
for (BgpNodeListener l : bgpController.listener()) {
l.addNode((BgpNodeLSNlriVer4) nlri, details);
}
......@@ -155,7 +155,7 @@ public class BgpLocalRibImpl implements BgpLocalRib {
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(linkTree.get(linkLsIdentifier), detailsLocRib);
if (decisionResult < 0) {
if (decisionResult <= 0) {
linkTree.replace(linkLsIdentifier, detailsLocRib);
for (BgpLinkListener l : bgpController.linkListener()) {
l.addLink((BgpLinkLsNlriVer4) nlri, details);
......@@ -175,7 +175,7 @@ public class BgpLocalRibImpl implements BgpLocalRib {
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(prefixTree.get(prefixIdentifier), detailsLocRib);
if (decisionResult < 0) {
if (decisionResult <= 0) {
prefixTree.replace(prefixIdentifier, detailsLocRib);
log.debug("Local RIB update prefix: {}", detailsLocRib.toString());
}
......
......@@ -159,15 +159,16 @@ public class BgpPeerImpl implements BgpPeer {
* Send flow specification update message to peer.
*
* @param operType operation type
* @param routeKey flow rule key
* @param flowSpec flow specification details
* @param wideCommunity for route policy
* @param wideCommunity for route policy
*/
public final void sendFlowSpecUpdateMessageToPeer(FlowSpecOperation operType, BgpFlowSpecRouteKey routeKey,
BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity) {
List<BgpValueType> attributesList = new LinkedList<>();
byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
byte sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
byte sAfi = Constants.SAFI_FLOWSPEC_VALUE;
boolean isFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
Constants.AFI_FLOWSPEC_VALUE,
......@@ -190,10 +191,10 @@ public class BgpPeerImpl implements BgpPeer {
return;
}
if ((wideCommunity != null) && (isVpnRpdCapabilitySet)) {
sAfi = Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE;
} else if (isVpnFsCapabilitySet) {
if (isVpnFsCapabilitySet) {
sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
} else if (isVpnRpdCapabilitySet) {
sAfi = Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE;
}
attributesList.add(new Origin((byte) 0));
......@@ -222,7 +223,9 @@ public class BgpPeerImpl implements BgpPeer {
}
attributesList.add(new BgpExtendedCommunity(flowSpec.fsActionTlv()));
attributesList.add(wideCommunity);
if (wideCommunity != null) {
attributesList.add(wideCommunity);
}
if (operType == FlowSpecOperation.ADD) {
attributesList.add(new MpReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
......
......@@ -16,7 +16,7 @@
package org.onosproject.bgp.controller.impl;
import static org.onlab.util.Tools.groupedThreads;
import io.netty.util.internal.PlatformDependent;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetSocketAddress;
......@@ -53,9 +53,11 @@ public class Controller {
public Channel serverChannel;
// Configuration options
private static final short BGP_PORT_NUM = 179;
protected static final short BGP_PORT_NUM = 179;
private static final short BGP_PRIVILEGED_PORT = 1790; // server port used for non root users in linux
private static final short PORT_NUM_ZERO = 0;
private static boolean isPortNumSet = false;
private static short portNumber = BGP_PORT_NUM;
private final int workerThreads = 16;
private final int peerWorkerThreads = 16;
......@@ -219,6 +221,11 @@ public class Controller {
*/
public void start() {
log.info("Started");
if (!PlatformDependent.isWindows() && !PlatformDependent.isRoot()) {
portNumber = BGP_PRIVILEGED_PORT;
} else {
portNumber = BGP_PORT_NUM;
}
this.init();
this.run();
}
......@@ -242,7 +249,8 @@ public class Controller {
if (isPortNumSet) {
return PORT_NUM_ZERO;
}
return BGP_PORT_NUM;
return portNumber;
}
/**
......
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//apps/pcep-api:onos-apps-pcep-api',
'//incubator/api:onos-incubator-api',
]
osgi_jar_with_tests (
......
......@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-controller</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-pcep-controller-api</artifactId>
......@@ -51,5 +52,9 @@
<groupId>org.onosproject</groupId>
<artifactId>onlab-misc</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
</dependency>
</dependencies>
</project>
......
......@@ -26,6 +26,8 @@ public class ClientCapability {
private boolean pceccCapability;
private boolean statefulPceCapability;
private boolean pcInstantiationCapability;
private boolean labelStackCapability;
private boolean srCapability;
/**
* Creates new instance of client capability.
......@@ -33,11 +35,34 @@ public class ClientCapability {
* @param pceccCapability represents PCECC capability
* @param statefulPceCapability represents stateful PCE capability
* @param pcInstantiationCapability represents PC initiation capability
* @param labelStackCapability represents S bit is set in PCECC capability
* @param srCapability represents SR capability
*/
public ClientCapability(boolean pceccCapability, boolean statefulPceCapability, boolean pcInstantiationCapability) {
public ClientCapability(boolean pceccCapability, boolean statefulPceCapability, boolean pcInstantiationCapability,
boolean labelStackCapability, boolean srCapability) {
this.pceccCapability = pceccCapability;
this.statefulPceCapability = statefulPceCapability;
this.pcInstantiationCapability = pcInstantiationCapability;
this.labelStackCapability = labelStackCapability;
this.srCapability = srCapability;
}
/**
* Obtains label stack capability.
*
* @return true if client supports PCECC capability with S bit set otherwise false
*/
public boolean labelStackCapability() {
return labelStackCapability;
}
/**
* Obtains segment routing capability.
*
* @return true if client supports SR capability otherwise false
*/
public boolean srCapability() {
return srCapability;
}
/**
......@@ -69,7 +94,8 @@ public class ClientCapability {
@Override
public int hashCode() {
return Objects.hash(pceccCapability, statefulPceCapability, pcInstantiationCapability);
return Objects.hash(pceccCapability, statefulPceCapability, pcInstantiationCapability, labelStackCapability,
srCapability);
}
@Override
......@@ -81,7 +107,9 @@ public class ClientCapability {
ClientCapability other = (ClientCapability) obj;
return Objects.equals(pceccCapability, other.pceccCapability)
&& Objects.equals(statefulPceCapability, other.statefulPceCapability)
&& Objects.equals(pcInstantiationCapability, other.pcInstantiationCapability);
&& Objects.equals(pcInstantiationCapability, other.pcInstantiationCapability)
&& Objects.equals(labelStackCapability, other.labelStackCapability)
&& Objects.equals(srCapability, other.srCapability);
}
return false;
}
......@@ -92,6 +120,8 @@ public class ClientCapability {
.add("pceccCapability", pceccCapability)
.add("statefulPceCapability", statefulPceCapability)
.add("pcInstantiationCapability", pcInstantiationCapability)
.add("labelStackCapability", labelStackCapability)
.add("srCapability", srCapability)
.toString();
}
}
\ No newline at end of file
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcep.controller;
import java.util.Objects;
import com.google.common.base.MoreObjects;
/**
* Representation of LSP info, it will be unique for each LSP.
*/
public class LspKey {
private int plspId;
private short localLspId;
/**
* Creates new instance of LspInfo.
*
* @param plspId LSP id assigned per tunnel per session
* @param localLspId LSP id assigned per tunnel
*/
public LspKey(int plspId, short localLspId) {
this.plspId = plspId;
this.localLspId = localLspId;
}
/**
* Obtains PLSP id.
*
* @return LSP id assigned per tunnel per session
*/
public int plspId() {
return plspId;
}
/**
* Obtains local LSP id.
*
* @return LSP id assigned per tunnel
*/
public short localLspId() {
return localLspId;
}
@Override
public int hashCode() {
return Objects.hash(plspId, localLspId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LspKey) {
LspKey other = (LspKey) obj;
return Objects.equals(plspId, other.plspId)
&& Objects.equals(localLspId, other.localLspId);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("plspId", plspId)
.add("localLspId", localLspId)
.toString();
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ import java.util.List;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepStateReport;
/**
* Represents to provider facing side of a path computation client(pcc).
......@@ -135,4 +136,64 @@ public interface PcepClient {
* @return capability supported by client
*/
ClientCapability capability();
/**
* Adds PCEP device when session is successfully established.
*
* @param pc PCEP client details
*/
void addNode(PcepClient pc);
/**
* Removes PCEP device when session is disconnected.
*
* @param pccId PCEP client ID
*/
void deleteNode(PccId pccId);
/**
* Sets D flag for the given LSP and its LSP info.
*
* @param lspKey contains LSP info
* @param dFlag delegation flag in LSP object
*/
void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag);
/**
* Returns delegation flag for the given LSP info.
*
* @param lspKey contains LSP info
* @return delegation flag
*/
Boolean delegationInfo(LspKey lspKey);
/**
* Creates a temporary cache to hold report messages received during LSPDB sync.
*
* @param pccId PCC id which is the key to store report messages
*/
void initializeSyncMsgList(PccId pccId);
/**
* Returns the list of report messages received during LSPDB sync.
*
* @param pccId PCC id which is the key for all the report messages
* @return list of report messages received during LSPDB sync
*/
List<PcepStateReport> getSyncMsgList(PccId pccId);
/**
* Removes the list of report messages received during LSPDB sync.
*
* @param pccId PCC id which is the key for all the report messages
*/
void removeSyncMsgList(PccId pccId);
/**
* Adds report message received during LSPDB sync into temporary cache.
*
* @param pccId PCC id which is the key to store report messages
* @param rptMsg the report message to be stored
*/
void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg);
}
......
......@@ -57,7 +57,7 @@ public interface PcepClientController {
void removeListener(PcepClientListener listener);
/**
* Register a listener for OF msg events.
* Register a listener for PCEP msg events.
*
* @param listener the listener to notify
*/
......@@ -71,6 +71,34 @@ public interface PcepClientController {
void removeEventListener(PcepEventListener listener);
/**
* Register a listener for PCEP msg events[carrying node descriptor details].
*
* @param listener the listener to notify
*/
void addNodeListener(PcepNodeListener listener);
/**
* Unregister a listener.
*
* @param listener the listener to be unregistered
*/
void removeNodeListener(PcepNodeListener listener);
/**
* Register a listener for packet events.
*
* @param listener the listener to notify
*/
void addPacketListener(PcepPacketListener listener);
/**
* Unregister a packet listener.
*
* @param listener the listener to unregister
*/
void removePacketListener(PcepPacketListener listener);
/**
* Send a message to a particular pcc client.
*
* @param pccId the id of the client to send message.
......
......@@ -15,6 +15,7 @@
*/
package org.onosproject.pcep.controller;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.pcepio.protocol.PcepMessage;
/**
* Notifies providers about PCEP message events.
......@@ -28,4 +29,21 @@ public interface PcepEventListener {
* @param msg the message
*/
void handleMessage(PccId pccId, PcepMessage msg);
/**
* Handles end of LSPDB sync actions.
*
* @param tunnel the tunnel on which action needs to be taken
* @param endOfSyncAction the action that needs to be taken for the tunnel
*/
void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction);
/**
* Handles sending PCEP message to client on end of LSPDB sync.
*
* @param pccId id of the pcc
* @param msg the message to be sent
* @param endOfSyncAction the action that needs to be taken in the message
*/
void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction);
}
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcep.controller;
/**
* Representation of actions to be taken for LSPs on end of LSP-DB sync.
*/
public enum PcepLspSyncAction {
/**
* Specifies that delete message for PCE intiiated tunnel should be sent.
*/
SEND_DELETE(0),
/**
* Specifies that update message should be sent.
*/
SEND_UPDATE(1),
/**
* Specifies that the tunnel should be removed from PCE.
*/
REMOVE(2),
/**
* Specifies that the status of the tunnel should be set as unstable.
*/
UNSTABLE(3);
int value;
/**
* Assigns val with the value for actions to be taken for LSPs on end of LSP-DB sync.
*
* @param val sync status
*/
PcepLspSyncAction(int val) {
value = val;
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcep.controller;
/**
* Notifies providers about PCEP node events.
*/
public interface PcepNodeListener {
/**
* Notifies that the node was added.
*
* @param pc PCEP client details
*/
void addNode(PcepClient pc);
/**
* Notifies that the node was removed.
*
* @param pccId PCEP client ID
*/
void deleteNode(PccId pccId);
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.pcep.controller;
public interface PcepPacketListener {
void sendPacketIn(PccId pccId);
}
......@@ -60,4 +60,25 @@ public interface PcepAgent {
*/
void processPcepMessage(PccId pccId, PcepMessage m);
/**
* Adds PCEP device when session is successfully established.
*
* @param pc PCEP client details
*/
void addNode(PcepClient pc);
/**
* Removes PCEP device when session is disconnected.
*
* @param pccId PCEP client ID
*/
void deleteNode(PccId pccId);
/**
* Analyzes report messages received during LSP DB sync again tunnel store and takes necessary actions.
*
* @param pccId the id of pcc client
* @return success or failure
*/
boolean analyzeSyncMsgList(PccId pccId);
}
......
......@@ -2,6 +2,7 @@ COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//protocols/pcep/api:onos-protocols-pcep-api',
'//incubator/api:onos-incubator-api',
]
osgi_jar_with_tests (
......
......@@ -55,6 +55,7 @@ import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.IPv4RouterIdOfLocalNodeSubTlv;
import org.onosproject.pcepio.types.NodeAttributesTlv;
import org.onosproject.pcepio.types.PceccCapabilityTlv;
import org.onosproject.pcepio.types.SrPceCapabilityTlv;
import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
import org.onosproject.pcepio.types.PcepErrorDetailInfo;
import org.onosproject.pcepio.types.PcepValueType;
......@@ -260,6 +261,8 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
disconnectDuplicate(h);
} else {
h.setState(ESTABLISHED);
//Session is established, add a PCEP device
h.addNode();
}
}
}
......@@ -469,6 +472,20 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
}
/**
* Adds PCEP device once session is established.
*/
private void addNode() {
pc.addNode(pc);
}
/**
* Deletes PCEP device when session is disconnected.
*/
private void deleteNode() {
pc.deleteNode(pc.getPccId());
}
/**
* Return a string describing this client based on the already available
* information (ip address and/or remote socket).
*
......@@ -523,6 +540,8 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
boolean pceccCapability = false;
boolean statefulPceCapability = false;
boolean pcInstantiationCapability = false;
boolean labelStackCapability = false;
boolean srCapability = false;
ListIterator<PcepValueType> listIterator = tlvList.listIterator();
while (listIterator.hasNext()) {
......@@ -531,6 +550,9 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
switch (tlv.getType()) {
case PceccCapabilityTlv.TYPE:
pceccCapability = true;
if (((PceccCapabilityTlv) tlv).sBit()) {
labelStackCapability = true;
}
break;
case StatefulPceCapabilityTlv.TYPE:
statefulPceCapability = true;
......@@ -539,11 +561,15 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
pcInstantiationCapability = true;
}
break;
case SrPceCapabilityTlv.TYPE:
srCapability = true;
break;
default:
continue;
}
}
this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability);
this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability,
labelStackCapability, srCapability);
}
/**
......@@ -563,6 +589,8 @@ class PcepChannelHandler extends IdleStateAwareChannelHandler {
*/
private void sendErrMsgAndCloseChannel() {
// TODO send error message
//Remove PCEP device from topology
deleteNode();
channel.close();
}
......
......@@ -15,34 +15,66 @@
*/
package org.onosproject.pcep.controller.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
import org.onosproject.net.device.DeviceService;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.PcepNodeListener;
import org.onosproject.pcep.controller.PcepPacketListener;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
import org.onosproject.pcepio.protocol.PcepErrorMsg;
import org.onosproject.pcepio.protocol.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepInitiateMsg;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepReportMsg;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.types.PcepValueType;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
import org.onosproject.pcepio.types.SymbolicPathNameTlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.UNSTABLE;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
......@@ -55,6 +87,9 @@ public class PcepClientControllerImpl implements PcepClientController {
private static final Logger log = LoggerFactory.getLogger(PcepClientControllerImpl.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
new ConcurrentHashMap<>();
......@@ -62,9 +97,23 @@ public class PcepClientControllerImpl implements PcepClientController {
protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
protected Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
protected Set<PcepPacketListener> pcepPacketListener = Sets.newHashSet();
private final Controller ctrl = new Controller();
public static final String BANDWIDTH = "bandwidth";
public static final String LSP_SIG_TYPE = "lspSigType";
public static final String PCC_TUNNEL_ID = "PccTunnelId";
public static final String PLSP_ID = "PLspId";
public static final String LOCAL_LSP_ID = "localLspId";
public static final String PCE_INIT = "pceInit";
public static final String COST_TYPE = "costType";
public static final String DELEGATE = "delegation";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TunnelService tunnelService;
@Activate
public void activate() {
ctrl.start(agent);
......@@ -112,11 +161,31 @@ public class PcepClientControllerImpl implements PcepClientController {
}
@Override
public void addPacketListener(PcepPacketListener listener) {
pcepPacketListener.add(listener);
}
@Override
public void removePacketListener(PcepPacketListener listener) {
pcepPacketListener.remove(listener);
}
@Override
public void writeMessage(PccId pccId, PcepMessage msg) {
this.getClient(pccId).sendMessage(msg);
}
@Override
public void addNodeListener(PcepNodeListener listener) {
pcepNodeListener.add(listener);
}
@Override
public void removeNodeListener(PcepNodeListener listener) {
pcepNodeListener.remove(listener);
}
@Override
public void processClientMessage(PccId pccId, PcepMessage msg) {
PcepClient pc = getClient(pccId);
......@@ -162,8 +231,48 @@ public class PcepClientControllerImpl implements PcepClientController {
case REPORT:
//Only update the listener if respective capability is supported else send PCEP-ERR msg
if (pc.capability().statefulPceCapability()) {
for (PcepEventListener l : pcepEventListener) {
l.handleMessage(pccId, msg);
ListIterator<PcepStateReport> listIterator = ((PcepReportMsg) msg).getStateReportList().listIterator();
while (listIterator.hasNext()) {
PcepStateReport stateRpt = listIterator.next();
if (stateRpt.getLspObject().getSFlag()) {
if (pc.lspDbSyncStatus() != PcepSyncStatus.IN_SYNC) {
// Initialize LSP DB sync and temporary cache.
pc.setLspDbSyncStatus(PcepSyncStatus.IN_SYNC);
pc.initializeSyncMsgList(pccId);
}
// Store stateRpt in temporary cache.
pc.addSyncMsgToList(pccId, stateRpt);
// Don't send to provider as of now.
continue;
} else {
if (pc.lspDbSyncStatus() == PcepSyncStatus.IN_SYNC) {
// Set end of LSPDB sync.
pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
// Call packet provider to initiate label DB sync (only if PCECC capable).
if (pc.capability().pceccCapability()) {
pc.setLabelDbSyncStatus(IN_SYNC);
for (PcepPacketListener l : pcepPacketListener) {
l.sendPacketIn(pccId);
}
} else {
// If label db sync is not to be done, handle end of LSPDB sync actions.
agent.analyzeSyncMsgList(pccId);
}
continue;
}
}
// It's a usual report message while sync is not undergoing. So process it immediately.
LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
llPcRptList.add(stateRpt);
PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
.build();
for (PcepEventListener l : pcepEventListener) {
l.handleMessage(pccId, pcReportMsg);
}
}
} else {
// Send PCEP-ERROR message.
......@@ -173,6 +282,8 @@ public class PcepClientControllerImpl implements PcepClientController {
break;
case LABEL_RANGE_RESERV:
break;
case LS_REPORT: //TODO: need to handle LS report to add or remove node
break;
case MAX:
break;
case END:
......@@ -270,5 +381,176 @@ public class PcepClientControllerImpl implements PcepClientController {
public void processPcepMessage(PccId pccId, PcepMessage m) {
processClientMessage(pccId, m);
}
@Override
public void addNode(PcepClient pc) {
for (PcepNodeListener l : pcepNodeListener) {
l.addNode(pc);
}
}
@Override
public void deleteNode(PccId pccId) {
for (PcepNodeListener l : pcepNodeListener) {
l.deleteNode(pccId);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public boolean analyzeSyncMsgList(PccId pccId) {
PcepClient pc = getClient(pccId);
/*
* PLSP_ID is null while tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by PCC and
* in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic path name must be
* carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be included in the LSP object in
* the LSP State Report (PCRpt) message when during a given PCEP session an LSP is "first" reported to a
* PCE. So two separate lists with separate keys are maintained.
*/
Map<LspKey, Tunnel> preSyncLspDbByKey = new HashMap<>();
Map<String, Tunnel> preSyncLspDbByName = new HashMap<>();
// Query tunnel service and fetch all the tunnels with this PCC as ingress.
// Organize into two maps, with LSP key if known otherwise with symbolic path name, for quick search.
Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
for (Tunnel tunnel : queriedTunnels) {
if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
String pLspId = tunnel.annotations().value(PLSP_ID);
if (pLspId != null) {
String localLspId = tunnel.annotations().value(LOCAL_LSP_ID);
checkNotNull(localLspId);
LspKey lspKey = new LspKey(Integer.valueOf(pLspId), Short.valueOf(localLspId));
preSyncLspDbByKey.put(lspKey, tunnel);
} else {
preSyncLspDbByName.put(tunnel.tunnelName().value(), tunnel);
}
}
}
List<PcepStateReport> syncStateRptList = pc.getSyncMsgList(pccId);
Iterator<PcepStateReport> stateRptListIterator = syncStateRptList.iterator();
// For every report, fetch PLSP id, local LSP id and symbolic path name from the message.
while (syncStateRptList.iterator().hasNext()) {
PcepStateReport stateRpt = stateRptListIterator.next();
Tunnel tunnel = null;
PcepLspObject lspObj = stateRpt.getLspObject();
ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
SymbolicPathNameTlv pathNameTlv = null;
while (listTlvIterator.hasNext()) {
PcepValueType tlv = listTlvIterator.next();
switch (tlv.getType()) {
case StatefulIPv4LspIdentifiersTlv.TYPE:
ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
break;
case SymbolicPathNameTlv.TYPE:
pathNameTlv = (SymbolicPathNameTlv) tlv;
break;
default:
break;
}
}
LspKey lspKeyOfRpt = new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId());
tunnel = preSyncLspDbByKey.get(lspKeyOfRpt);
// PCE tunnel is matched with PCRpt LSP. Now delete it from the preSyncLspDb list as the residual
// non-matching list will be processed at the end.
if (tunnel != null) {
preSyncLspDbByKey.remove(lspKeyOfRpt);
} else if (pathNameTlv != null) {
tunnel = preSyncLspDbByName.get(Arrays.toString(pathNameTlv.getValue()));
if (tunnel != null) {
preSyncLspDbByName.remove(tunnel.tunnelName());
}
}
if (tunnel == null) {
// If remove flag is set, and tunnel is not known to PCE, ignore it.
if (lspObj.getCFlag() && !lspObj.getRFlag()) {
// For initiated LSP, need to send PCInit delete msg.
try {
PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
.setLspObject(lspObj).build();
LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList
= new LinkedList<PcInitiatedLspRequest>();
llPcInitiatedLspRequestList.add(releaseLspRequest);
PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
.setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
for (PcepEventListener l : pcepEventListener) {
l.handleEndOfSyncAction(pccId, pcInitiateMsg, SEND_DELETE);
}
} catch (PcepParseException e) {
log.error("Exception occured while sending initiate delete message {}", e.getMessage());
}
}
continue;
}
if (!lspObj.getCFlag()) {
// For learned LSP process both add/update PCRpt.
LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
llPcRptList.add(stateRpt);
PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
.build();
for (PcepEventListener l : pcepEventListener) {
l.handleMessage(pccId, pcReportMsg);
}
continue;
}
// Implied that tunnel != null and lspObj.getCFlag() is set
// State different for PCC sent LSP and PCE known LSP, send PCUpd msg.
State tunnelState = PcepLspStatus
.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
if (tunnelState != tunnel.state()) {
for (PcepEventListener l : pcepEventListener) {
l.handleEndOfSyncAction(tunnel, SEND_UPDATE);
}
}
}
// Check which tunnels are extra at PCE that were not reported by PCC.
Map<Object, Tunnel> preSyncLspDb = (Map) preSyncLspDbByKey;
handleResidualTunnels(preSyncLspDb);
preSyncLspDbByKey = null;
preSyncLspDb = (Map) preSyncLspDbByName;
handleResidualTunnels(preSyncLspDb);
preSyncLspDbByName = null;
preSyncLspDb = null;
pc.removeSyncMsgList(pccId);
return true;
}
/*
* Go through the tunnels which are known by PCE but were not reported by PCC during LSP DB sync and take
* appropriate actions.
*/
private void handleResidualTunnels(Map<Object, Tunnel> preSyncLspDb) {
for (Tunnel pceExtraTunnel : preSyncLspDb.values()) {
if (pceExtraTunnel.annotations().value(PCE_INIT) == null
|| "false".equalsIgnoreCase(pceExtraTunnel.annotations().value(PCE_INIT))) {
// PCC initiated tunnels should be removed from tunnel store.
for (PcepEventListener l : pcepEventListener) {
l.handleEndOfSyncAction(pceExtraTunnel, REMOVE);
}
} else {
// PCE initiated tunnels should be initiated again.
for (PcepEventListener l : pcepEventListener) {
l.handleEndOfSyncAction(pceExtraTunnel, UNSTABLE);
}
}
}
}
}
}
......
......@@ -19,13 +19,18 @@ package org.onosproject.pcep.controller.impl;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
import org.onlab.packet.IpAddress;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepPacketStats;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.driver.PcepAgent;
......@@ -33,6 +38,7 @@ import org.onosproject.pcep.controller.driver.PcepClientDriver;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -66,6 +72,8 @@ public class PcepClientImpl implements PcepClientDriver {
private byte deadTime;
private byte sessionId;
private PcepPacketStatsImpl pktStats;
private Map<LspKey, Boolean> lspDelegationInfo;
private Map<PccId, List<PcepStateReport>> sycRptCache = new HashMap<>();
@Override
public void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats) {
......@@ -188,7 +196,14 @@ public class PcepClientImpl implements PcepClientDriver {
@Override
public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
PcepSyncStatus syncOldStatus = labelDbSyncStatus();
this.labelDbSyncStatus = syncStatus;
if ((syncOldStatus == PcepSyncStatus.IN_SYNC) && (syncStatus == PcepSyncStatus.SYNCED)) {
// Perform end of LSP DB sync actions.
this.agent.analyzeSyncMsgList(pccId);
}
}
@Override
......@@ -203,6 +218,16 @@ public class PcepClientImpl implements PcepClientDriver {
}
@Override
public void addNode(PcepClient pc) {
this.agent.addNode(pc);
}
@Override
public void deleteNode(PccId pccId) {
this.agent.deleteNode(pccId);
}
@Override
public final boolean connectClient() {
return this.agent.addConnectedClient(pccId, this);
}
......@@ -230,6 +255,39 @@ public class PcepClientImpl implements PcepClientDriver {
}
@Override
public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
lspDelegationInfo.put(lspKey, dFlag);
}
@Override
public Boolean delegationInfo(LspKey lspKey) {
return lspDelegationInfo.get(lspKey);
}
@Override
public void initializeSyncMsgList(PccId pccId) {
List<PcepStateReport> rptMsgList = new LinkedList<>();
sycRptCache.put(pccId, rptMsgList);
}
@Override
public List<PcepStateReport> getSyncMsgList(PccId pccId) {
return sycRptCache.get(pccId);
}
@Override
public void removeSyncMsgList(PccId pccId) {
sycRptCache.remove(pccId);
}
@Override
public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
List<PcepStateReport> rptMsgList = sycRptCache.get(pccId);
rptMsgList.add(rptMsg);
sycRptCache.put(pccId, rptMsgList);
}
@Override
public boolean isOptical() {
return false;
}
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.pcep.tunnel.impl;
package org.onosproject.pcep.controller.impl;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
......@@ -51,6 +51,7 @@ public enum PcepLspStatus {
* Returns the applicable PCEP LSP status corresponding to ONOS tunnel state.
*
* @param tunnelState ONOS tunnel state
* @return LSP status as per protocol
*/
public static PcepLspStatus getLspStatusFromTunnelStatus(State tunnelState) {
......@@ -76,6 +77,7 @@ public enum PcepLspStatus {
* Returns the applicable ONOS tunnel state corresponding to PCEP LSP status.
*
* @param lspState PCEP LSP status
* @return tunnel state
*/
public static State getTunnelStatusFromLspStatus(PcepLspStatus lspState) {
......
......@@ -29,14 +29,14 @@ public interface PcepBandwidthObject {
*
* @return bandwidth value
*/
int getBandwidth();
float getBandwidth();
/**
* Sets bandwidth with specified value.
*
* @param iBandwidth Bandwidth's value
*/
void setBandwidth(int iBandwidth);
void setBandwidth(float iBandwidth);
/**
* Writes the BandwidthObject into channel buffer.
......
......@@ -51,6 +51,7 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
public static final byte BANDWIDTH_OBJ_TYPE = 1;
public static final byte BANDWIDTH_OBJ_CLASS = 5;
public static final byte BANDWIDTH_OBJECT_VERSION = 1;
public static final int NO_OF_BITS = 8;
public static final short BANDWIDTH_OBJ_MINIMUM_LENGTH = 8;
static final PcepObjectHeader DEFAULT_BANDWIDTH_OBJECT_HEADER = new PcepObjectHeader(BANDWIDTH_OBJ_CLASS,
......@@ -58,7 +59,7 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
BANDWIDTH_OBJ_MINIMUM_LENGTH);
private PcepObjectHeader bandwidthObjHeader;
private int iBandwidth;
private float iBandwidth;
/**
* Constructor to bandwidth object header and bandwidth.
......@@ -66,7 +67,7 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
* @param bandwidthObjHeader bandwidth object header
* @param iBandwidth bandwidth value
*/
public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, int iBandwidth) {
public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, float iBandwidth) {
this.bandwidthObjHeader = bandwidthObjHeader;
this.iBandwidth = iBandwidth;
}
......@@ -76,7 +77,7 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
*
* @param iBandwidth bandwidth value
*/
public PcepBandwidthObjectVer1(int iBandwidth) {
public PcepBandwidthObjectVer1(float iBandwidth) {
this.bandwidthObjHeader = DEFAULT_BANDWIDTH_OBJECT_HEADER;
this.iBandwidth = iBandwidth;
}
......@@ -100,12 +101,12 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
}
@Override
public int getBandwidth() {
public float getBandwidth() {
return this.iBandwidth;
}
@Override
public void setBandwidth(int iBandwidth) {
public void setBandwidth(float iBandwidth) {
this.iBandwidth = iBandwidth;
}
......@@ -119,12 +120,25 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
public static PcepBandwidthObject read(ChannelBuffer cb) throws PcepParseException {
PcepObjectHeader bandwidthObjHeader;
int iBandwidth;
float bandwidth;
bandwidthObjHeader = PcepObjectHeader.read(cb);
iBandwidth = cb.readInt();
bandwidth = ieeeToFloatRead(cb.readInt()) * NO_OF_BITS;
return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth);
return new PcepBandwidthObjectVer1(bandwidthObjHeader, bandwidth);
}
/**
* Parse the IEEE floating point notation and returns it in normal float.
*
* @param iVal IEEE floating point number
* @return normal float
*/
public static float ieeeToFloatRead(int iVal) {
iVal = (((iVal & 0xFF) << 24) | ((iVal & 0xFF00) << 8)
| ((iVal & 0xFF0000) >> 8) | ((iVal >> 24) & 0xFF));
return Float.intBitsToFloat(iVal);
}
@Override
......@@ -138,7 +152,7 @@ public class PcepBandwidthObjectVer1 implements PcepBandwidthObject {
throw new PcepParseException("Failed to write bandwidth object header. Index " + objLenIndex);
}
cb.writeInt(iBandwidth);
cb.writeInt(Float.floatToIntBits(iBandwidth));
short hLength = (short) (cb.writerIndex() - objStartIndex);
cb.setShort(objLenIndex, hLength);
//will be helpful during print().
......
......@@ -16,8 +16,10 @@
package org.onosproject.pcepio.protocol.ver1;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
......@@ -399,10 +401,47 @@ public class PcepEroObjectVer1 implements PcepEroObject {
}
@Override
public int hashCode() {
return Objects.hash(eroObjHeader, subObjectList);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).omitNullValues()
.add("EroObjHeader", eroObjHeader)
.add("SubObjects", subObjectList)
.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof PcepEroObjectVer1) {
int countObjSubTlv = 0;
int countOtherSubTlv = 0;
boolean isCommonSubTlv = true;
PcepEroObjectVer1 other = (PcepEroObjectVer1) obj;
Iterator<PcepValueType> objListIterator = other.subObjectList.iterator();
countOtherSubTlv = other.subObjectList.size();
countObjSubTlv = subObjectList.size();
if (countObjSubTlv != countOtherSubTlv) {
return false;
} else {
while (objListIterator.hasNext() && isCommonSubTlv) {
PcepValueType subTlv = objListIterator.next();
if (subObjectList.contains(subTlv)) {
isCommonSubTlv = Objects.equals(subObjectList.get(subObjectList.indexOf(subTlv)),
other.subObjectList.get(other.subObjectList.indexOf(subTlv)));
} else {
isCommonSubTlv = false;
}
}
return isCommonSubTlv && Objects.equals(eroObjHeader, other.eroObjHeader);
}
}
return false;
}
}
......
......@@ -57,6 +57,10 @@ public class PcepMetricObjectVer1 implements PcepMetricObject {
public static final int BFLAG_RESET = 0;
public static final byte CFLAG_CHECK = 0x02;
public static final byte IGP_METRIC = 0x01;
public static final byte TE_METRIC = 0x02;
public static final byte HOP_COUNT_METRIC = 0x03;
static final PcepObjectHeader DEFAULT_METRIC_OBJECT_HEADER = new PcepObjectHeader(METRIC_OBJ_CLASS,
METRIC_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
METRIC_OBJ_MINIMUM_LENGTH);
......
......@@ -16,6 +16,8 @@
package org.onosproject.pcepio.types;
import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -212,6 +214,27 @@ public class PcepObjectHeader {
}
@Override
public int hashCode() {
return Objects.hash(objClass, objType, bPFlag, bIFlag, objLen);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof PcepObjectHeader) {
PcepObjectHeader other = (PcepObjectHeader) obj;
return Objects.equals(objClass, other.objClass)
&& Objects.equals(objType, other.objType)
&& Objects.equals(bPFlag, other.bPFlag)
&& Objects.equals(bIFlag, other.bIFlag)
&& Objects.equals(objLen, other.objLen);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("ObjectClass", objClass)
......
......@@ -40,6 +40,11 @@
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
......
......@@ -3,6 +3,7 @@ COMPILE_DEPS = [
'//protocols/bgp/api:onos-protocols-bgp-api',
'//protocols/bgp/bgpio:onos-protocols-bgp-bgpio',
'//incubator/store:onos-incubator-store',
'//incubator/api:onos-incubator-api',
]
TEST_DEPS = [
......
......@@ -17,11 +17,16 @@ import static org.onosproject.bgp.controller.BgpDpid.uri;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Device.Type.ROUTER;
import static org.onosproject.net.Device.Type.VIRTUAL;
import static org.onosproject.incubator.net.resource.label.LabelResourceId.labelResourceId;
import static java.util.stream.Collectors.toList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ip4Address;
import org.onlab.util.Bandwidth;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -45,9 +50,21 @@ import org.onosproject.bgpio.types.IPv4AddressTlv;
import org.onosproject.bgpio.types.IsIsNonPseudonode;
import org.onosproject.bgpio.types.IsIsPseudonode;
import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.OspfNonPseudonode;
import org.onosproject.bgpio.types.OspfPseudonode;
import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
......@@ -56,12 +73,15 @@ import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
......@@ -70,6 +90,7 @@ import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -106,16 +127,39 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LabelResourceAdminService labelResourceAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetworkConfigService networkConfigService;
private DeviceProviderService deviceProviderService;
private LinkProviderService linkProviderService;
private InternalMastershipListener masterListener = new InternalMastershipListener();
private InternalBgpProvider listener = new InternalBgpProvider();
private static final String UNKNOWN = "unknown";
public static final long IDENTIFIER_SET = 0x100000000L;
public static final String AS_NUMBER = "asNumber";
public static final String DOMAIN_IDENTIFIER = "domainIdentifier";
public static final String ROUTING_UNIVERSE = "routingUniverse";
public static final String EXTERNAL_BIT = "externalBit";
public static final String ABR_BIT = "abrBit";
public static final String INTERNAL_BIT = "internalBit";
public static final String PSEUDO = "psuedo";
public static final String AREAID = "areaId";
public static final String LSRID = "lsrId";
public static final String COST = "cost";
public static final String TE_COST = "teCost";
public static final long PSEUDO_PORT = 0xffffffff;
public static final int DELAY = 2;
private LabelResourceId beginLabel = labelResourceId(5122);
private LabelResourceId endLabel = labelResourceId(9217);
@Activate
public void activate() {
......@@ -123,6 +167,7 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
deviceProviderService = deviceProviderRegistry.register(this);
linkProviderService = linkProviderRegistry.register(this);
controller.addListener(listener);
mastershipService.addListener(masterListener);
controller.addLinkListener(listener);
}
......@@ -135,6 +180,27 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
linkProviderService = null;
controller.removeListener(listener);
controller.removeLinkListener(listener);
mastershipService.removeListener(masterListener);
}
private class InternalMastershipListener implements MastershipListener {
@Override
public void event(MastershipEvent event) {
if (event.type() == MastershipEvent.Type.MASTER_CHANGED) {
if (mastershipService.getMasterFor(event.subject()) != null) {
//Only for L3 device create label pool for that device
Device device = deviceService.getDevice(event.subject());
if (device == null) {
log.debug("Device {} doesn't exist", event.subject());
return;
}
//Reserve device label pool for L3 devices
if (device.annotations().value(LSRID) != null) {
createDevicePool(event.subject());
}
}
}
}
}
/*
......@@ -146,7 +212,7 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
public void addNode(BgpNodeLSNlriVer4 nodeNlri, PathAttrNlriDetails details) {
log.debug("Add node {}", nodeNlri.toString());
if (deviceProviderService == null) {
if (deviceProviderService == null || deviceService == null) {
return;
}
Device.Type deviceType = ROUTER;
......@@ -154,6 +220,13 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
DeviceId deviceId = deviceId(uri(nodeUri.toString()));
ChassisId cId = new ChassisId();
/*
* Check if device is already there (available) , if yes not updating to core.
*/
if (deviceService.isAvailable(deviceId)) {
return;
}
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(AnnotationKeys.TYPE, "L3");
......@@ -183,11 +256,13 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
}
}
}
DefaultAnnotations.Builder anntotations = DefaultAnnotations.builder();
anntotations = getAnnotations(newBuilder, true, details);
DeviceDescription description = new DefaultDeviceDescription(uri(nodeUri.toString()), deviceType, UNKNOWN,
UNKNOWN, UNKNOWN, UNKNOWN, cId, newBuilder.build());
deviceProviderService.deviceConnected(deviceId, description);
UNKNOWN, UNKNOWN, UNKNOWN, cId, anntotations.build());
deviceProviderService.deviceConnected(deviceId, description);
}
@Override
......@@ -200,6 +275,12 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
BgpDpid deviceUri = new BgpDpid(nodeNlri);
DeviceId deviceId = deviceId(uri(deviceUri.toString()));
if (labelResourceAdminService != null) {
//Destroy local device label pool reserved for that device
labelResourceAdminService.destroyDevicePool(deviceId);
}
deviceProviderService.deviceDisconnected(deviceId);
}
......@@ -211,6 +292,24 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
return;
}
LinkDescription linkDes = buildLinkDes(linkNlri, details, true);
/*
* Update link ports and configure bandwidth on source and destination port using networkConfig service
* Only master of source link registers for bandwidth
*/
if (mastershipService.isLocalMaster(linkDes.src().deviceId())) {
registerBandwidth(linkDes, details);
}
//Updating ports of the link
List<PortDescription> srcPortDescriptions = new LinkedList<>();
srcPortDescriptions.add(new DefaultPortDescription(linkDes.src().port(), true));
deviceProviderService.updatePorts(linkDes.src().deviceId(), srcPortDescriptions);
List<PortDescription> dstPortDescriptions = new LinkedList<>();
dstPortDescriptions.add(new DefaultPortDescription(linkDes.dst().port(), true));
deviceProviderService.updatePorts(linkDes.dst().deviceId(), dstPortDescriptions);
linkProviderService.linkDetected(linkDes);
}
......@@ -273,7 +372,12 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
addOrDeletePseudoNode(isAddLink, localPseduo, remotePseduo, srcNodeNlri,
dstNodeNlri, srcId, dstId, details);
return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false);
DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
if (details != null) {
annotationBuilder = getAnnotations(annotationBuilder, false, details);
}
return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false, annotationBuilder.build());
}
private void addOrDeletePseudoNode(boolean isAddLink, boolean localPseduo, boolean remotePseduo,
......@@ -322,10 +426,140 @@ public class BgpTopologyProvider extends AbstractProvider implements DeviceProvi
}
LinkDescription linkDes = buildLinkDes(linkNlri, null, false);
/*
* Only master for the link src will release the bandwidth resource.
*/
if (networkConfigService != null && mastershipService.isLocalMaster(linkDes.src().deviceId())) {
// Releases registered resource for this link
networkConfigService.removeConfig(linkDes.src(), BandwidthCapacity.class);
networkConfigService.removeConfig(linkDes.dst(), BandwidthCapacity.class);
}
linkProviderService.linkVanished(linkDes);
}
}
// Creates label resource pool for the specific device. For all devices label range is 5122-9217
private void createDevicePool(DeviceId deviceId) {
if (labelResourceAdminService == null) {
return;
}
labelResourceAdminService.createDevicePool(deviceId, beginLabel, endLabel);
}
private void registerBandwidth(LinkDescription linkDes, PathAttrNlriDetails details) {
if (details == null) {
log.error("Couldnot able to register bandwidth ");
return;
}
List<BgpValueType> attribute = details.pathAttributes().stream()
.filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
if (attribute.isEmpty()) {
return;
}
List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
float maxReservableBw = 0;
for (BgpValueType tlv : tlvs) {
switch (tlv.getType()) {
case LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH:
maxReservableBw = ((BgpLinkAttrMaxLinkBandwidth) tlv).linkAttrMaxLinkBandwidth();
break;
default: // do nothing
}
}
if (maxReservableBw == 0.0) {
return;
}
//Configure bandwidth for src and dst port
BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
config.capacity(Bandwidth.bps(maxReservableBw)).apply();
config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
config.capacity(Bandwidth.bps(maxReservableBw)).apply();
}
private DefaultAnnotations.Builder getAnnotations(DefaultAnnotations.Builder annotationBuilder, boolean isNode,
PathAttrNlriDetails details) {
List<BgpValueType> attribute = details.pathAttributes().stream()
.filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
if (attribute.isEmpty()) {
return annotationBuilder;
}
List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
boolean abrBit = false;
boolean externalBit = false;
boolean pseudo = false;
int igpMetric = 0;
int teMetric = 0;
byte[] areaId = null;
Ip4Address routerId = null;
for (BgpValueType tlv : tlvs) {
switch (tlv.getType()) {
case LinkStateAttributes.ATTR_NODE_FLAG_BITS:
abrBit = ((BgpAttrNodeFlagBitTlv) tlv).abrBit();
externalBit = ((BgpAttrNodeFlagBitTlv) tlv).externalBit();
break;
case NodeDescriptors.IGP_ROUTERID_TYPE:
if (tlv instanceof IsIsPseudonode || tlv instanceof OspfPseudonode) {
pseudo = true;
}
break;
case LinkStateAttributes.ATTR_NODE_ISIS_AREA_ID:
areaId = ((BgpAttrNodeIsIsAreaId) tlv).attrNodeIsIsAreaId();
break;
case LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID:
routerId = ((BgpAttrRouterIdV4) tlv).attrRouterId();
break;
case LinkStateAttributes.ATTR_LINK_IGP_METRIC:
igpMetric = ((BgpLinkAttrIgpMetric) tlv).attrLinkIgpMetric();
break;
case LinkStateAttributes.ATTR_LINK_TE_DEFAULT_METRIC:
teMetric = ((BgpLinkAttrTeDefaultMetric) tlv).attrLinkDefTeMetric();
break;
default: // do nothing
}
}
// Annotations for device
if (isNode) {
boolean internalBit = false;
if (!abrBit && !externalBit) {
internalBit = true;
}
annotationBuilder.set(EXTERNAL_BIT, String.valueOf(externalBit));
annotationBuilder.set(ABR_BIT, String.valueOf(abrBit));
annotationBuilder.set(INTERNAL_BIT, String.valueOf(internalBit));
annotationBuilder.set(PSEUDO, String.valueOf(pseudo));
if (areaId != null) {
annotationBuilder.set(AREAID, new String(areaId));
}
if (routerId != null) {
// LsrID
annotationBuilder.set(LSRID, String.valueOf(routerId));
}
} else {
// Annotations for link
if (igpMetric != 0) {
annotationBuilder.set(COST, String.valueOf(igpMetric));
}
if (teMetric != 0) {
annotationBuilder.set(TE_COST, String.valueOf(teMetric));
}
}
return annotationBuilder;
}
@Override
public void triggerProbe(DeviceId deviceId) {
// TODO Auto-generated method stub
......
......@@ -16,6 +16,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.onosproject.net.Link.State.ACTIVE;
import static org.onosproject.net.MastershipRole.MASTER;
import static org.hamcrest.Matchers.nullValue;
import java.util.Collection;
import java.util.HashMap;
......@@ -29,7 +31,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ip4Address;
import org.onlab.util.Bandwidth;
import org.onosproject.bgp.controller.BgpLinkListener;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgpio.exceptions.BgpParseException;
......@@ -43,9 +49,26 @@ import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
import org.onosproject.bgpio.types.AutonomousSystemTlv;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.IsIsNonPseudonode;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourcePool;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.mastership.MastershipEvent.Type;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
import org.onosproject.bgpio.types.RouteDistinguisher;
import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
......@@ -53,6 +76,11 @@ import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
......@@ -65,6 +93,15 @@ import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.ResourceAdminService;
import org.onosproject.net.resource.ResourceId;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Test for BGP topology provider.
......@@ -73,21 +110,31 @@ public class BgpTopologyProviderTest {
private static final DeviceId DID2 = DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10");
private static final String UNKNOWN = new String("unknown");
public static ProviderId providerId = new ProviderId("l3", "foo");
private static final NodeId NODE1 = new NodeId("Master1");
private final BgpTopologyProvider provider = new BgpTopologyProvider();
private final TestDeviceRegistry nodeRegistry = new TestDeviceRegistry();
private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
private final MockBgpController controller = new MockBgpController();
private MockDeviceService deviceService = new MockDeviceService();
private MockLinkService linkService = new MockLinkService();
private MockMastershipService mastershipService = new MockMastershipService();
private MockNetConfigRegistryAdapter networkConfigService = new MockNetConfigRegistryAdapter();
private MockLabelResourceService labelResourceAdminService = new MockLabelResourceService();
private Map<DeviceId, Device> deviceMap = new HashMap<>();
private MastershipListener listener;
@Before
public void startUp() {
public void startUp() throws TestUtilsException {
provider.deviceProviderRegistry = nodeRegistry;
provider.linkProviderRegistry = linkRegistry;
provider.controller = controller;
provider.deviceService = deviceService;
provider.linkService = linkService;
provider.labelResourceAdminService = labelResourceAdminService;
provider.mastershipService = mastershipService;
provider.networkConfigService = networkConfigService;
listener = TestUtils.getField(provider, "masterListener");
provider.activate();
assertThat("device provider should be registered", not(nodeRegistry.provider));
assertThat("link provider should be registered", not(linkRegistry.linkProvider));
......@@ -101,15 +148,177 @@ public class BgpTopologyProviderTest {
provider.controller = null;
provider.deviceService = null;
provider.deviceProviderRegistry = null;
provider.linkService = null;
provider.mastershipService = null;
provider.networkConfigService = null;
provider.labelResourceAdminService = null;
assertThat(controller.nodeListener, is(new HashSet<BgpNodeListener>()));
assertThat(controller.linkListener, is(new HashSet<BgpLinkListener>()));
}
private class MockLabelResourceService implements LabelResourceAdminService {
Map<DeviceId, LabelResourcePool> resourcePool = new HashMap<>();
@Override
public boolean createDevicePool(DeviceId deviceId, LabelResourceId beginLabel, LabelResourceId endLabel) {
LabelResourcePool labelResource = new LabelResourcePool(deviceId.toString(),
beginLabel.labelId(),
endLabel.labelId());
if (resourcePool.containsValue(labelResource)) {
return false;
}
resourcePool.put(deviceId, labelResource);
return true;
}
@Override
public boolean createGlobalPool(LabelResourceId beginLabel, LabelResourceId endLabel) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean destroyDevicePool(DeviceId deviceId) {
LabelResourcePool devicePool = resourcePool.get(deviceId);
if (devicePool == null) {
return false;
}
resourcePool.remove(deviceId);
return true;
}
@Override
public boolean destroyGlobalPool() {
// TODO Auto-generated method stub
return false;
}
}
/* Mock test for device service */
private class MockNetConfigRegistryAdapter extends NetworkConfigRegistryAdapter {
private ConfigFactory cfgFactory;
private Map<ConnectPoint, BandwidthCapacity> classConfig = new HashMap<>();
@Override
public void registerConfigFactory(ConfigFactory configFactory) {
cfgFactory = configFactory;
}
@Override
public void unregisterConfigFactory(ConfigFactory configFactory) {
cfgFactory = null;
}
@Override
public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
if (configClass == BandwidthCapacity.class) {
BandwidthCapacity devCap = new BandwidthCapacity();
classConfig.put((ConnectPoint) subject, devCap);
JsonNode node = new ObjectNode(new MockJsonNode());
ObjectMapper mapper = new ObjectMapper();
ConfigApplyDelegate delegate = new InternalApplyDelegate();
devCap.init((ConnectPoint) subject, null, node, mapper, delegate);
return (C) devCap;
}
return null;
}
@Override
public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
classConfig.remove(subject);
}
@Override
public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
if (configClass == BandwidthCapacity.class) {
return (C) classConfig.get(subject);
}
return null;
}
private class MockJsonNode extends JsonNodeFactory {
}
// Auxiliary delegate to receive notifications about changes applied to
// the network configuration - by the apps.
private class InternalApplyDelegate implements ConfigApplyDelegate {
@Override
public void onApply(Config config) {
}
}
}
private class MockMastershipService extends MastershipServiceAdapter {
@Override
public MastershipRole getLocalRole(DeviceId deviceId) {
return MASTER;
}
@Override
public boolean isLocalMaster(DeviceId deviceId) {
return getLocalRole(deviceId) == MASTER;
}
@Override
public NodeId getMasterFor(DeviceId deviceId) {
return NODE1;
}
}
private class MockResourceAdminService implements ResourceAdminService {
Map<ResourceId, List<Resource>> registeredRes = new HashMap<>();
@Override
public boolean register(List<Resource> resources) {
for (Resource res : resources) {
List<Resource> resource = new LinkedList<>();
resource.add(res);
if (registeredRes.containsKey(res.id())) {
resource.addAll(registeredRes.get(res.id()));
}
registeredRes.put(res.id(), resource);
}
return true;
}
@Override
public boolean unregister(List<ResourceId> ids) {
for (ResourceId id : ids) {
if (registeredRes.containsKey(id)) {
registeredRes.remove(id);
} else {
return false;
}
}
return true;
}
}
private class MockLinkService extends LinkServiceAdapter {
@Override
public Link getLink(ConnectPoint src, ConnectPoint dst) {
for (Link link : linkRegistry.links) {
if (link.src().equals(src) && link.dst().equals(dst)) {
return link;
}
}
return null;
}
}
/* Class implement device test registry */
private class TestDeviceRegistry implements DeviceProviderRegistry {
DeviceProvider provider;
Set<DeviceId> connected = new HashSet<>();
Map<DeviceId, List<PortDescription>> portUpdated = new HashMap<>();
@Override
public DeviceProviderService register(DeviceProvider provider) {
......@@ -138,7 +347,7 @@ public class BgpTopologyProviderTest {
if (!deviceId.equals(DID2)) {
connected.add(deviceId);
Device device = new DefaultDevice(BgpTopologyProviderTest.providerId, deviceId, Device.Type.ROUTER,
UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId());
UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
deviceMap.put(deviceId, device);
}
}
......@@ -153,8 +362,7 @@ public class BgpTopologyProviderTest {
@Override
public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
// TODO Auto-generated method stub
portUpdated.put(deviceId, portDescriptions);
}
@Override
......@@ -202,9 +410,14 @@ public class BgpTopologyProviderTest {
@Override
public void linkDetected(LinkDescription linkDescription) {
links.add(DefaultLink.builder().src(linkDescription.src())
.dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
.providerId(BgpTopologyProviderTest.providerId).build());
links.add(DefaultLink.builder()
.src(linkDescription.src())
.dst(linkDescription.dst())
.state(ACTIVE)
.type(linkDescription.type())
.providerId(BgpTopologyProviderTest.providerId)
.annotations(linkDescription.annotations())
.build());
}
@Override
......@@ -349,6 +562,59 @@ public class BgpTopologyProviderTest {
}
}
/**
* Validate node is added to the device with all device annotations.
*/
@Test
public void bgpTopologyProviderTestAddDevice4() {
LinkedList<BgpValueType> subTlvs = new LinkedList<>();
BgpValueType tlv = new AutonomousSystemTlv(100);
short deslength = AutonomousSystemTlv.LENGTH;
short desType = AutonomousSystemTlv.TYPE;
subTlvs.add(tlv);
BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
desType));
BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
new RouteDistinguisher());
PathAttrNlriDetails details = new PathAttrNlriDetails();
details.setIdentifier(0);
details.setProtocolID(ProtocolType.DIRECT);
List<BgpValueType> pathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttr = new LinkedList<>();
tlv = BgpAttrNodeFlagBitTlv.of(true, true, true, false);
linkStateAttr.add(tlv);
tlv = BgpAttrNodeIsIsAreaId.of(new byte[] {01, 01, 01, 01});
linkStateAttr.add(tlv);
tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
linkStateAttr.add(tlv);
pathAttributes.add(new LinkStateAttributes(linkStateAttr));
details.setPathAttribute(pathAttributes);
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.ABR_BIT),
is("false"));
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.EXTERNAL_BIT),
is("true"));
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.INTERNAL_BIT),
is("false"));
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.PSEUDO),
is("false"));
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.AREAID).getBytes(),
is(new byte[] {01, 01, 01, 01}));
assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.LSRID),
is("1.1.1.1"));
assertThat(nodeRegistry.connected.size(), is(1));
l.deleteNode(nodeNlri);
assertThat(nodeRegistry.connected.size(), is(0));
}
}
/**
* Add a link and two devices.
*
......@@ -460,6 +726,82 @@ public class BgpTopologyProviderTest {
}
/**
* Add a link and delete a link with registering/unregistering bandwidth.
*
* @throws BgpParseException while adding or removing the link
* @throws InterruptedException while registering for bandwidth
*/
@Test
public void bgpTopologyProviderTestAddLink3() throws BgpParseException, InterruptedException {
LinkedList<BgpValueType> localTlvs = new LinkedList<>();
LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
LinkedList<BgpValueType> linkdes = new LinkedList<>();
BgpValueType tlv = new AutonomousSystemTlv(10);
short deslength = AutonomousSystemTlv.LENGTH;
short desType = AutonomousSystemTlv.TYPE;
localTlvs.add(tlv);
remoteTlvs.add(tlv);
tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
localTlvs.add(tlv);
tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
remoteTlvs.add(tlv);
NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
new RouteDistinguisher());
BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
new RouteDistinguisher());
PathAttrNlriDetails details = new PathAttrNlriDetails();
details.setIdentifier(0);
details.setProtocolID(ProtocolType.DIRECT);
List<BgpValueType> pathAttributes = new LinkedList<>();
details.setPathAttribute(pathAttributes);
tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
linkdes.add(tlv);
BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
new RouteDistinguisher(), false);
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
l.addNode(remNodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(2));
l.deleteNode(remNodeNlri);
assertThat(nodeRegistry.connected.size(), is(1));
}
List<BgpValueType> linkPathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttr = new LinkedList<>();
tlv = BgpLinkAttrIgpMetric.of(10, 4);
linkStateAttr.add(tlv);
tlv = BgpLinkAttrTeDefaultMetric.of(20);
linkStateAttr.add(tlv);
tlv = BgpLinkAttrMaxLinkBandwidth.of(30, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
linkStateAttr.add(tlv);
linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
details.setPathAttribute(linkPathAttributes);
for (BgpLinkListener l : controller.linkListener) {
l.addLink(linkNlri, details);
assertThat(linkRegistry.links.size(), is(1));
assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
is("10"));
assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
is("20"));
l.deleteLink(linkNlri);
assertThat(linkRegistry.links.size(), is(0));
}
}
/**
* Invalid link.
*
* @throws BgpParseException while adding or deleting a link
......@@ -512,4 +854,188 @@ public class BgpTopologyProviderTest {
assertThat(linkRegistry.links.size(), is(0));
}
}
/**
* Add device check label registration is done.
*
* @throws BgpParseException while adding a device
*/
@Test
public void bgpTopologyProviderDeviceTestLabel1() throws BgpParseException {
LinkedList<BgpValueType> subTlvs = new LinkedList<>();
BgpValueType tlv = new AutonomousSystemTlv(100);
short deslength = AutonomousSystemTlv.LENGTH;
short desType = AutonomousSystemTlv.TYPE;
subTlvs.add(tlv);
BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
desType));
BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
new RouteDistinguisher());
PathAttrNlriDetails details = new PathAttrNlriDetails();
details.setIdentifier(0);
details.setProtocolID(ProtocolType.DIRECT);
List<BgpValueType> pathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttributes = new LinkedList<>();
tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
linkStateAttributes.add(tlv);
pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
details.setPathAttribute(pathAttributes);
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
}
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
}
/**
* Add device check label registration is done and delete node destroy label pool.
*
* @throws BgpParseException while adding a device
*/
@Test
public void bgpTopologyProviderDeviceTestLabel2() throws BgpParseException {
LinkedList<BgpValueType> subTlvs = new LinkedList<>();
BgpValueType tlv = new AutonomousSystemTlv(100);
short deslength = AutonomousSystemTlv.LENGTH;
short desType = AutonomousSystemTlv.TYPE;
subTlvs.add(tlv);
BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
desType));
BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
new RouteDistinguisher());
PathAttrNlriDetails details = new PathAttrNlriDetails();
details.setIdentifier(0);
details.setProtocolID(ProtocolType.DIRECT);
List<BgpValueType> pathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttributes = new LinkedList<>();
tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
linkStateAttributes.add(tlv);
pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
details.setPathAttribute(pathAttributes);
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
// Check label resource reserved for that device
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
l.deleteNode(nodeNlri);
assertThat(nodeRegistry.connected.size(), is(0));
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(0));
}
}
/**
* Add a link register bandwidth and remove link unregister bandwidth.
*
* @throws BgpParseException while registering/unregistering bandwidth
*/
@Test
public void bgpTopologyProviderDeviceTestLabel3() throws BgpParseException {
LinkedList<BgpValueType> localTlvs = new LinkedList<>();
LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
LinkedList<BgpValueType> linkdes = new LinkedList<>();
BgpValueType tlv = new AutonomousSystemTlv(10);
short deslength = AutonomousSystemTlv.LENGTH;
short desType = AutonomousSystemTlv.TYPE;
localTlvs.add(tlv);
remoteTlvs.add(tlv);
tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
localTlvs.add(tlv);
tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
remoteTlvs.add(tlv);
NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
new RouteDistinguisher());
BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
new RouteDistinguisher());
PathAttrNlriDetails details = new PathAttrNlriDetails();
details.setIdentifier(0);
details.setProtocolID(ProtocolType.DIRECT);
List<BgpValueType> pathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttributes = new LinkedList<>();
tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
linkStateAttributes.add(tlv);
pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
details.setPathAttribute(pathAttributes);
tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
linkdes.add(tlv);
BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
new RouteDistinguisher(), false);
for (BgpNodeListener l : controller.nodeListener) {
l.addNode(nodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(1));
//Check label resource reserved for that device
MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
listener.event(event);
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
l.addNode(remNodeNlri, details);
assertThat(nodeRegistry.connected.size(), is(2));
l.deleteNode(remNodeNlri);
assertThat(nodeRegistry.connected.size(), is(1));
assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
}
List<BgpValueType> linkPathAttributes = new LinkedList<>();
List<BgpValueType> linkStateAttr = new LinkedList<>();
tlv = BgpLinkAttrIgpMetric.of(10, 4);
linkStateAttr.add(tlv);
tlv = BgpLinkAttrTeDefaultMetric.of(20);
linkStateAttr.add(tlv);
tlv = BgpLinkAttrMaxLinkBandwidth.of(70, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
linkStateAttr.add(tlv);
linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
details.setPathAttribute(linkPathAttributes);
for (BgpLinkListener l : controller.linkListener) {
l.addLink(linkNlri, details);
assertThat(linkRegistry.links.size(), is(1));
assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
is("10"));
assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
is("20"));
ConnectPoint src = new ConnectPoint(
DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1414.1414.0014"),
PortNumber.portNumber(4294967395L));
ConnectPoint dst = new ConnectPoint(
DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1e1e.1e1e.001e"),
PortNumber.portNumber(4294967396L));
BandwidthCapacity bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
assertThat(bandwidth.capacity().bps(), is(70.0 * 1_000_000L));
bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
assertThat(bandwidth.capacity(), is(Bandwidth.bps(70.0 * 1_000_000L)));
l.deleteLink(linkNlri);
assertThat(linkRegistry.links.size(), is(0));
bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
assertThat(bandwidth, is(nullValue()));
bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
assertThat(bandwidth, is(nullValue()));
}
}
}
......
<!--
~ Copyright 2016-present Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-providers</artifactId>
<version>1.6.0-SNAPSHOT</version>
</parent>
<artifactId>onos-pcep-provider-packet</artifactId>
<packaging>bundle</packaging>
<description>PCEP packet provider</description>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-controller-api</artifactId>
</dependency>
</dependencies>
</project>
package org.onosproject.provider.pcep.packet.impl;
import static org.slf4j.LoggerFactory.getLogger;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.TCP;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketProvider;
import org.onosproject.net.packet.PacketProviderRegistry;
import org.onosproject.net.packet.PacketProviderService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepPacketListener;
import org.slf4j.Logger;
/**
* Provider which uses an PCEP controller to process packets.
*/
@Component(immediate = true)
@Service
public class PcepPacketProvider extends AbstractProvider implements PacketProvider {
private static final Logger log = getLogger(PcepPacketProvider.class);
static final String PROVIDER_ID = "org.onosproject.provider.packet.pcep";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketProviderRegistry packetProviderRegistry;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PcepClientController pcepClientController;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
PacketProviderService packetProviderService;
private InnerPacketProvider listener = new InnerPacketProvider();
public static final String LSRID = "lsrId";
public static final int PCEP_PORT = 4189;
/**
* Creates a Packet provider.
*/
public PcepPacketProvider() {
super(new ProviderId("pcep", PROVIDER_ID));
}
@Activate
public void activate() {
packetProviderService = packetProviderRegistry.register(this);
pcepClientController.addPacketListener(listener);
log.info("Started");
}
@Deactivate
public void deactivate() {
packetProviderRegistry.unregister(this);
pcepClientController.removePacketListener(listener);
log.info("Stopped");
}
private class InnerPacketProvider implements PcepPacketListener {
@Override
public void sendPacketIn(PccId pccId) {
TCP tcp = new TCP();
// Set the well known PCEP port. To be used to decide to process/discard the packet while processing.
tcp.setDestinationPort(PCEP_PORT);
IPv4 ipv4 = new IPv4();
ipv4.setProtocol(IPv4.PROTOCOL_TCP);
ipv4.setPayload(tcp);
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
// Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
String lsrId = String.valueOf(pccId.ipAddress());
DeviceId pccDeviceId = null;
// Find PCC deviceID from lsrId stored as annotations
Iterable<Device> devices = deviceService.getAvailableDevices();
for (Device dev : devices) {
if ("L3".equals(dev.annotations().value(AnnotationKeys.TYPE))
&& lsrId.equals(dev.annotations().value(LSRID))) {
pccDeviceId = dev.id();
break;
}
}
if (pccDeviceId == null) {
return;
}
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(pccDeviceId,
PortNumber.portNumber(PCEP_PORT)),
eth, null);
packetProviderService.processPacket(new PcepPacketContext(inPkt, null));
}
}
// Minimal PacketContext to make core and applications happy.
private final class PcepPacketContext extends DefaultPacketContext {
private PcepPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
super(System.currentTimeMillis(), inPkt, outPkt, false);
}
@Override
public void send() {
// We don't send anything out.
return;
}
}
@Override
public void emit(OutboundPacket packet) {
// Nothing to emit
return;
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*Provider that uses PCEP controller as a means to send packets.
*/
package org.onosproject.provider.pcep.packet.impl;
\ No newline at end of file
......@@ -27,5 +27,6 @@
<module>topology</module>
<module>tunnel</module>
<module>app</module>
<module>packet</module>
</modules>
</project>
\ No newline at end of file
......
......@@ -3,6 +3,9 @@ COMPILE_DEPS = [
'//protocols/ovsdb/api:onos-protocols-ovsdb-api',
'//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
'//apps/pcep-api:onos-apps-pcep-api',
'//protocols/pcep/api:onos-protocols-pcep-api',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//core/api:onos-api-tests',
]
osgi_jar_with_tests (
......
......@@ -23,10 +23,20 @@
<artifactId>onos-pcep-provider-topology</artifactId>
<packaging>bundle</packaging>
<description>PCEP topology provider</description>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-pcep-api</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-pcep-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-controller-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......
......@@ -62,6 +62,10 @@ import org.onosproject.pcep.api.PcepLinkListener;
import org.onosproject.pcep.api.PcepOperator.OperationType;
import org.onosproject.pcep.api.PcepSwitch;
import org.onosproject.pcep.api.PcepSwitchListener;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepNodeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -115,18 +119,40 @@ public class PcepTopologyProvider extends AbstractProvider
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PcepClientController pcepClientController;
private DeviceProviderService deviceProviderService;
private LinkProviderService linkProviderService;
private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
private InternalLinkProvider listener = new InternalLinkProvider();
/*
* For the client supporting SR capability.
*/
public static final String SR_CAPABILITY = "srCapability";
/*
* For the client supporting PCECC capability.
*/
public static final String PCECC_CAPABILITY = "pceccCapability";
/*
* For the client supporting label stack capability.
*/
public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
public static final String LSRID = "lsrId";
private static final String UNKNOWN = "unknown";
@Activate
public void activate() {
linkProviderService = linkProviderRegistry.register(this);
deviceProviderService = deviceProviderRegistry.register(this);
controller.addListener(listener);
controller.addLinkListener(listener);
pcepClientController.addNodeListener(listener);
}
@Deactivate
......@@ -135,6 +161,7 @@ public class PcepTopologyProvider extends AbstractProvider
linkProviderService = null;
controller.removeListener(listener);
controller.removeLinkListener(listener);
pcepClientController.removeNodeListener(listener);
}
private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
......@@ -225,7 +252,7 @@ public class PcepTopologyProvider extends AbstractProvider
}
private class InternalLinkProvider
implements PcepSwitchListener, PcepLinkListener {
implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
@Override
public void switchAdded(PcepDpid dpid) {
......@@ -306,6 +333,51 @@ public class PcepTopologyProvider extends AbstractProvider
}
}
@Override
public void addNode(PcepClient pc) {
if (deviceProviderService == null) {
return;
}
//Right now device URI for PCEP devices is their LSRID
DeviceId deviceId = deviceId(uri(new PcepDpid(pc.getPccId().id().getIp4Address().toInt())));
ChassisId cId = new ChassisId();
Device.Type deviceType = Device.Type.ROUTER;
DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
//PCC capabilities (SR, PCECC and PCECC-SR)
annotationBuilder.set(SR_CAPABILITY, String.valueOf(pc.capability().srCapability()));
annotationBuilder.set(PCECC_CAPABILITY, String.valueOf(pc.capability().pceccCapability()));
annotationBuilder.set(LABEL_STACK_CAPABILITY, String.valueOf(pc.capability().labelStackCapability()));
//PccId is the lsrId contained in openMsg, if not present it will be the socket address
annotationBuilder.set(LSRID, String.valueOf(pc.getPccId().id()));
DeviceDescription description = new DefaultDeviceDescription(
deviceId.uri(),
deviceType,
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
cId,
annotationBuilder.build());
deviceProviderService.deviceConnected(deviceId, description);
}
@Override
public void deleteNode(PccId pccId) {
if (deviceProviderService == null || deviceService == null) {
return;
}
//TODO: In device manager, in deviceDisconnected() method, get the device but null check is not validated
if (deviceService.getDevice(DeviceId.deviceId(uri(new PcepDpid(pccId.id()
.getIp4Address().toInt())))) == null) {
return;
}
deviceProviderService.deviceDisconnected(deviceId(uri(new PcepDpid(pccId.id().getIp4Address().toInt()))));
}
}
@Override
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.pcep.topology.impl;
import static org.junit.Assert.assertNotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepVersion;
/**
* Representation of PCEP client adapter.
*/
public class PcepClientAdapter implements PcepClient {
private Channel channel;
protected String channelId;
private boolean connected;
private PccId pccId;
private ClientCapability capability;
private PcepVersion pcepVersion;
private PcepSyncStatus lspDbSyncStatus;
private PcepSyncStatus labelDbSyncStatus;
private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
/**
* Initialize instance with specified parameters.
*
* @param pccId PCC id
* @param pcepVersion PCEP message version
*/
public void init(PccId pccId, PcepVersion pcepVersion) {
this.pccId = pccId;
this.pcepVersion = pcepVersion;
}
@Override
public final void disconnectClient() {
this.channel.close();
}
@Override
public final void sendMessage(PcepMessage m) {
}
@Override
public final void sendMessage(List<PcepMessage> msgs) {
try {
PcepMessage pcepMsg = msgs.get(0);
assertNotNull("PCEP MSG should be created.", pcepMsg);
} catch (RejectedExecutionException e) {
throw e;
}
}
@Override
public final boolean isConnected() {
return this.connected;
}
@Override
public String channelId() {
return channelId;
}
@Override
public final PccId getPccId() {
return this.pccId;
};
@Override
public final String getStringId() {
return this.pccId.toString();
}
@Override
public final void handleMessage(PcepMessage m) {
}
@Override
public boolean isOptical() {
return false;
}
@Override
public PcepFactory factory() {
return PcepFactories.getFactory(pcepVersion);
}
@Override
public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
this.lspDbSyncStatus = syncStatus;
}
@Override
public PcepSyncStatus lspDbSyncStatus() {
return lspDbSyncStatus;
}
@Override
public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
this.labelDbSyncStatus = syncStatus;
}
@Override
public PcepSyncStatus labelDbSyncStatus() {
return labelDbSyncStatus;
}
@Override
public void setCapability(ClientCapability capability) {
this.capability = capability;
}
@Override
public ClientCapability capability() {
return capability;
}
@Override
public void addNode(PcepClient pc) {
}
@Override
public void deleteNode(PccId pccId) {
}
@Override
public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
lspDelegationInfo.put(lspKey, dFlag);
}
@Override
public Boolean delegationInfo(LspKey lspKey) {
return lspDelegationInfo.get(lspKey);
}
@Override
public void initializeSyncMsgList(PccId pccId) {
// TODO Auto-generated method stub
}
@Override
public List<PcepStateReport> getSyncMsgList(PccId pccId) {
// TODO Auto-generated method stub
return null;
}
@Override
public void removeSyncMsgList(PccId pccId) {
// TODO Auto-generated method stub
}
@Override
public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
// TODO Auto-generated method stub
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.pcep.topology.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.packet.IpAddress;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.PcepNodeListener;
import org.onosproject.pcep.controller.PcepPacketListener;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
import org.onosproject.pcepio.protocol.PcepErrorMsg;
import org.onosproject.pcepio.protocol.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepVersion;
import com.google.common.collect.Sets;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
/**
* Representation of PCEP client controller adapter.
*/
public class PcepClientControllerAdapter implements PcepClientController {
protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
new ConcurrentHashMap<PccId, PcepClient>();
protected PcepClientAgent agent = new PcepClientAgent();
protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
@Activate
public void activate() {
}
@Deactivate
public void deactivate() {
}
@Override
public Collection<PcepClient> getClients() {
return connectedClients.values();
}
@Override
public PcepClient getClient(PccId pccId) {
if (null != connectedClients.get(pccId)) {
return connectedClients.get(pccId);
}
PcepClientAdapter pc = new PcepClientAdapter();
if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
|| pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
pc.setCapability(new ClientCapability(true, false, false, false, false));
} else {
pc.setCapability(new ClientCapability(true, true, true, false, false));
}
pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
connectedClients.put(pccId, pc);
return pc;
}
@Override
public void addListener(PcepClientListener listener) {
if (!pcepClientListener.contains(listener)) {
this.pcepClientListener.add(listener);
}
}
@Override
public void addNodeListener(PcepNodeListener listener) {
pcepNodeListener.add(listener);
}
@Override
public void removeNodeListener(PcepNodeListener listener) {
pcepNodeListener.remove(listener);
}
@Override
public void removeListener(PcepClientListener listener) {
this.pcepClientListener.remove(listener);
}
@Override
public void addEventListener(PcepEventListener listener) {
pcepEventListener.add(listener);
}
@Override
public void removeEventListener(PcepEventListener listener) {
pcepEventListener.remove(listener);
}
@Override
public void writeMessage(PccId pccId, PcepMessage msg) {
this.getClient(pccId).sendMessage(msg);
}
@Override
public void processClientMessage(PccId pccId, PcepMessage msg) {
PcepClient pc = getClient(pccId);
switch (msg.getType()) {
case NONE:
break;
case OPEN:
break;
case KEEP_ALIVE:
//log.debug("Sending Keep Alive Message to {" + pccIpAddress.toString() + "}");
pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build()));
break;
case PATH_COMPUTATION_REQUEST:
break;
case PATH_COMPUTATION_REPLY:
break;
case NOTIFICATION:
break;
case ERROR:
break;
case CLOSE:
//log.debug("Sending Close Message to { }", pccIpAddress.toString());
pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
break;
case INITIATE:
if (!pc.capability().pcInstantiationCapability()) {
pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
ERROR_TYPE_19, ERROR_VALUE_5)));
}
break;
case REPORT:
//Only update the listener if respective capability is supported else send PCEP-ERR msg
if (pc.capability().statefulPceCapability()) {
for (PcepEventListener l : pcepEventListener) {
l.handleMessage(pccId, msg);
}
} else {
// Send PCEP-ERROR message.
pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
ERROR_TYPE_19, ERROR_VALUE_5)));
}
break;
case UPDATE:
if (!pc.capability().statefulPceCapability()) {
pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
ERROR_TYPE_19, ERROR_VALUE_5)));
}
break;
case LABEL_UPDATE:
if (!pc.capability().pceccCapability()) {
pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
ERROR_TYPE_19, ERROR_VALUE_5)));
}
break;
case MAX:
break;
case END:
break;
default:
break;
}
}
@Override
public void closeConnectedClients() {
PcepClient pc;
for (PccId id : connectedClients.keySet()) {
pc = getClient(id);
pc.disconnectClient();
}
}
private PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
LinkedList<PcepError> llPcepErr = new LinkedList<>();
LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
PcepErrorMsg errMsg;
PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
.build();
llerrObj.add(errObj);
PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
llPcepErr.add(pcepErr);
PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
return errMsg;
}
/**
* Implementation of an Pcep Agent which is responsible for
* keeping track of connected clients and the state in which
* they are.
*/
public class PcepClientAgent implements PcepAgent {
@Override
public boolean addConnectedClient(PccId pccId, PcepClient pc) {
if (connectedClients.get(pccId) != null) {
return false;
} else {
connectedClients.put(pccId, pc);
for (PcepClientListener l : pcepClientListener) {
l.clientConnected(pccId);
}
return true;
}
}
@Override
public boolean validActivation(PccId pccId) {
if (connectedClients.get(pccId) == null) {
//log.error("Trying to activate client but is not in "
// + "connected switches: pccIp {}. Aborting ..", pccIpAddress.toString());
return false;
}
return true;
}
@Override
public void removeConnectedClient(PccId pccId) {
connectedClients.remove(pccId);
for (PcepClientListener l : pcepClientListener) {
//log.warn("removal for {}", pccIpAddress.toString());
l.clientDisconnected(pccId);
}
}
@Override
public void processPcepMessage(PccId pccId, PcepMessage m) {
processClientMessage(pccId, m);
}
@Override
public void addNode(PcepClient pc) {
for (PcepNodeListener l : pcepNodeListener) {
l.addNode(pc);
}
}
@Override
public void deleteNode(PccId pccId) {
for (PcepNodeListener l : pcepNodeListener) {
l.deleteNode(pccId);
}
}
@Override
public boolean analyzeSyncMsgList(PccId pccId) {
// TODO Auto-generated method stub
return false;
}
}
@Override
public void addPacketListener(PcepPacketListener listener) {
// TODO Auto-generated method stub
}
@Override
public void removePacketListener(PcepPacketListener listener) {
// TODO Auto-generated method stub
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.pcep.topology.impl;
import org.onosproject.net.DeviceId;
import org.onosproject.pcep.api.PcepController;
import org.onosproject.pcep.api.PcepDpid;
import org.onosproject.pcep.api.PcepLinkListener;
import org.onosproject.pcep.api.PcepSwitch;
import org.onosproject.pcep.api.PcepSwitchListener;
import org.onosproject.pcep.api.PcepTunnel;
import org.onosproject.pcep.api.PcepTunnelListener;
/**
* Implementation of PCEP controller.
*/
public class PcepControllerAdapter implements PcepController {
@Override
public Iterable<PcepSwitch> getSwitches() {
return null;
}
@Override
public PcepSwitch getSwitch(PcepDpid did) {
return null;
}
@Override
public void addListener(PcepSwitchListener listener) {
}
@Override
public void removeListener(PcepSwitchListener listener) {
}
@Override
public void addLinkListener(PcepLinkListener listener) {
}
@Override
public void removeLinkListener(PcepLinkListener listener) {
}
@Override
public void addTunnelListener(PcepTunnelListener listener) {
}
@Override
public void removeTunnelListener(PcepTunnelListener listener) {
}
@Override
public PcepTunnel applyTunnel(DeviceId srcDid, DeviceId dstDid, long srcPort, long dstPort, long bandwidth,
String name) {
return null;
}
@Override
public Boolean deleteTunnel(String id) {
return null;
}
@Override
public Boolean updateTunnelBandwidth(String id, long bandwidth) {
return null;
}
@Override
public void getTunnelStatistics(String pcepTunnelId) {
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.onosproject.provider.pcep.topology.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.onosproject.net.Link.State.ACTIVE;
import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LABEL_STACK_CAPABILITY;
import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LSRID;
import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.PCECC_CAPABILITY;
import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.SR_CAPABILITY;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepNodeListener;
/**
* Test for PCEP topology provider.
*/
public class PcepTopologyProviderTest {
private static final String UNKNOWN = new String("unknown");
public static ProviderId providerId = new ProviderId("l3", "foo");
private final PcepClientControllerAdapter clientController = new PcepClientControllerAdapter();
private final PcepTopologyProvider provider = new PcepTopologyProvider();
private final MockDeviceRegistry nodeRegistry = new MockDeviceRegistry();
private final PcepControllerAdapter controller = new PcepControllerAdapter();
private final MockLinkRegistry linkRegistry = new MockLinkRegistry();
private final MockDeviceService deviceService = new MockDeviceService();
private Map<DeviceId, Device> deviceMap = new HashMap<>();
@Before
public void startUp() {
provider.pcepClientController = clientController;
provider.deviceProviderRegistry = nodeRegistry;
provider.linkProviderRegistry = linkRegistry;
provider.controller = controller;
provider.deviceService = deviceService;
provider.activate();
}
@After
public void tearDown() {
provider.deactivate();
provider.deviceProviderRegistry = null;
provider.pcepClientController = null;
provider.linkProviderRegistry = null;
provider.controller = null;
provider.deviceService = null;
}
/* Class implement device test registry */
private class MockLinkRegistry implements LinkProviderRegistry {
LinkProvider linkProvider;
Set<Link> links = new HashSet<>();
@Override
public LinkProviderService register(LinkProvider provider) {
this.linkProvider = provider;
return new MockProviderService();
}
@Override
public void unregister(LinkProvider provider) {
// TODO Auto-generated method stub
}
@Override
public Set<ProviderId> getProviders() {
return null;
}
private class MockProviderService implements LinkProviderService {
@Override
public void linkDetected(LinkDescription linkDescription) {
links.add(DefaultLink.builder().src(linkDescription.src())
.dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
.providerId(ProviderId.NONE).build());
}
@Override
public void linkVanished(LinkDescription linkDescription) {
links.remove(DefaultLink.builder().src(linkDescription.src())
.dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
.providerId(ProviderId.NONE).build());
}
@Override
public void linksVanished(ConnectPoint connectPoint) {
// TODO Auto-generated method stub
}
@Override
public void linksVanished(DeviceId deviceId) {
// TODO Auto-generated method stub
}
@Override
public LinkProvider provider() {
// TODO Auto-generated method stub
return null;
}
}
}
/* Class implement device test registry */
private class MockDeviceRegistry implements DeviceProviderRegistry {
DeviceProvider provider;
Set<DeviceId> connected = new HashSet<>();
@Override
public DeviceProviderService register(DeviceProvider provider) {
this.provider = provider;
return new MockProviderService();
}
@Override
public void unregister(DeviceProvider provider) {
}
@Override
public Set<ProviderId> getProviders() {
return null;
}
private class MockProviderService implements DeviceProviderService {
@Override
public DeviceProvider provider() {
return null;
}
@Override
public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {
connected.add(deviceId);
Device device = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.ROUTER, UNKNOWN, UNKNOWN,
UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
deviceMap.put(deviceId, device);
}
@Override
public void deviceDisconnected(DeviceId deviceId) {
connected.remove(deviceId);
deviceMap.remove(deviceId);
}
@Override
public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
// TODO Auto-generated method stub
}
@Override
public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
// TODO Auto-generated method stub
}
@Override
public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response) {
// TODO Auto-generated method stub
}
@Override
public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
// TODO Auto-generated method stub
}
}
}
/* Mock test for device service */
private class MockDeviceService extends DeviceServiceAdapter {
@Override
public Device getDevice(DeviceId deviceId) {
return deviceMap.get(deviceId);
}
}
/**
* Adds the PCEP device and removes it.
*/
@Test
public void testPcepTopologyProviderTestAddDevice1() {
PcepClient pc = clientController.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1")));
for (PcepNodeListener l : clientController.pcepNodeListener) {
pc.setCapability(new ClientCapability(true, true, false, true, true));
l.addNode(pc);
assertThat(nodeRegistry.connected.size(), is(1));
assertThat(deviceMap.keySet().iterator().next(), is(DeviceId.deviceId("l3:1.1.1.1")));
assertThat(deviceMap.values().iterator().next().annotations().value(LABEL_STACK_CAPABILITY), is("true"));
assertThat(deviceMap.values().iterator().next().annotations().value(LSRID), is("1.1.1.1"));
assertThat(deviceMap.values().iterator().next().annotations().value(PCECC_CAPABILITY), is("true"));
assertThat(deviceMap.values().iterator().next().annotations().value(SR_CAPABILITY), is("true"));
l.deleteNode(pc.getPccId());
assertThat(nodeRegistry.connected.size(), is(0));
}
}
}
......@@ -6,6 +6,7 @@ COMPILE_DEPS = [
'//incubator/api:onos-incubator-api',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//protocols/pcep/api:onos-protocols-pcep-api',
'//protocols/pcep/ctl:onos-protocols-pcep-ctl',
]
TEST_DEPS = [
......
......@@ -49,5 +49,10 @@
<version>${project.version} </version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-controller-impl</artifactId>
<version>${project.version} </version>
</dependency>
</dependencies>
</project>
......
......@@ -36,6 +36,7 @@ import org.onosproject.incubator.net.tunnel.OpticalLogicId;
import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelDescription;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
......@@ -45,11 +46,14 @@ import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelStatistics;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.IpElementId;
......@@ -57,6 +61,7 @@ import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.api.PcepController;
......@@ -68,12 +73,14 @@ import org.onosproject.pcep.api.PcepTunnel.PathState;
import org.onosproject.pcep.api.PcepTunnel.PathType;
import org.onosproject.pcep.api.PcepTunnelListener;
import org.onosproject.pcep.api.PcepTunnelStatistics;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.PcepLspSyncAction;
import org.onosproject.pcep.controller.impl.PcepLspStatus;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
import org.onosproject.pcepio.protocol.PcepAttribute;
......@@ -83,6 +90,7 @@ import org.onosproject.pcepio.protocol.PcepEroObject;
import org.onosproject.pcepio.protocol.PcepInitiateMsg;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMetricObject;
import org.onosproject.pcepio.protocol.PcepMsgPath;
import org.onosproject.pcepio.protocol.PcepReportMsg;
import org.onosproject.pcepio.protocol.PcepSrpObject;
......@@ -107,8 +115,10 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
......@@ -125,14 +135,18 @@ import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LOCAL
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCE_INIT;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.COST_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
import static org.slf4j.LoggerFactory.getLogger;
/**
......@@ -148,6 +162,11 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
private static final long MIN_BANDWIDTH = 64;
private static final String BANDWIDTH_UINT = "kbps";
static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
public static final long IDENTIFIER_SET = 0x100000000L;
public static final long SET = 0xFFFFFFFFL;
private static final int DELAY = 2;
private static final int WAIT_TIME = 5;
public static final String LSRID = "lsrId";
static final int POLL_INTERVAL = 10;
@Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
......@@ -171,6 +190,15 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TunnelAdminService tunnelAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
TunnelProviderService service;
HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
......@@ -182,10 +210,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
private static final int DEFAULT_BANDWIDTH_VALUE = 10;
private Map<IpAddress, Map<TunnelId, Tunnel>> preSyncLspDbMap = new HashMap<>();
private Map<IpAddress, List<Tunnel>> syncCompleteDeleteList = new HashMap<>();
private Map<IpAddress, List<Tunnel>> syncCompleteUpdateList = new HashMap<>();
/**
* Creates a Tunnel provider.
*/
......@@ -263,7 +287,8 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
//If stateful and PC Initiation capability is not supported by client not sending Initiate msg
if (pc.capability().pcInstantiationCapability()) {
//Only master will initiate setup tunnel
if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepSetupTunnel(tunnel, path, pc);
}
}
......@@ -300,7 +325,10 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (pc.capability().pcInstantiationCapability()) {
//If stateful and PC Initiation capability is not supported by client not sending Initiate msg
//Only master will initiate setup tunnel
if (pc.capability().pcInstantiationCapability()
&& mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepSetupTunnel(tunnel, path, pc);
}
}
......@@ -327,7 +355,9 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (pc.capability().pcInstantiationCapability()) {
//Only master will release tunnel
if (pc.capability().pcInstantiationCapability()
&& mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepReleaseTunnel(tunnel, pc);
}
}
......@@ -358,7 +388,9 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (pc.capability().pcInstantiationCapability()) {
//Only master will release tunnel
if (pc.capability().pcInstantiationCapability()
&& mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepReleaseTunnel(tunnel, pc);
}
}
......@@ -384,7 +416,12 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (pc.capability().statefulPceCapability()) {
// If delegation flag is set then only send update message[means delegated PCE can send update msg for that
// LSP].If annotation is null D flag is not set else it is set.
if (pc.capability().statefulPceCapability()
&& pc.delegationInfo(
new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
.annotations().value(LOCAL_LSP_ID)))) != null) {
pcepUpdateTunnel(tunnel, path, pc);
}
}
......@@ -416,7 +453,12 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (pc.capability().statefulPceCapability()) {
// If delegation flag is set then only send update message[means delegated PCE can send update msg for that
// LSP].If annotation is null D flag is not set else it is set.
if (pc.capability().statefulPceCapability()
&& pc.delegationInfo(
new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
.annotations().value(LOCAL_LSP_ID)))) != null) {
pcepUpdateTunnel(tunnel, path, pc);
}
}
......@@ -480,6 +522,43 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return tunnelId;
}
private void tunnelUpdated(Tunnel tunnel, Path path) {
handleTunnelUpdate(tunnel, path);
}
//Handles tunnel updated using tunnel admin service[specially to update annotations].
private void handleTunnelUpdate(Tunnel tunnel, Path path) {
if (tunnel.type() == MPLS) {
pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
tunnelAdminService.updateTunnel(tunnel, path);
return;
}
Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
if (tunnelOld.type() != Tunnel.Type.VLAN) {
error("Illegal tunnel type. Only support VLAN tunnel update.");
return;
}
long bandwidth = Long
.parseLong(tunnel.annotations().value("bandwidth"));
if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
error("Update failed, invalid bandwidth.");
return;
}
String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
checkNotNull(pcepTunnelId, "Invalid tunnel id");
if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
error("Update failed,maybe invalid bandwidth.");
return;
}
tunnelAdminService.updateTunnel(tunnel, path);
}
@Override
public void tunnelRemoved(TunnelDescription tunnel) {
if (tunnel.type() == MPLS) {
......@@ -681,7 +760,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
path,
annotations);
return tunnel;
}
/**
......@@ -1098,41 +1176,8 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
log.debug("SRP ID in handle message " + srpId);
if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
// Check the sync status
if (lspObj.getSFlag()) {
if (pcepClientController.getClient(pccId).lspDbSyncStatus() != IN_SYNC) {
pcepClientController.getClient(pccId).setLspDbSyncStatus(IN_SYNC);
// On starting LSP-DB sync, store LSP DB locally for this PCC.
Map<TunnelId, Tunnel> preSyncLspDb = new HashMap<>();
Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(MPLS);
for (Tunnel tunnel : queriedTunnels) {
if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
preSyncLspDb.put(tunnel.tunnelId(), tunnel);
}
}
preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
syncCompleteDeleteList.put(pccId.ipAddress(), new LinkedList<>());
syncCompleteUpdateList.put(pccId.ipAddress(), new LinkedList<>());
}
handleRptWithoutSrpId(stateRpt, pccId, IN_SYNC);
continue;
} else if (pcepClientController.getClient(pccId).lspDbSyncStatus() == IN_SYNC) {
// If sync flag is not set in the msg, and the
// previous state was "in sync" means this is
// end of sync message. PCRpt for end of sync
// does not carry any LSP report.
pcepClientController.getClient(pccId).setLspDbSyncStatus(SYNCED);
handleEndOfSyncAction(pccId);
continue;
}
// For PCRpt without matching SRP id not during LSPDB sync.
handleRptWithoutSrpId(stateRpt, pccId, SYNCED);
// For PCRpt without matching SRP id.
handleRptWithoutSrpId(stateRpt, pccId);
continue;
}
......@@ -1226,27 +1271,30 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
}
private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId, PcepSyncStatus syncStatus) {
ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
checkNotNull(msgPath);
PcepEroObject eroObj = msgPath.getEroObject();
if (eroObj == null) {
log.error("ERO object is null in report message.");
return;
}
Path path = buildPathFromEroObj(eroObj, providerId);
private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
float bandwidth, LspType lspType, String costType) {
int bandwidth = 0;
if (msgPath.getBandwidthObject() != null) {
bandwidth = msgPath.getBandwidthObject().getBandwidth();
}
Builder builder = DefaultAnnotations.builder();
/*
* To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
* from PCE.
* [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
* for which no constraints need be applied to any of the metrics.
*/
PcepSrpObject srpObj = stateRpt.getSrpObject();
if (costType != null) {
builder.set(COST_TYPE, costType);
}
SparseAnnotations annotations = builder
.set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
.set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
.set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
.set(DELEGATE, String.valueOf(lspObj.getDFlag()))
.build();
return annotations;
}
private LspType getLspType(PcepSrpObject srpObj) {
LspType lspType = WITH_SIGNALLING;
if (null != srpObj) {
......@@ -1266,6 +1314,55 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
}
}
return lspType;
}
private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
String costType = null;
PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
checkNotNull(msgPath);
PcepEroObject eroObj = msgPath.getEroObject();
if (eroObj == null) {
log.error("ERO object is null in report message.");
return;
}
PcepAttribute attributes = msgPath.getPcepAttribute();
int cost = 0;
if (attributes != null && attributes.getMetricObjectList() != null) {
ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
PcepMetricObject metricObj = iterator.next();
while (metricObj != null) {
if (metricObj.getBType() == IGP_METRIC) {
costType = "COST";
} else if (metricObj.getBType() == TE_METRIC) {
costType = "TE_COST";
}
if (costType != null) {
cost = metricObj.getMetricVal();
log.debug("Path cost {}", cost);
break;
}
metricObj = iterator.next();
}
}
Path path = buildPathFromEroObj(eroObj, providerId, cost);
float bandwidth = 0;
if (msgPath.getBandwidthObject() != null) {
bandwidth = msgPath.getBandwidthObject().getBandwidth();
}
/*
* To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
* from PCE.
*/
PcepSrpObject srpObj = stateRpt.getSrpObject();
LspType lspType = getLspType(srpObj);
PcepLspObject lspObj = stateRpt.getLspObject();
ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
......@@ -1287,7 +1384,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
break;
}
}
/*
* Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
* RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
......@@ -1303,6 +1399,14 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
.ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
// Store delegation flag info and that LSP info because only delegated PCE sends update message
// Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
// not present then non-delegated , if present it is delegated.
if (lspObj.getDFlag()) {
pcepClientController.getClient(pccId).setLspAndDelegationInfo(
new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
}
Tunnel tunnel = null;
// Asynchronous status change message from PCC for LSP reported earlier.
for (Tunnel tunnelObj : tunnelQueryResult) {
......@@ -1321,7 +1425,6 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
continue;
}
if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
.valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
tunnel = tunnelObj;
......@@ -1330,6 +1433,7 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
}
DefaultTunnelDescription td;
SparseAnnotations annotations = null;
State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
if (tunnel == null) {
if (lspObj.getRFlag()) {
......@@ -1340,91 +1444,96 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
return;
}
if (lspObj.getCFlag()) {
/*
* While in sync, if PCRpt is received for PCE init LSP and PCE doesn't have entry, mark to send
* delete message on end of sync.
*/
SparseAnnotations annotations = DefaultAnnotations.builder()
.set(BANDWIDTH, (new Integer(bandwidth)).toString())
.set(LSP_SIG_TYPE, lspType.name())
.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
.set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
.set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
// Gnenerate tunnel id for the temporary tunnel.
String onosTunnelId = "PCC" + String.valueOf(ipv4LspIdenTlv.getTunnelId());
Tunnel tunnelToBeDeleted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
new DefaultGroupId(0), TunnelId.valueOf(onosTunnelId),
TunnelName.tunnelName(String
.valueOf(pathNameTlv.getValue())),
path, annotations);
DeviceId deviceId = getDevice(pccId);
if (deviceId == null) {
log.error("Ingress deviceId not found");
return;
}
annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
/*
* Need to send PCInitiate delete msg for a tunnel which does not exist at PCE. For that some dummy
* data-structures need to be populated.
*/
PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelToBeDeleted, path, RequestType.DELETE);
pcepTunnelData.setPlspId(lspObj.getPlspId());
pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
pcepTunnelApiMapper.handleCreateTunnelRequestQueue(0, pcepTunnelData);
td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
annotations);
/*
* Add to the list of tunnels for which PCInit delete will be sent at the end of sync.
*/
List<Tunnel> tunnelToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
tunnelToBeDeletedList.add(tunnelToBeDeleted);
syncCompleteDeleteList.put(pccId.ipAddress(), tunnelToBeDeletedList);
// Do not support PCC initiated LSP after LSP DB sync is completed.
if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
log.error("Received PCC initiated LSP while not in sync.");
return;
}
SparseAnnotations annotations = DefaultAnnotations.builder()
.set(BANDWIDTH, (new Integer(bandwidth)).toString())
.set(LSP_SIG_TYPE, lspType.name())
.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
.set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
.set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
new DefaultGroupId(0), providerId,
TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())), path,
annotations);
TunnelId tId = tunnelAdded(td, tunnelState);
Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
tunnelState, new DefaultGroupId(0), tId,
TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())),
path, annotations);
PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
/*
* If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
* Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
* delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
* wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
* updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
* send update message to that client.
*
* 1)Master can 1st get the Rpt message
* a)Master adds the tunnel into core.
* b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
* after master, then runs timer then update the tunnel with D flag set.
* 2)Non-Master can 1st get the Rpt message
* a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
* b)Master would have got the message while the non-master running timer, hence master adds
* tunnel to core
*
* In general always master adds the tunnel to the core
* while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
*/
if (mastershipService.isLocalMaster(deviceId)) {
TunnelId tId = tunnelAdded(td, tunnelState);
Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
.getValue())), path, annotations);
PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
} else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
//Start timer then update the tunnel with D flag
tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
}
return;
}
if ((syncStatus == IN_SYNC) && (lspObj.getCFlag()) && (tunnelState != tunnel.state())) {
// Mark to send PCUpd msg with state known at PCE.
List<Tunnel> tunnelToBeUpdateList = syncCompleteUpdateList.get(pccId.ipAddress());
tunnelToBeUpdateList.add(tunnel);
syncCompleteUpdateList.put(pccId.ipAddress(), tunnelToBeUpdateList);
return;
//delegated owner will update can be a master or non-master
if (lspObj.getDFlag()) {
annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
annotations);
tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
}
removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
return;
}
td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
tunnel.type(), tunnel.groupId(), providerId,
tunnel.tunnelName(), tunnel.path(),
(SparseAnnotations) tunnel.annotations());
private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
State tunnelState) {
DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
(SparseAnnotations) tunnel.annotations());
if (lspObj.getRFlag()) {
tunnelRemoved(td);
} else {
if (syncStatus == IN_SYNC) {
markLspDbEntryAsLatest(pccId, tunnel.tunnelId());
}
tunnelUpdated(td, tunnelState);
}
return;
}
private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
DefaultTunnelDescription td, ProviderId providerId) {
//Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
/*
* If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
* master has added the tunnel to the store] then update the tunnel.
*/
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
executor), DELAY, DELAY, TimeUnit.SECONDS);
}
/**
......@@ -1432,9 +1541,10 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
*
* @param eroObj ERO object
* @param providerId provider id
* @param cost cost of path
* @return path object
*/
private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId) {
private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
checkNotNull(eroObj);
List<Link> links = new ArrayList<Link>();
LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
......@@ -1474,7 +1584,8 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
// the other sub objects are not required
}
}
return new DefaultPath(providerId, links, 0, EMPTY);
return new DefaultPath(providerId, links, cost, EMPTY);
}
@Override
......@@ -1493,44 +1604,14 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
tunnelStatisticsMap.put(id, tunnelStatistics);
}
}
@Override
public Tunnel tunnelQueryById(TunnelId tunnelId) {
return service.tunnelQueryById(tunnelId);
}
/**
* Removes the entry from temporary copy of LSPDB, signifying its status as upto date.
*
* @param pccId the key for temporary LSPDB
* @param tunnelId the tunnel id for which information is updated.
*/
private void markLspDbEntryAsLatest(PccId pccId, TunnelId tunnelId) {
checkNotNull(pccId);
checkNotNull(tunnelId);
Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
checkNotNull(preSyncLspDb);
preSyncLspDb.remove(tunnelId);
preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
}
/**
* Sends PCInit, PCInit(R) or PCUpd messages for initiated LSPs at the end
* of LSP DB sync based on actions decided while sync was in progress. Also
* triggers label DB sync.
*
* @param pccId the key for temporary DBs storing required end of sync
* actions.
*/
private void handleEndOfSyncAction(PccId pccId) {
Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
checkNotNull(preSyncLspDb);
@Override
public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
for (Tunnel tunnel : preSyncLspDb.values()) {
if (endOfSyncAction == SEND_UPDATE) {
updateTunnel(tunnel, tunnel.path());
return;
}
TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
tunnel.src(), tunnel.dst(),
......@@ -1541,41 +1622,133 @@ public class PcepTunnelProvider extends AbstractProvider implements TunnelProvid
tunnel.path(),
(SparseAnnotations) tunnel.annotations());
if ((tunnel.annotations().value(PCE_INIT) == null)
|| (tunnel.annotations().value(PCE_INIT).equals("false"))) {
tunnelRemoved(td);
} else {
if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
// Send PCInit msg again after global reoptimization.
tunnelUpdated(td, UNSTABLE);
// To remove the old tunnel from store whose PLSPID is not
// recognized by ingress PCC.
tunnelRemoved(td);
} else if (endOfSyncAction == REMOVE) {
tunnelRemoved(td);
}
}
List<Tunnel> tunnelsToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
checkNotNull(tunnelsToBeDeletedList);
for (Tunnel tunnel: tunnelsToBeDeletedList) {
releaseTunnel(tunnel);
@Override
public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
try {
if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
PcepClient pc = pcepClientController.getClient(pccId);
LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
.getPcInitiatedLspRequestList();
PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
if (pcInitMsg != null) {
PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
.setRFlag(true).build();
PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
.setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
llPcInitiatedLspRequestList.remove(pcInitMsg);
llPcInitiatedLspRequestList.add(releaseLspRequest);
PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
.setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
pc.sendMessage(Collections.singletonList(pcInitiateMsg));
}
}
} catch (PcepParseException e) {
log.error("Exception occured while sending initiate delete message {}", e.getMessage());
}
}
}
@Override
public Tunnel tunnelQueryById(TunnelId tunnelId) {
return service.tunnelQueryById(tunnelId);
}
List<Tunnel> tunnelsToBeUpdatedList = syncCompleteUpdateList.get(pccId.ipAddress());
checkNotNull(tunnelsToBeUpdatedList);
for (Tunnel tunnel: tunnelsToBeUpdatedList) {
updateTunnel(tunnel, tunnel.path());
private DeviceId getDevice(PccId pccId) {
// Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
IpAddress lsrId = pccId.ipAddress();
String lsrIdentifier = String.valueOf(lsrId);
// Find PCC deviceID from lsrId stored as annotations
Iterable<Device> devices = deviceService.getAvailableDevices();
for (Device dev : devices) {
if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
&& dev.annotations().value(LSRID).equals(lsrIdentifier)) {
return dev.id();
}
}
return null;
}
/**
* Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
* tunnel is found.
*/
private class UpdateDelegation implements Runnable {
DefaultTunnelDescription td;
ProviderId providerId;
SparseAnnotations annotations;
PccId pccId;
ScheduledExecutorService executor;
/**
* Creates an instance of UpdateDelegation.
*
* @param td tunnel description
* @param providerId provider id
* @param annotations tunnel annotations
* @param pccId PCEP client id
* @param executor service of delegated owner
*/
public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
PccId pccId, ScheduledExecutorService executor) {
this.td = td;
this.providerId = providerId;
this.annotations = annotations;
this.pccId = pccId;
this.executor = executor;
}
/* On end of sync, empty all temporary data structures. */
preSyncLspDbMap.remove(pccId.ipAddress());
syncCompleteDeleteList.remove(pccId.ipAddress());
syncCompleteUpdateList.remove(pccId.ipAddress());
//Temporary using annotations later will use projection/network config service
@Override
public void run() {
Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
TunnelId tempTunnelId = null;
for (Tunnel t : tunnelQueryResult) {
if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
continue;
}
// TODO: If SR capable, send a notification to
// PCE APP to start label DB sync.
if (true) {
pcepClientController.getClient(pccId).setLabelDbSyncStatus(IN_SYNC);
if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
&& t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
&& ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
tempTunnelId = t.tunnelId();
break;
}
}
//If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
//periodically
if (tempTunnelId != null) {
Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
tempTunnelId, td.tunnelName(), td.path(), annotations);
tunnelUpdated(tunnel, td.path());
executor.shutdown();
try {
executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("updating delegation failed");
}
}
}
}
}
......
......@@ -17,17 +17,22 @@ package org.onosproject.provider.pcep.tunnel.impl;
import static org.junit.Assert.assertNotNull;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepVersion;
/**
......@@ -45,6 +50,8 @@ public class PcepClientAdapter implements PcepClient {
private PcepVersion pcepVersion;
private PcepSyncStatus lspDbSyncStatus;
private PcepSyncStatus labelDbSyncStatus;
private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
private Map<PccId, List<PcepStateReport>> sycRptCache = new HashMap<>();
/**
* Initialize instance with specified parameters.
......@@ -139,4 +146,45 @@ public class PcepClientAdapter implements PcepClient {
public ClientCapability capability() {
return capability;
}
@Override
public void addNode(PcepClient pc) {
}
@Override
public void deleteNode(PccId pccId) {
}
@Override
public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
lspDelegationInfo.put(lspKey, dFlag);
}
@Override
public Boolean delegationInfo(LspKey lspKey) {
return lspDelegationInfo.get(lspKey);
}
@Override
public void initializeSyncMsgList(PccId pccId) {
List<PcepStateReport> rptMsgList = new LinkedList<>();
sycRptCache.put(pccId, rptMsgList);
}
@Override
public List<PcepStateReport> getSyncMsgList(PccId pccId) {
return sycRptCache.get(pccId);
}
@Override
public void removeSyncMsgList(PccId pccId) {
sycRptCache.remove(pccId);
}
@Override
public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
List<PcepStateReport> rptMsgList = sycRptCache.get(pccId);
rptMsgList.add(rptMsg);
sycRptCache.put(pccId, rptMsgList);
}
}
......
......@@ -24,13 +24,13 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.packet.IpAddress;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.PcepNodeListener;
import org.onosproject.pcep.controller.PcepPacketListener;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
......@@ -57,6 +57,8 @@ public class PcepClientControllerAdapter implements PcepClientController {
protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
protected Set<PcepPacketListener> pcepPacketListener = Sets.newHashSet();
@Activate
public void activate() {
......@@ -73,16 +75,11 @@ public class PcepClientControllerAdapter implements PcepClientController {
@Override
public PcepClient getClient(PccId pccId) {
if (null != connectedClients.get(pccId)) {
if (connectedClients.get(pccId) != null) {
return connectedClients.get(pccId);
}
PcepClientAdapter pc = new PcepClientAdapter();
if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
|| pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
pc.setCapability(new ClientCapability(true, false, false));
} else {
pc.setCapability(new ClientCapability(true, true, true));
}
pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
connectedClients.put(pccId, pc);
return pc;
......@@ -96,6 +93,16 @@ public class PcepClientControllerAdapter implements PcepClientController {
}
@Override
public void addNodeListener(PcepNodeListener listener) {
pcepNodeListener.add(listener);
}
@Override
public void removeNodeListener(PcepNodeListener listener) {
pcepNodeListener.remove(listener);
}
@Override
public void removeListener(PcepClientListener listener) {
this.pcepClientListener.remove(listener);
}
......@@ -111,6 +118,16 @@ public class PcepClientControllerAdapter implements PcepClientController {
}
@Override
public void addPacketListener(PcepPacketListener listener) {
pcepPacketListener.add(listener);
}
@Override
public void removePacketListener(PcepPacketListener listener) {
pcepPacketListener.remove(listener);
}
@Override
public void writeMessage(PccId pccId, PcepMessage msg) {
this.getClient(pccId).sendMessage(msg);
}
......@@ -254,5 +271,25 @@ public class PcepClientControllerAdapter implements PcepClientController {
public void processPcepMessage(PccId pccId, PcepMessage m) {
processClientMessage(pccId, m);
}
@Override
public void addNode(PcepClient pc) {
for (PcepNodeListener l : pcepNodeListener) {
l.addNode(pc);
}
}
@Override
public void deleteNode(PccId pccId) {
for (PcepNodeListener l : pcepNodeListener) {
l.deleteNode(pccId);
}
}
@Override
public boolean analyzeSyncMsgList(PccId pccId) {
// TODO Auto-generated method stub
return false;
}
}
}
......
......@@ -40,6 +40,7 @@ import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
......@@ -49,7 +50,10 @@ import org.onosproject.net.IpElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
/**
......@@ -64,12 +68,16 @@ public class PcepReleaseTunnelProviderTest {
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Before
public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
tunnelProvider.deviceService = deviceService;
tunnelProvider.mastershipService = mastershipService;
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
tunnelProvider.cfgService = new ComponentConfigAdapter();
......@@ -125,6 +133,8 @@ public class PcepReleaseTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -179,6 +189,8 @@ public class PcepReleaseTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E22))).setCapability(
new ClientCapability(true, false, false, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
......@@ -233,6 +245,8 @@ public class PcepReleaseTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -287,6 +301,8 @@ public class PcepReleaseTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -298,5 +314,7 @@ public class PcepReleaseTunnelProviderTest {
tunnelProvider.controller = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
tunnelProvider.deviceService = null;
tunnelProvider.mastershipService = null;
}
}
......
......@@ -40,6 +40,7 @@ import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
......@@ -49,7 +50,10 @@ import org.onosproject.net.IpElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
/**
* Test for PCEP setup tunnel.
......@@ -62,12 +66,16 @@ public class PcepSetupTunnelProviderTest {
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Before
public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
tunnelProvider.deviceService = deviceService;
tunnelProvider.mastershipService = mastershipService;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
......@@ -111,6 +119,8 @@ public class PcepSetupTunnelProviderTest {
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -154,6 +164,8 @@ public class PcepSetupTunnelProviderTest {
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010103))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
......@@ -197,6 +209,8 @@ public class PcepSetupTunnelProviderTest {
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -240,6 +254,8 @@ public class PcepSetupTunnelProviderTest {
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
......@@ -251,5 +267,7 @@ public class PcepSetupTunnelProviderTest {
tunnelProvider.controller = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
tunnelProvider.deviceService = null;
tunnelProvider.mastershipService = null;
}
}
......
......@@ -24,27 +24,35 @@ import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LOCAL
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
import static org.onosproject.net.Device.Type.ROUTER;
import static org.onosproject.net.MastershipRole.MASTER;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.Type;
import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelDescription;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
......@@ -52,16 +60,26 @@ import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelProvider;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Path;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import com.google.common.collect.ImmutableSet;
......@@ -71,13 +89,73 @@ import com.google.common.collect.ImmutableSet;
*/
public class PcepTunnelAddedTest {
static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
public static final String UNKOWN = "UNKOWN";
PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final MockTunnelProviderRegistryAdapter registry = new MockTunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final MockTunnelServiceAdapter tunnelService = new MockTunnelServiceAdapter();
public final MockDeviceService deviceService = new MockDeviceService();
private final MockMasterShipService masterShipService = new MockMasterShipService();
private final MockTunnelAdminService tunnelAdminService = new MockTunnelAdminService();
private class MockTunnelAdminService implements TunnelAdminService {
@Override
public void removeTunnel(TunnelId tunnelId) {
// TODO Auto-generated method stub
}
@Override
public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, ProviderId producerName) {
// TODO Auto-generated method stub
}
@Override
public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Type type, ProviderId producerName) {
// TODO Auto-generated method stub
}
@Override
public void updateTunnel(Tunnel tunnel, Path path) {
if (tunnelService.tunnelIdAsKeyStore.containsKey(tunnel.tunnelId())) {
tunnelService.tunnelIdAsKeyStore.replace(tunnel.tunnelId(), tunnel);
}
}
}
private class MockMasterShipService extends MastershipServiceAdapter {
boolean set;
private void setMaster(boolean isMaster) {
this.set = isMaster;
}
@Override
public MastershipRole getLocalRole(DeviceId deviceId) {
return set ? MastershipRole.MASTER : MastershipRole.STANDBY;
}
@Override
public boolean isLocalMaster(DeviceId deviceId) {
return getLocalRole(deviceId) == MASTER;
}
}
private class MockDeviceService extends DeviceServiceAdapter {
List<Device> devices = new LinkedList<>();
private void addDevice(Device dev) {
devices.add(dev);
}
@Override
public Iterable<Device> getAvailableDevices() {
return devices;
}
}
private class MockTunnelProviderRegistryAdapter extends TunnelProviderRegistryAdapter {
public long tunnelIdCounter;
......@@ -97,12 +175,34 @@ public class PcepTunnelAddedTest {
@Override
public TunnelId tunnelAdded(TunnelDescription tunnel) {
return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
tunnel.src(), tunnel.dst(),
tunnel.type(),
tunnel.groupId(),
id,
tunnel.tunnelName(),
tunnel.path(),
tunnel.resource(),
tunnel.annotations());
tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
return id;
}
@Override
public TunnelId tunnelAdded(TunnelDescription tunnel, State state) {
return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
tunnel.src(), tunnel.dst(),
tunnel.type(),
tunnel.groupId(),
id,
tunnel.tunnelName(),
tunnel.path(),
tunnel.resource(),
tunnel.annotations());
tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
return id;
}
@Override
......@@ -168,9 +268,12 @@ public class PcepTunnelAddedTest {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
tunnelProvider.deviceService = deviceService;
tunnelProvider.mastershipService = masterShipService;
tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.tunnelAdminService = tunnelAdminService;
tunnelProvider.service = registry.register(tunnelProvider);
tunnelProvider.activate();
}
......@@ -210,6 +313,19 @@ public class PcepTunnelAddedTest {
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
newBuilder.set(AnnotationKeys.TYPE, "L3");
Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
UNKOWN, UNKOWN, UNKOWN,
UNKOWN, new ChassisId(),
newBuilder.build());
deviceService.addDevice(device);
controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
new ClientCapability(true, true, true, true, true));
masterShipService.setMaster(true);
controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
assertThat(registry.tunnelIdCounter, is((long) 1));
......@@ -254,14 +370,20 @@ public class PcepTunnelAddedTest {
.set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
.set(PCC_TUNNEL_ID, String.valueOf(1))
.set(PLSP_ID, String.valueOf(1))
.set(LOCAL_LSP_ID, String.valueOf(1)).build();
.set(LOCAL_LSP_ID, String.valueOf(1))
.set(DELEGATE, String.valueOf("true"))
.build();
Tunnel tunnel = new DefaultTunnel(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, INIT, null, null,
TunnelName.tunnelName("T123"), null, annotations);
tunnelService.setupTunnel(null, null, tunnel, null);
PccId pccId = PccId.pccId(IpAddress.valueOf(0x4e1f0400));
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
masterShipService.setMaster(true);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
// Process update message.
......@@ -281,7 +403,7 @@ public class PcepTunnelAddedTest {
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x02,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
......@@ -308,167 +430,139 @@ public class PcepTunnelAddedTest {
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
newBuilder.set(AnnotationKeys.TYPE, "L3");
Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
UNKOWN, UNKOWN, UNKOWN,
UNKOWN, new ChassisId(),
newBuilder.build());
deviceService.addDevice(device);
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
masterShipService.setMaster(true);
controller.processClientMessage(pccId, message);
assertThat(registry.tunnelIdCounter, is((long) 1));
}
/**
* Tests LSPDB sync where PCC reports less LSPs than known by PCE and PCE deletes at the end of DB sync.
* Tests PCRpt msg with D flag set and delegated to non-master.
*
* @throws InterruptedException while waiting for delay
*/
@Test
public void testCaseLspDbSync1() throws PcepParseException, PcepOutOfBoundMessageException {
/* Step 1 create 2 LSPs */
byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
public void tunnelProviderAddedTest4() throws PcepParseException, PcepOutOfBoundMessageException,
InterruptedException {
byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, //SRP object
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x02,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x02, //LSP object
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
buffer1.writeBytes(reportMsg1);
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(reportMsg);
PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
PcepMessage message1 = reader1.readFrom(buffer1);
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
controller.processClientMessage(pccId, message1);
//PCC 1.1.1.1, D=0, ONOS as master
masterShipService.setMaster(true);
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
newBuilder.set(AnnotationKeys.TYPE, "L3");
Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
UNKOWN, UNKOWN, UNKOWN,
UNKOWN, new ChassisId(),
newBuilder.build());
deviceService.addDevice(device);
controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
new ClientCapability(true, true, true, true, true));
controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
is("false"));
/* create 2nd LSP */
byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x02, 0x00, 0x02,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
//PCC 1.1.1.1, D=1, non-master
masterShipService.setMaster(false);
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, //SRP object
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x02,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x03, //LSP object
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(reportMsg);
ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
buffer2.writeBytes(reportMsg2);
PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
PcepMessage message2 = reader2.readFrom(buffer2);
controller.processClientMessage(pccId, message2);
/* Assert number of LSPs in DB to be 2. */
assertThat(registry.tunnelIdCounter, is((long) 2));
/* Step 2 send sync begin message and LSP 1. */
byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
buffer3.writeBytes(reportMsg3);
PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
PcepMessage message3 = reader3.readFrom(buffer3);
controller.processClientMessage(pccId, message3);
assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
/* Step 3 send end of sync marker */
byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
0x20, 0x10, 0x00, 0x1C, // LSP object
0x00, 0x00, 0x10, 0x19,
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x07, 0x10, 0x00, 0x04, //ERO object
};
ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
buffer4.writeBytes(reportMsg4);
PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
PcepMessage message4 = reader4.readFrom(buffer4);
controller.processClientMessage(pccId, message4);
assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
reader = PcepFactories.getGenericReader();
message = reader.readFrom(buffer);
controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
TimeUnit.MILLISECONDS.sleep(4000);
assertThat(registry.tunnelIdCounter, is((long) 1));
assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
is("true"));
}
/**
* Tests PCC PCRpt PCE initiated LSP which PCE doesn't know and hence should send PCInit delete msg.
* Tests adding PCC Init LSP after LSP DB sync is over.
*/
@Test
public void testCaseLspDbSync2() throws PcepParseException, PcepOutOfBoundMessageException {
/* Step 1 create 2 LSPs */
byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
public void tunnelProviderAddedTest5() throws PcepParseException, PcepOutOfBoundMessageException {
byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01,
......@@ -488,110 +582,33 @@ public class PcepTunnelAddedTest {
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
buffer1.writeBytes(reportMsg1);
PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
PcepMessage message1 = reader1.readFrom(buffer1);
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
controller.processClientMessage(pccId, message1);
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(reportMsg);
/* create 2nd LSP */
byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x02, 0x00, 0x02,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
newBuilder.set(AnnotationKeys.TYPE, "L3");
Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
UNKOWN, UNKOWN, UNKOWN,
UNKOWN, new ChassisId(),
newBuilder.build());
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
deviceService.addDevice(device);
ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
buffer2.writeBytes(reportMsg2);
PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
PcepMessage message2 = reader2.readFrom(buffer2);
controller.processClientMessage(pccId, message2);
/* Assert number of LSPs in DB to be 2. */
assertThat(registry.tunnelIdCounter, is((long) 2));
/* Step 2 send sync begin message and LSP 1. */
byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
0x21, 0x10, 0x00, 0x14, //SRP object
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, (byte) 0x9B, // LSP object
0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x00, 0x03,
0x01, 0x01, 0x01, 0x01,
0x05, 0x05, 0x05, 0x05,
0x07, 0x10, 0x00, 0x14, //ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
0x08, 0x10, 0x00, 0x34, //RRO object
0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
};
ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
buffer3.writeBytes(reportMsg3);
PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
PcepMessage message3 = reader3.readFrom(buffer3);
controller.processClientMessage(pccId, message3);
assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
/* Step 3 send end of sync marker */
byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
0x20, 0x10, 0x00, 0x1C, // LSP object
0x00, 0x00, 0x10, 0x19,
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x07, 0x10, 0x00, 0x04, //ERO object
};
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
buffer4.writeBytes(reportMsg4);
PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
PcepMessage message4 = reader4.readFrom(buffer4);
controller.processClientMessage(pccId, message4);
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
masterShipService.setMaster(true);
controller.processClientMessage(pccId, message);
assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
assertThat(registry.tunnelIdCounter, is((long) 0));
}
@After
......@@ -604,6 +621,9 @@ public class PcepTunnelAddedTest {
tunnelProvider.pcepTunnelApiMapper = null;
tunnelProvider.cfgService = null;
tunnelProvider.tunnelService = null;
tunnelProvider.tunnelAdminService = null;
tunnelProvider.deviceService = null;
tunnelProvider.mastershipService = null;
tunnelProvider.service = null;
}
}
......
......@@ -35,6 +35,7 @@ import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
......@@ -44,7 +45,10 @@ import org.onosproject.net.IpElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.cfg.ComponentConfigAdapter;
public class PcepTunnelProviderTest {
......@@ -55,6 +59,8 @@ public class PcepTunnelProviderTest {
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Test
public void testCasePcepSetupTunnel() {
......@@ -62,6 +68,8 @@ public class PcepTunnelProviderTest {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
tunnelProvider.deviceService = deviceService;
tunnelProvider.mastershipService = mastershipService;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
......@@ -99,6 +107,8 @@ public class PcepTunnelProviderTest {
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
......@@ -109,6 +119,8 @@ public class PcepTunnelProviderTest {
public void tearDown() throws IOException {
tunnelProvider.deactivate();
tunnelProvider.controller = null;
tunnelProvider.deviceService = null;
tunnelProvider.mastershipService = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
}
......
......@@ -47,6 +47,10 @@ import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
......@@ -99,7 +103,7 @@ public class PcepUpdateTunnelProviderTest {
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
......@@ -108,6 +112,8 @@ public class PcepUpdateTunnelProviderTest {
path = new DefaultPath(pid, links, 20, EMPTY);
Annotations annotations = DefaultAnnotations.builder()
.set(PcepAnnotationKeys.PLSP_ID, "1")
.set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
.build();
......@@ -124,6 +130,12 @@ public class PcepUpdateTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
......@@ -137,7 +149,7 @@ public class PcepUpdateTunnelProviderTest {
Path path;
ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
List<Link> links = new ArrayList<>();
IpAddress srcIp = IpAddress.valueOf(0xC010103);
IpAddress srcIp = IpAddress.valueOf(0xD010101);
IpElementId srcElementId = IpElementId.ipElement(srcIp);
IpAddress dstIp = IpAddress.valueOf(0xD010102);
......@@ -151,7 +163,7 @@ public class PcepUpdateTunnelProviderTest {
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
......@@ -161,6 +173,8 @@ public class PcepUpdateTunnelProviderTest {
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
.set(PcepAnnotationKeys.PLSP_ID, "1")
.set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
......@@ -176,6 +190,12 @@ public class PcepUpdateTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
}
......@@ -203,7 +223,7 @@ public class PcepUpdateTunnelProviderTest {
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
......@@ -213,6 +233,8 @@ public class PcepUpdateTunnelProviderTest {
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, SR_WITHOUT_SIGNALLING.name())
.set(PcepAnnotationKeys.PLSP_ID, "1")
.set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
......@@ -228,6 +250,12 @@ public class PcepUpdateTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
......@@ -255,7 +283,7 @@ public class PcepUpdateTunnelProviderTest {
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
......@@ -265,6 +293,8 @@ public class PcepUpdateTunnelProviderTest {
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
.set(PcepAnnotationKeys.PLSP_ID, "1")
.set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
......@@ -280,6 +310,12 @@ public class PcepUpdateTunnelProviderTest {
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
PcepClientAdapter pc = new PcepClientAdapter();
pc.init(pccId, PcepVersion.PCEP_1);
controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
......