From ba1c912fa4b4fe1097508dfa07978369cda0ec2a Mon Sep 17 00:00:00 2001 From: Satish K Date: Wed, 5 Apr 2017 15:27:23 +0530 Subject: [PATCH] Pce Load Balancing Change-Id: I417e7473db86fa26f7a2dc46122dcacdeb584108 --- .../PceDeleteLoadBalancingPathCommand.java | 51 +++++ .../cli/PceQueryLoadBalancingPathCommand.java | 94 +++++++++ .../pce/cli/PceSetupPathCommand.java | 13 ++ .../pce/pceservice/PceManager.java | 178 +++++++++++++++++- .../pce/pceservice/api/PceService.java | 45 +++++ .../pce/pcestore/DistributedPceStore.java | 61 ++++++ .../onosproject/pce/pcestore/PcePathInfo.java | 32 +++- .../pce/pcestore/api/PceStore.java | 32 ++++ .../OSGI-INF/blueprint/shell-config.xml | 6 + .../pce/pcestore/DistributedPceStoreTest.java | 8 +- .../pce/pcestore/PcePathInfoTest.java | 8 +- .../onosproject/pce/util/PceStoreAdapter.java | 49 +++++ .../pcerest/PcePathResourceTest.java | 2 +- .../pceweb/PceWebTopovMessageHandler.java | 147 +++++++++++---- .../app/view/pcewebTopov/pcewebTopovDemo.js | 18 +- 15 files changed, 685 insertions(+), 59 deletions(-) create mode 100644 apps/pce/app/src/main/java/org/onosproject/pce/cli/PceDeleteLoadBalancingPathCommand.java create mode 100644 apps/pce/app/src/main/java/org/onosproject/pce/cli/PceQueryLoadBalancingPathCommand.java diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceDeleteLoadBalancingPathCommand.java b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceDeleteLoadBalancingPathCommand.java new file mode 100644 index 0000000000..75b95c1353 --- /dev/null +++ b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceDeleteLoadBalancingPathCommand.java @@ -0,0 +1,51 @@ +/* + * 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.pce.cli; + +import static org.slf4j.LoggerFactory.getLogger; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; + +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.pce.pceservice.api.PceService; + +import org.slf4j.Logger; + +/** + * Supports deleting pce load balancing path. + */ +@Command(scope = "onos", name = "pce-delete-load-balancing-path", + description = "Supports deleting pce load balancing path.") +public class PceDeleteLoadBalancingPathCommand extends AbstractShellCommand { + private final Logger log = getLogger(getClass()); + + @Argument(index = 0, name = "name", description = "load balancing path name", required = true, + multiValued = false) + String name = null; + + @Override + protected void execute() { + log.info("executing pce-delete-load-balancing-path"); + + PceService service = get(PceService.class); + + if (!service.releasePath(name)) { + error("Path deletion failed."); + return; + } + } +} diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceQueryLoadBalancingPathCommand.java b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceQueryLoadBalancingPathCommand.java new file mode 100644 index 0000000000..9250ba2e6e --- /dev/null +++ b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceQueryLoadBalancingPathCommand.java @@ -0,0 +1,94 @@ +/* + * 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.pce.cli; + +import static org.slf4j.LoggerFactory.getLogger; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; + +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.incubator.net.tunnel.Tunnel; +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.net.AnnotationKeys; +import org.onosproject.pce.pceservice.api.PceService; + +import org.slf4j.Logger; + +import java.util.List; + +/** + * Supports quering PCE load balanced path. + */ +@Command(scope = "onos", name = "pce-query-load-balancing-path", + description = "Supports querying PCE path.") +public class PceQueryLoadBalancingPathCommand extends AbstractShellCommand { + private final Logger log = getLogger(getClass()); + public static final String COST_TYPE = "costType"; + + @Argument(index = 0, name = "pathName", description = "load balencing path name", required = true, + multiValued = false) + String name = null; + + @Override + protected void execute() { + log.info("executing pce-query-load-balancing-path"); + + PceService service = get(PceService.class); + + if (name == null) { + print("Path name is mandatory"); + return; + } + + List tunnelIds = service.queryLoadBalancingPath(name); + if (tunnelIds == null || tunnelIds.isEmpty()) { + print("Release path failed"); + return; + } + + for (TunnelId id : tunnelIds) { + Tunnel tunnel = service.queryPath(id); + if (tunnel == null) { + print("Path doesnot exists"); + return; + } + display(tunnel); + } + } + + /** + * Display tunnel information on the terminal. + * + * @param tunnel pce tunnel + */ + void display(Tunnel tunnel) { + + print("\npath-id : %s \n" + + "source : %s \n" + + "destination : %s \n" + + "path-type : %s \n" + + "symbolic-path-name : %s \n" + + "constraints: \n" + + " cost : %s \n" + + " bandwidth : %s", + tunnel.tunnelId().id(), tunnel.path().src().deviceId().toString(), + tunnel.path().dst().deviceId().toString(), + tunnel.type().name(), tunnel.tunnelName(), tunnel.annotations().value(COST_TYPE), + tunnel.annotations().value(AnnotationKeys.BANDWIDTH)); + print("Path : %s", tunnel.path().toString()); + } +} diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceSetupPathCommand.java b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceSetupPathCommand.java index 18e2ce8d3d..b3c07b86c2 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceSetupPathCommand.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/cli/PceSetupPathCommand.java @@ -95,6 +95,10 @@ public class PceSetupPathCommand extends AbstractShellCommand { required = false, multiValued = true) String[] explicitPathInfoStrings; + @Option(name = "-l", aliases = "--loadBalancing", description = "The load balancing option for user. ", + required = false, multiValued = false) + boolean loadBalancing = false; + //explicitPathInfo format : Type/SubType/Value(DeviceId or Link info) //If Value is Device : Type/SubType/deviceId //If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo @@ -188,6 +192,15 @@ public class PceSetupPathCommand extends AbstractShellCommand { explicitPathInfo.add(obj); } } + + //with load balancing option + if (loadBalancing) { + if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, loadBalancing)) { + error("Path creation failed."); + } + return; + } + if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, explicitPathInfo)) { error("Path creation failed."); } diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java index bc80a7f97d..658dcbbf1b 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java @@ -17,6 +17,7 @@ package org.onosproject.pce.pceservice; import static com.google.common.base.Preconditions.checkNotNull; +import org.onosproject.net.DisjointPath; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -168,6 +169,7 @@ public class PceManager implements PceService { private ApplicationId appId; private final TopologyListener topologyListener = new InternalTopologyListener(); + public static final String LOAD_BALANCING_PATH_NAME = "loadBalancingPathName"; private List rsvpTunnelsWithLocalBw = new ArrayList<>(); @@ -421,13 +423,26 @@ public class PceManager implements PceService { @Override public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, LspType lspType) { - return setupPath(src, dst, tunnelName, constraints, lspType, null); + return setupPath(src, dst, tunnelName, constraints, lspType, null, false); } //[TODO:] handle requests in queue @Override public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, LspType lspType, List explicitPathInfo) { + return setupPath(src, dst, tunnelName, constraints, lspType, explicitPathInfo, false); + + } + + @Override + public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, + LspType lspType, boolean loadBalancing) { + return setupPath(src, dst, tunnelName, constraints, lspType, null, loadBalancing); + } + + @Override + public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, + LspType lspType, List explicitPathInfo, boolean loadBalancing) { checkNotNull(src); checkNotNull(dst); checkNotNull(tunnelName); @@ -439,7 +454,8 @@ public class PceManager implements PceService { if (srcDevice == null || dstDevice == null) { // Device is not known. - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo)); + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo, + loadBalancing)); return false; } @@ -449,7 +465,8 @@ public class PceManager implements PceService { if (srcLsrId == null || dstLsrId == null) { // LSR id is not known. - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo)); + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo, + loadBalancing)); return false; } @@ -457,7 +474,8 @@ public class PceManager implements PceService { DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class); if (cfg == null) { log.debug("No session to ingress."); - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo)); + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo, + loadBalancing)); return false; } @@ -495,6 +513,11 @@ public class PceManager implements PceService { } Set computedPathSet = Sets.newLinkedHashSet(); + if (loadBalancing) { + return setupDisjointPaths(src, dst, constraints, tunnelName, bwConstraintValue, lspType, costConstraint, + srcEndPoint, dstEndPoint); + } + if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) { List finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints); if (finalComputedPath == null) { @@ -516,7 +539,8 @@ public class PceManager implements PceService { // NO-PATH if (computedPathSet.isEmpty()) { - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo)); + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo, + loadBalancing)); return false; } @@ -550,14 +574,15 @@ public class PceManager implements PceService { if (bwConstraintValue != 0) { if (!reserveBandwidth(computedPath, bwConstraintValue, null)) { pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, - lspType, explicitPathInfo)); + lspType, explicitPathInfo, loadBalancing)); return false; } } TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath); if (tunnelId == null) { - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo)); + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo, + loadBalancing)); if (bwConstraintValue != 0) { computedPath.links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln), @@ -574,6 +599,114 @@ public class PceManager implements PceService { return true; } + private boolean setupDisjointPaths(DeviceId src, DeviceId dst, List constraints, String tunnelName, + double bwConstraintValue, LspType lspType, CostConstraint costConstraint, + TunnelEndPoint srcEndPoint, TunnelEndPoint dstEndPoint) { + Set paths = pathService.getDisjointPaths(src, dst, weight(constraints)); + + // NO-PATH + if (paths.isEmpty()) { + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true)); + return false; + } + + DisjointPath path = null; + if (!paths.isEmpty()) { + path = paths.iterator().next(); + } + + Builder annotationBuilder = DefaultAnnotations.builder(); + double bw = 0; + if (bwConstraintValue != 0) { + //TODO: BW needs to be divided by 2 :: bwConstraintValue/2 + bw = bwConstraintValue / 2; + annotationBuilder.set(BANDWIDTH, String.valueOf(bw)); + } + if (costConstraint != null) { + annotationBuilder.set(COST_TYPE, String.valueOf(costConstraint.type())); + } + annotationBuilder.set(LSP_SIG_TYPE, lspType.name()); + annotationBuilder.set(PCE_INIT, TRUE); + annotationBuilder.set(DELEGATE, TRUE); + annotationBuilder.set(LOAD_BALANCING_PATH_NAME, tunnelName); + + //Path computedPath = computedPathSet.iterator().next(); + + if (lspType != WITH_SIGNALLING) { + /* + * Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by + * PCE for non-RSVP signalled LSPs. + */ + annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(getNextLocalLspId())); + } + + //Generate different tunnel name for disjoint paths + String tunnel1 = (new StringBuilder()).append(tunnelName).append("_1").toString(); + String tunnel2 = (new StringBuilder()).append(tunnelName).append("_2").toString(); + + // For SR-TE tunnels, call SR manager for label stack and put it inside tunnel. + Tunnel tunnelPrimary = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null, + TunnelName.tunnelName(tunnel1), path.primary(), + annotationBuilder.build()); + + Tunnel tunnelBackup = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null, + TunnelName.tunnelName(tunnel2), path.backup(), + annotationBuilder.build()); + + // Allocate bandwidth. + if (bwConstraintValue != 0) { + if (!reserveBandwidth(path.primary(), bw, null)) { + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnel1, constraints, + lspType, null, true)); + return false; + } + + if (!reserveBandwidth(path.backup(), bw, null)) { + //Release bandwidth resource for tunnel1 + if (bwConstraintValue != 0) { + path.primary().links().forEach(ln -> + bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln), + Double.parseDouble(tunnelPrimary.annotations().value(BANDWIDTH)))); + } + + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnel2, constraints, + lspType, null, true)); + return false; + } + } + + TunnelId tunnelId1 = tunnelService.setupTunnel(appId, src, tunnelPrimary, path.primary()); + if (tunnelId1 == null) { + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true)); + + if (bwConstraintValue != 0) { + path.primary().links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln), + Double.parseDouble(tunnelPrimary.annotations().value(BANDWIDTH)))); + } + + return false; + } + + TunnelId tunnelId2 = tunnelService.setupTunnel(appId, src, tunnelBackup, path.backup()); + if (tunnelId2 == null) { + //Release 1st tunnel + releasePath(tunnelId2); + + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, null, true)); + + if (bwConstraintValue != 0) { + path.backup().links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln), + Double.parseDouble(tunnelBackup.annotations().value(BANDWIDTH)))); + } + + return false; + } + + pceStore.addLoadBalancingTunnelIdsInfo(tunnelName, tunnelId1, tunnelId2); + //pceStore.addDisjointPathInfo(tunnelName, path); + return true; + } + @Override public boolean updatePath(TunnelId tunnelId, List constraints) { checkNotNull(tunnelId); @@ -750,6 +883,26 @@ public class PceManager implements PceService { return tunnelService.downTunnel(appId, tunnel.tunnelId()); } + @Override + public boolean releasePath(String loadBalancingPathName) { + checkNotNull(loadBalancingPathName); + + List tunnelIds = pceStore.getLoadBalancingTunnelIds(loadBalancingPathName); + if (tunnelIds != null && !tunnelIds.isEmpty()) { + for (TunnelId id : tunnelIds) { + if (!tunnelService.downTunnel(appId, id)) { + return false; + } + } + + //pceStore.removeDisjointPathInfo(loadBalancedPathName); + pceStore.removeLoadBalancingTunnelIdsInfo(loadBalancingPathName); + return true; + } + + return false; + } + @Override public Iterable queryAllPath() { return tunnelService.queryTunnel(MPLS); @@ -907,7 +1060,8 @@ public class PceManager implements PceService { pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList, LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)), - pceStore.getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value()))); + pceStore.getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value()), + tunnel.annotations().value(LOAD_BALANCING_PATH_NAME) != null ? true : false)); //Release that tunnel calling PCInitiate releasePath(tunnel.tunnelId()); } @@ -1079,7 +1233,8 @@ public class PceManager implements PceService { links.get(links.size() - 1).dst().deviceId(), tunnel.tunnelName().value(), constraints, lspType, pceStore.getTunnelNameExplicitPathInfoMap(tunnel - .tunnelName().value()))); + .tunnelName().value()), tunnel.annotations() + .value(LOAD_BALANCING_PATH_NAME) != null ? true : false)); } break; @@ -1115,6 +1270,11 @@ public class PceManager implements PceService { return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName); } + @Override + public List queryLoadBalancingPath(String pathName) { + return pceStore.getLoadBalancingTunnelIds(pathName); + } + //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)] diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java index fdfdb73b3c..db2bdfbd16 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java @@ -56,6 +56,35 @@ public interface PceService { boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, LspType lspType, List explicitPathInfo); + /** + * Creates new path based on constraints and LSP type with load balancing option. + * + * @param src source device + * @param dst destination device + * @param tunnelName name of the tunnel + * @param constraints list of constraints to be applied on path + * @param lspType type of path to be setup + * @param loadBalancing load balancing option enable or not + * @return false on failure and true on successful path creation + */ + boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, LspType lspType, + boolean loadBalancing); + + /** + * Creates new path based on constraints and LSP type with load balancing and explicit path options. + * + * @param src source device + * @param dst destination device + * @param tunnelName name of the tunnel + * @param constraints list of constraints to be applied on path + * @param lspType type of path to be setup + * @param explicitPathInfo list of explicit path info + * @param loadBalancing load balancing option enable or not + * @return false on failure and true on successful path creation + */ + boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List constraints, LspType lspType, + List explicitPathInfo, boolean loadBalancing); + /** * Updates an existing path. * @@ -73,6 +102,14 @@ public interface PceService { */ boolean releasePath(TunnelId tunnelId); + /** + * Releases load balancing paths. + * + * @param loadBalancingPathName load balance path name + * @return false on failure and true on successful paths removal + */ + boolean releasePath(String loadBalancingPathName); + /** * Queries all paths. * @@ -95,4 +132,12 @@ public interface PceService { * @return list of explicit path info */ List explicitPathInfoList(String tunnelName); + + /** + * Queries load balancing paths on load balance path name. + * + * @param pathName load balance path name + * @return list of load balancing tunnels + */ + List queryLoadBalancingPath(String pathName); } \ No newline at end of file diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java index eb6fadd6af..18d291ef95 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java @@ -16,6 +16,7 @@ package org.onosproject.pce.pcestore; import com.google.common.collect.ImmutableSet; +import java.util.Arrays; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -23,6 +24,7 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.onlab.util.KryoNamespace; +import org.onosproject.incubator.net.tunnel.TunnelId; import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pceservice.LspType; import org.onosproject.pce.pceservice.constraint.CapabilityConstraint; @@ -57,6 +59,9 @@ public class DistributedPceStore implements PceStore { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected StorageService storageService; + //Mapping tunnel name with Disjoint paths + private ConsistentMap> tunnelNameDisjoinTunnelIdInfo; + // List of Failed path info private DistributedSet failedPathSet; @@ -96,6 +101,15 @@ public class DistributedPceStore implements PceStore { .build())) .build(); + tunnelNameDisjoinTunnelIdInfo = storageService.>consistentMapBuilder() + .withName("onos-pce-disjointTunnelIds") + .withSerializer(Serializer.using( + new KryoNamespace.Builder() + .register(KryoNamespaces.API) + .register(TunnelId.class) + .build())) + .build(); + log.info("Started"); } @@ -157,4 +171,51 @@ public class DistributedPceStore implements PceStore { return null; } +/* @Override + public DisjointPath getDisjointPaths(String tunnelName) { + if (tunnelNameDisjointPathInfo.get(tunnelName) != null) { + return tunnelNameDisjointPathInfo.get(tunnelName).value(); + } + return null; + } + + @Override + public boolean addDisjointPathInfo(String tunnelName, DisjointPath path) { + checkNotNull(tunnelName); + checkNotNull(path); + return tunnelNameDisjointPathInfo.put(tunnelName, path) != null ? true : false; + }*/ + + @Override + public boolean addLoadBalancingTunnelIdsInfo(String tunnelName, TunnelId... tunnelIds) { + checkNotNull(tunnelName); + checkNotNull(tunnelIds); + return tunnelNameDisjoinTunnelIdInfo.put(tunnelName, Arrays.asList(tunnelIds)) != null ? true : false; + } + + @Override + public List getLoadBalancingTunnelIds(String tunnelName) { + if (tunnelNameDisjoinTunnelIdInfo.get(tunnelName) != null) { + return tunnelNameDisjoinTunnelIdInfo.get(tunnelName).value(); + } + return null; + } + + @Override + public boolean removeLoadBalancingTunnelIdsInfo(String tunnelName) { + if (tunnelNameDisjoinTunnelIdInfo.remove(tunnelName) == null) { + log.error("Failed to remove entry {} for this tunnelName in DisjointTunnelIdsInfoMap" + tunnelName); + return false; + } + return true; + } + + /* @Override + public boolean removeDisjointPathInfo(String tunnelName) { + if (tunnelNameDisjointPathInfo.remove(tunnelName) == null) { + log.error("Failed to remove entry {} for this tunnelName in DisjointPathInfoMap", tunnelName); + return false; + } + return true; + }*/ } diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/PcePathInfo.java b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/PcePathInfo.java index 6497e36a53..3f38ddd83f 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/PcePathInfo.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/PcePathInfo.java @@ -43,6 +43,8 @@ public final class PcePathInfo { private List explicitPathInfo; //Explicit path info to compute explicit path + private boolean loadBalancing; //load balancing option + /** * Initialization of member variables. * @@ -52,19 +54,22 @@ public final class PcePathInfo { * @param constraints list of constraints * @param lspType lsp type * @param explicitPathInfo explicit path info + * @param loadBalancing load balancing option */ public PcePathInfo(DeviceId src, DeviceId dst, String name, List constraints, LspType lspType, - List explicitPathInfo) { + List explicitPathInfo, + boolean loadBalancing) { this.src = src; this.dst = dst; this.name = name; this.constraints = constraints; this.lspType = lspType; this.explicitPathInfo = explicitPathInfo; + this.loadBalancing = loadBalancing; } /** @@ -77,6 +82,7 @@ public final class PcePathInfo { this.constraints = null; this.lspType = null; this.explicitPathInfo = null; + this.loadBalancing = false; } /** @@ -187,9 +193,27 @@ public final class PcePathInfo { this.explicitPathInfo = explicitPathInfo; } + /** + * Returns whether stored path has enabled load balancing. + * + * @return load balancing option is enable + */ + public boolean isLoadBalancing() { + return loadBalancing; + } + + /** + * Sets load balancing option is enable. + * + * @param loadBalancing load balancing option is enable + */ + public void loadBalancing(boolean loadBalancing) { + this.loadBalancing = loadBalancing; + } + @Override public int hashCode() { - return Objects.hash(src, dst, name, constraints, lspType, explicitPathInfo); + return Objects.hash(src, dst, name, constraints, lspType, explicitPathInfo, loadBalancing); } @Override @@ -204,7 +228,8 @@ public final class PcePathInfo { Objects.equals(this.name, other.name) && Objects.equals(this.constraints, other.constraints) && Objects.equals(this.lspType, other.lspType) && - Objects.equals(this.explicitPathInfo, other.explicitPathInfo); + Objects.equals(this.explicitPathInfo, other.explicitPathInfo) && + Objects.equals(this.loadBalancing, other.loadBalancing); } return false; } @@ -219,6 +244,7 @@ public final class PcePathInfo { .add("Constraints", constraints) .add("explicitPathInfo", explicitPathInfo) .add("LspType", lspType) + .add("loadBalancing", loadBalancing) .toString(); } } diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java index 61f7fda011..9ca38cb922 100644 --- a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java +++ b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java @@ -15,6 +15,7 @@ */ package org.onosproject.pce.pcestore.api; +import org.onosproject.incubator.net.tunnel.TunnelId; import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pcestore.PcePathInfo; @@ -79,4 +80,35 @@ public interface PceStore { * @return list of explicit path info */ List getTunnelNameExplicitPathInfoMap(String tunnelName); + + //DisjointPath getDisjointPaths(String tunnelName); + + //boolean addDisjointPathInfo(String tunnelName, DisjointPath path); + + /** + * Stores load balancing tunnels by load balance path name. + * + * @param loadBalancingPathName load balancing path name + * @param tunnelIds list load balancing tunnels + * @return success or failure + */ + boolean addLoadBalancingTunnelIdsInfo(String loadBalancingPathName, TunnelId... tunnelIds); + + /** + * Query load balancing tunnels by load balance path name. + * + * @param loadBalancingPathName load balancing path name + * @return list of load balancing tunnels + */ + List getLoadBalancingTunnelIds(String loadBalancingPathName); + + /** + * Removes load balancing tunnel info. + * + * @param loadBalancingPathName load balancing path name + * @return success or failure + */ + boolean removeLoadBalancingTunnelIdsInfo(String loadBalancingPathName); + + //boolean removeDisjointPathInfo(String tunnelName); } diff --git a/apps/pce/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/pce/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml index 9704c5ca0d..1d4d5a3aa3 100644 --- a/apps/pce/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ b/apps/pce/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -27,5 +27,11 @@ + + + + + + diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/DistributedPceStoreTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/DistributedPceStoreTest.java index 0039c3c9ec..ccefcf4e1f 100644 --- a/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/DistributedPceStoreTest.java +++ b/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/DistributedPceStoreTest.java @@ -119,7 +119,7 @@ public class DistributedPceStoreTest { Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS); constraints1.add(bandwidth1); - failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null); + failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null, false); // Creates failedPathInfo2 DeviceId src2 = DeviceId.deviceId("foo2"); @@ -130,7 +130,7 @@ public class DistributedPceStoreTest { Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS); constraints2.add(bandwidth2); - failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null); + failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null, false); // Creates failedPathInfo3 DeviceId src3 = DeviceId.deviceId("foo3"); @@ -141,7 +141,7 @@ public class DistributedPceStoreTest { Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS); constraints3.add(bandwidth3); - failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null); + failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null, false); // Creates failedPathInfo4 DeviceId src4 = DeviceId.deviceId("foo4"); @@ -152,7 +152,7 @@ public class DistributedPceStoreTest { Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS); constraints4.add(bandwidth4); - failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null); + failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null, false); } @After diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/PcePathInfoTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/PcePathInfoTest.java index a13c634f65..fa2bc21c5e 100644 --- a/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/PcePathInfoTest.java +++ b/apps/pce/app/src/test/java/org/onosproject/pce/pcestore/PcePathInfoTest.java @@ -53,10 +53,10 @@ public class PcePathInfoTest { Constraint bandwidth13 = BandwidthConstraint.of(300, DataRateUnit.BPS); constraints1.add(bandwidth13); - PcePathInfo pathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null); + PcePathInfo pathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null, false); // create same object as above object - PcePathInfo samePathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null); + PcePathInfo samePathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null, false); // Create different object. DeviceId src2 = DeviceId.deviceId("foo2"); @@ -69,7 +69,7 @@ public class PcePathInfoTest { Constraint bandwidth22 = BandwidthConstraint.of(800, DataRateUnit.BPS); constraints2.add(bandwidth22); - PcePathInfo pathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null); + PcePathInfo pathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null, false); new EqualsTester().addEqualityGroup(pathInfo1, samePathInfo1) .addEqualityGroup(pathInfo2) @@ -93,7 +93,7 @@ public class PcePathInfoTest { Constraint bandwidth3 = BandwidthConstraint.of(300, DataRateUnit.BPS); constraints.add(bandwidth3); - PcePathInfo pathInfo = new PcePathInfo(src, dst, name, constraints, lspType, null); + PcePathInfo pathInfo = new PcePathInfo(src, dst, name, constraints, lspType, null, false); assertThat(src, is(pathInfo.src())); assertThat(dst, is(pathInfo.dst())); diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java b/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java index 8688fb33ca..76e0e84a79 100644 --- a/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java +++ b/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java @@ -16,12 +16,15 @@ package org.onosproject.pce.util; import com.google.common.collect.ImmutableSet; +import org.onosproject.incubator.net.tunnel.TunnelId; import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pcestore.PcePathInfo; import org.onosproject.pce.pcestore.api.PceStore; import java.util.HashMap; import java.util.HashSet; +import java.util.Arrays; + import java.util.List; import java.util.Map; import java.util.Set; @@ -39,6 +42,9 @@ public class PceStoreAdapter implements PceStore { // Locally maintain with tunnel name as key and corresponding list of explicit path object private Map> tunnelNameExplicitPathInfoMap = new HashMap<>(); + //Mapping tunnel name with Disjoint paths + private Map> loadBalancingPathNameTunnelIdInfo = new HashMap<>(); + @Override public boolean existsFailedPathInfo(PcePathInfo pathInfo) { return failedPathInfoSet.contains(pathInfo); @@ -77,4 +83,47 @@ public class PceStoreAdapter implements PceStore { public List getTunnelNameExplicitPathInfoMap(String tunnelName) { return tunnelNameExplicitPathInfoMap.get(tunnelName); } + +/* @Override + public DisjointPath getDisjointPaths(String tunnelName) { + if (tunnelNameDisjointPathInfo.get(tunnelName) != null) { + return tunnelNameDisjointPathInfo.get(tunnelName); + } + return null; + } + + @Override + public boolean addDisjointPathInfo(String tunnelName, DisjointPath path) { + return tunnelNameDisjointPathInfo.put(tunnelName, path) != null ? true : false; + }*/ + + @Override + public boolean addLoadBalancingTunnelIdsInfo(String loadBalancingPathName, TunnelId... tunnelIds) { + return loadBalancingPathNameTunnelIdInfo.put(loadBalancingPathName, + Arrays.asList(tunnelIds)) != null ? true : false; + } + + @Override + public List getLoadBalancingTunnelIds(String loadBalancingPathName) { + if (loadBalancingPathNameTunnelIdInfo.get(loadBalancingPathName) != null) { + return loadBalancingPathNameTunnelIdInfo.get(loadBalancingPathName); + } + return null; + } + + @Override + public boolean removeLoadBalancingTunnelIdsInfo(String loadBalancingPathName) { + if (loadBalancingPathNameTunnelIdInfo.remove(loadBalancingPathName) == null) { + return false; + } + return true; + } + +/* @Override + public boolean removeDisjointPathInfo(String tunnelName) { + if (tunnelNameDisjointPathInfo.remove(tunnelName) == null) { + return false; + } + return true; + }*/ } diff --git a/apps/pce/pcerest/src/test/java/org/onosproject/pcerest/PcePathResourceTest.java b/apps/pce/pcerest/src/test/java/org/onosproject/pcerest/PcePathResourceTest.java index 20a53e1478..2a316caa9f 100644 --- a/apps/pce/pcerest/src/test/java/org/onosproject/pcerest/PcePathResourceTest.java +++ b/apps/pce/pcerest/src/test/java/org/onosproject/pcerest/PcePathResourceTest.java @@ -286,7 +286,7 @@ public class PcePathResourceTest extends PceResourceTest { */ @Test public void testDelete() { - expect(pceService.releasePath(anyObject())) + expect(pceService.releasePath(TunnelId.valueOf("1"))) .andReturn(true) .anyTimes(); replay(pceService); 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 5c4724886b..a899d9567d 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 @@ -16,9 +16,11 @@ package org.onosproject.pceweb; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import org.onlab.osgi.ServiceDirectory; import org.onlab.packet.IpAddress; import org.onlab.util.DataRateUnit; @@ -50,10 +52,12 @@ import org.onosproject.ui.topo.Highlights; import org.onosproject.ui.topo.LinkHighlight; import org.onosproject.ui.topo.Mod; import org.onosproject.ui.topo.NodeBadge; +import org.onosproject.ui.topo.TopoJson; import org.onosproject.ui.topo.TopoUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -85,6 +89,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { private static final String DST = "DST"; private static final String SRC = "SRC"; private static final String BANDWIDTH = "bw"; + private static final String LOADBALANCING = "lb"; private static final String BANDWIDTHTYPE = "bwtype"; private static final String COSTTYPE = "ctype"; private static final String LSPTYPE = "lsptype"; @@ -198,6 +203,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { String bandWidth = string(payload, BANDWIDTH); String bandWidthType = string(payload, BANDWIDTHTYPE); String costType = string(payload, COSTTYPE); + String loadBalancing = string(payload, LOADBALANCING); String lspType = string(payload, LSPTYPE); String tunnelName = string(payload, TUNNEL_NAME); @@ -226,7 +232,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { } if ((src != null) && (dst != null)) { - findAndSendPaths(src, dst, bandWidth, bandWidthType, costType, lspType, tunnelName); + findAndSendPaths(src, dst, bandWidth, bandWidthType, costType, lspType, tunnelName, loadBalancing); } } } @@ -371,8 +377,26 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { for (Tunnel tunnel : tunnelSet) { if (tunnel.type() == MPLS) { if (tunnel.state().equals(ACTIVE)) { - arrayNode.add(tunnel.tunnelId().toString()); - arrayNode.add(tunnel.tunnelName().toString()); + + if (tunnel.annotations().value("loadBalancingPathName") != null) { + boolean present = false; + if (!arrayNode.isNull()) { + for (JsonNode node : arrayNode) { + if (node.asText().equals(tunnel.annotations().value("loadBalancingPathName"))) { + present = true; + break; + } + } + if (!present) { + arrayNode.add(""); + arrayNode.add(tunnel.annotations().value("loadBalancingPathName")); + } + } + + } else { + arrayNode.add(tunnel.tunnelId().toString()); + arrayNode.add(tunnel.tunnelName().toString()); + } } } } @@ -394,12 +418,22 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { @Override public void process(ObjectNode payload) { String tunnelId = string(payload, TUNNEL_ID); + String pathName = string(payload, "tunnelname"); - if (tunnelId == null) { - log.error("PCE update path is failed."); + //TODO: if tunnel id null it is load banlanced path + if (tunnelId.equals("") && pathName != null) { + findAndSendPathsRemove(STRING_NULL, pathName); + /* List tunnelIds = pceService.getLoadBalancedPath(pathName); + for (TunnelId id : tunnelIds) { + Tunnel tunnel = tunnelService.queryTunnel(id); + if (tunnel != null) { + + } + }*/ + } else { + findAndSendPathsRemove(tunnelId, null); } - findAndSendPathsRemove(tunnelId); } } @@ -421,8 +455,27 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { tunnelSet = tunnelService.queryTunnel(MPLS); for (Tunnel tunnel : tunnelSet) { if (tunnel.state().equals(ACTIVE)) { - arrayNode.add(tunnel.tunnelId().toString()); - arrayNode.add(tunnel.tunnelName().toString()); + //TODO: if it is load balancing need to check whether to send tunnel ID as null or some negative + //TODO;value + if (tunnel.annotations().value("loadBalancingPathName") != null) { + boolean present = false; + if (!arrayNode.isNull()) { + for (JsonNode node : arrayNode) { + if (node.asText().equals(tunnel.annotations().value("loadBalancingPathName"))) { + present = true; + break; + } + } + if (!present) { + arrayNode.add(""); + arrayNode.add(tunnel.annotations().value("loadBalancingPathName")); + } + } + + } else { + arrayNode.add(tunnel.tunnelId().toString()); + arrayNode.add(tunnel.tunnelName().toString()); + } } } @@ -443,26 +496,24 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { @Override public void process(ObjectNode payload) { String tunnelIdStr = string(payload, TUNNEL_ID); + String pathName = string(payload, "tunnelname"); - if (tunnelIdStr == null) { - log.error("Tunnel Id is NULL."); - return; - } - - if (tunnelIdStr.equals(STRING_NULL)) { - log.error("Tunnel Id is NULL."); - return; - } - - if (pceService == null) { - log.error("PCE service is not active"); - return; - } - - TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr); - Tunnel tunnel = tunnelService.queryTunnel(tunnelId); - if (tunnel != null) { - highlightsForTunnel(tunnel); + if (tunnelIdStr.equals("")) { + List tunnels = Lists.newLinkedList(); + List tunnelIds = pceService.queryLoadBalancingPath(pathName); + for (TunnelId id : tunnelIds) { + Tunnel t = tunnelService.queryTunnel(id); + tunnels.add(t); + } + if (!tunnels.isEmpty()) { + highlightsForTunnel(tunnels); + } + } else { + TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr); + Tunnel t = tunnelService.queryTunnel(tunnelId); + if (t != null) { + highlightsForTunnel(t); + } } } } @@ -492,7 +543,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { */ private void findAndSendPaths(ElementId src, ElementId dst, String bandWidth, String bandWidthType, String costType, - String lspType, String tunnelName) { + String lspType, String tunnelName, String loadBalancing) { log.debug("src={}; dst={};", src, dst); boolean path; List listConstrnt; @@ -515,9 +566,17 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { break; } + boolean loadBalancingOpt = Boolean.parseBoolean(loadBalancing); + //TODO: need to get explicit paths [temporarily using null as the value] - path = pceService.setupPath((DeviceId) src, (DeviceId) dst, - tunnelName, listConstrnt, lspTypeVal, null); + + if (loadBalancingOpt) { + path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal, + loadBalancingOpt); + } else { + path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal, + null); + } if (!path) { log.error("setup path is failed"); @@ -562,19 +621,24 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { * * @param tunnelIdStr tunnelId */ - private void findAndSendPathsRemove(String tunnelIdStr) { - if (tunnelIdStr != null) { + private void findAndSendPathsRemove(String tunnelIdStr, String pathName) { if (pceService == null) { log.error("PCE service is not active"); return; } + boolean path; + + if (tunnelIdStr.equals(STRING_NULL) && !pathName.equals(STRING_NULL)) { + path = pceService.releasePath(pathName); + } else { + TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr); + path = pceService.releasePath(tunnelId); + } - TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr); - boolean path = pceService.releasePath(tunnelId); if (!path) { log.error("remove path is failed"); } - } + } private ImmutableSet.Builder buildPaths(ImmutableSet.Builder pathBuilder) { @@ -747,12 +811,22 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { hilightAndSendPaths(highlights); } + private void highlightsForTunnel(Tunnel... tunnels) { + highlightsForTunnel(Arrays.asList(tunnels)); + } /** * Handles the event of topology listeners. */ - private void highlightsForTunnel(Tunnel tunnel) { + private void highlightsForTunnel(List tunnels) { Highlights highlights = new Highlights(); paths.removeAll(paths); + + if (tunnels.isEmpty()) { + log.error("path does not exist"); + sendMessage(TopoJson.highlightsMessage(highlights)); + return; + } + for (Tunnel tunnel : tunnels) { if (tunnel.path() == null) { log.error("path does not exist"); sendMessage(highlightsMessage(highlights)); @@ -777,6 +851,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { } } paths.add(tunnel.path()); + } ImmutableSet.Builder builder = ImmutableSet.builder(); allPathLinks = buildPaths(builder).build(); 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 77292898e1..4a1b2f1ee2 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 @@ -121,6 +121,10 @@ 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 load balancing related inputs. + addAttribute('pce-load-balancing-option-name', 'pce-load-balance', 'Load balancing', 'checkbox'); + //Add the LSP type related inputs. p.append('span').text("Lsp Type *"); p.append('br'); @@ -200,6 +204,11 @@ return; } + if (val == 'LoadBalancing') { + constType = 'LB'; + return; + } + if (constType == 'TUNNEL') { p.append('span').text('Tunnel Id: '); p.append('span').text(val); @@ -464,6 +473,8 @@ } } + var loadBalancedOption = isChecked('pce-load-balance'); + var lspTypeVal = null; if (isChecked('pce-lsp-type-cr')) { @@ -480,6 +491,7 @@ bw: bandValue, bwtype: bandType, ctype: costTypeVal, + lb: loadBalancedOption, lsptype: lspTypeVal, tunnelname: getCheckedValue('pce-tunnel-name-id') }); @@ -515,7 +527,8 @@ var tunnelNameVal = isChecked('tunnel-id-remove-'+idx); if (tunnelNameVal) { wss.sendEvent(remPathmsg, { - tunnelid: tunnelNameDataRemove.a[idx] + tunnelid: tunnelNameDataRemove.a[idx], + tunnelname: tunnelNameDataRemove.a[++idx] }); } idx++; @@ -530,7 +543,8 @@ var tunnelNameVal = isChecked('tunnel-id-query-'+idx); if (tunnelNameVal) { wss.sendEvent(showTunnelHighlightMsg, { - tunnelid: tunnelNameDataQuery.a[idx] + tunnelid: tunnelNameDataQuery.a[idx], + tunnelname: tunnelNameDataQuery.a[++idx] }); } idx++;