[ONOS] Cherry picked from master 1.7
Change-Id: I74a0c1634f9c425af2bcb646edc3d9170b3c087c
diff --git a/apps/pce/pceweb/app.png b/apps/pce/pceweb/app.png
index abe34eb..01ea558 100644
--- a/apps/pce/pceweb/app.png
+++ b/apps/pce/pceweb/app.png
Binary files differ
diff --git a/apps/pce/pceweb/pom.xml b/apps/pce/pceweb/pom.xml
index b9b1435..9e815a0 100644
--- a/apps/pce/pceweb/pom.xml
+++ b/apps/pce/pceweb/pom.xml
@@ -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>
diff --git a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
index 0c1a5b5..95e9f1f 100644
--- a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
+++ b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
@@ -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 @@
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 @@
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 @@
@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 @@
}
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
srcType, src.toString(), SRC)));
-
}
}
@@ -167,7 +211,6 @@
if (src.equals(dst)) {
src = null;
}
-
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
dstType, dst.toString(), DST)));
@@ -175,7 +218,7 @@
}
/**
- * 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 @@
@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);
- // TODO: Read user input[constraints] and call the path calculation based on
- //given constrainsts.
- findAndSendPaths();
+ 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;
+ }
+
+ 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 @@
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;
}
- //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) {
+ /**
+ * 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;
+ }
+
+ 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 @@
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 @@
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();
+ }
}
diff --git a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
index 087f4bc..41f3243 100644
--- a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
+++ b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
@@ -63,7 +63,6 @@
public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
pp.title(MY_TITLE);
- log.info("Modify device details called.");
DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
index 096f872..e16e15b 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
@@ -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");
-
- if (d3.select("#band-kpbs-val").property("checked")) {
- bandType = 'kbps';
- } else if (d3.select('#band-mpbs-val').property("checked")) {
- bandType = 'mbps';
- }
- }
-
- var costType = d3.select('#pce-cost-type').property("checked");
- var costTypeVal = null;
-
- if (costType) {
-
- if (d3.select("#pce-cost-type-igp").property("checked")) {
- costTypeVal = 'igp';
- } else if (d3.select('#pce-cost-type-te').property("checked")) {
- costTypeVal = 'te';
- }
- }
-
- var lspType = d3.select('#pce-lsp-type').property("checked");
- var lspTypeVal = null;
-
- if (lspType) {
-
- 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';
- }
- }
-
- //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');
- }
-
function dClose() {
$log.debug('Dialog Close button clicked (or Esc pressed)');
}
function createUserText() {
- var content = ds.createDiv();
- var form = content.append('form');
- var p = form.append('p');
+ 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');
+ }
//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');
-
+ 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.
- 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-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.
- p.append('input').attr({
- id: 'pce-lsp-type',
- type: 'checkbox',
- name: 'pce-lsp-type-name'
- });
- p.append('span').text('Lsp Type');
- 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');
+ 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');
return content;
}
- function setMode() {
+ function createUserTextUpdate(data) {
+ var content = ds.createDiv(),
+ form = content.append('form'),
+ p = form.append('p');
+
+ p.append('span').text('Tunnel IDs');
+ p.append('br');
+
+ data.a.forEach( function (val, idx) {
+ p.append('input').attr({
+ id: 'tunnel-id-'+idx,
+ type: 'radio',
+ name: 'tunnel-id-name',
+ value: val
+ });
+
+ p.append('span').text(val);
+ p.append('br');
+
+ } );
+
+ return content;
+ }
+
+ function createUserTextUpdatePathEvent() {
+ var content = ds.createDiv(),
+ 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');
+ }
+
+ //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.
+ 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');
+
+ 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');
+
+ 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('constraints user')
+ .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 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
};
}]);
}());
diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
index 63a4d2d..4ad40a0 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
@@ -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: 'Select constraints for LSP',
+ tt: 'Setup path',
+ gid: 'plus'
+ },
+ 2: {
+ cb: function () {
+ pps.updatePath(selection);
+ },
+ 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);
}
}
};