Pce Load Balancing

Change-Id: I417e7473db86fa26f7a2dc46122dcacdeb584108
This commit is contained in:
Satish K 2017-04-05 15:27:23 +05:30 committed by Satishk-Huawei
parent 2eb5d84bca
commit ba1c912fa4
15 changed files with 685 additions and 59 deletions

View File

@ -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;
}
}
}

View File

@ -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<TunnelId> 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());
}
}

View File

@ -95,6 +95,10 @@ public class PceSetupPathCommand extends AbstractShellCommand {
required = false, multiValued = true) required = false, multiValued = true)
String[] explicitPathInfoStrings; 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) //explicitPathInfo format : Type/SubType/Value(DeviceId or Link info)
//If Value is Device : Type/SubType/deviceId //If Value is Device : Type/SubType/deviceId
//If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo //If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo
@ -188,6 +192,15 @@ public class PceSetupPathCommand extends AbstractShellCommand {
explicitPathInfo.add(obj); 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)) { if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, explicitPathInfo)) {
error("Path creation failed."); error("Path creation failed.");
} }

View File

@ -17,6 +17,7 @@ package org.onosproject.pce.pceservice;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.net.DisjointPath;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -168,6 +169,7 @@ public class PceManager implements PceService {
private ApplicationId appId; private ApplicationId appId;
private final TopologyListener topologyListener = new InternalTopologyListener(); private final TopologyListener topologyListener = new InternalTopologyListener();
public static final String LOAD_BALANCING_PATH_NAME = "loadBalancingPathName";
private List<TunnelId> rsvpTunnelsWithLocalBw = new ArrayList<>(); private List<TunnelId> rsvpTunnelsWithLocalBw = new ArrayList<>();
@ -421,13 +423,26 @@ public class PceManager implements PceService {
@Override @Override
public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
LspType lspType) { LspType lspType) {
return setupPath(src, dst, tunnelName, constraints, lspType, null); return setupPath(src, dst, tunnelName, constraints, lspType, null, false);
} }
//[TODO:] handle requests in queue //[TODO:] handle requests in queue
@Override @Override
public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
LspType lspType, List<ExplicitPathInfo> explicitPathInfo) { LspType lspType, List<ExplicitPathInfo> explicitPathInfo) {
return setupPath(src, dst, tunnelName, constraints, lspType, explicitPathInfo, false);
}
@Override
public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> 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<Constraint> constraints,
LspType lspType, List<ExplicitPathInfo> explicitPathInfo, boolean loadBalancing) {
checkNotNull(src); checkNotNull(src);
checkNotNull(dst); checkNotNull(dst);
checkNotNull(tunnelName); checkNotNull(tunnelName);
@ -439,7 +454,8 @@ public class PceManager implements PceService {
if (srcDevice == null || dstDevice == null) { if (srcDevice == null || dstDevice == null) {
// Device is not known. // 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; return false;
} }
@ -449,7 +465,8 @@ public class PceManager implements PceService {
if (srcLsrId == null || dstLsrId == null) { if (srcLsrId == null || dstLsrId == null) {
// LSR id is not known. // 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; return false;
} }
@ -457,7 +474,8 @@ public class PceManager implements PceService {
DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class); DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class);
if (cfg == null) { if (cfg == null) {
log.debug("No session to ingress."); 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; return false;
} }
@ -495,6 +513,11 @@ public class PceManager implements PceService {
} }
Set<Path> computedPathSet = Sets.newLinkedHashSet(); Set<Path> computedPathSet = Sets.newLinkedHashSet();
if (loadBalancing) {
return setupDisjointPaths(src, dst, constraints, tunnelName, bwConstraintValue, lspType, costConstraint,
srcEndPoint, dstEndPoint);
}
if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) { if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) {
List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints); List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints);
if (finalComputedPath == null) { if (finalComputedPath == null) {
@ -516,7 +539,8 @@ public class PceManager implements PceService {
// NO-PATH // NO-PATH
if (computedPathSet.isEmpty()) { 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; return false;
} }
@ -550,14 +574,15 @@ public class PceManager implements PceService {
if (bwConstraintValue != 0) { if (bwConstraintValue != 0) {
if (!reserveBandwidth(computedPath, bwConstraintValue, null)) { if (!reserveBandwidth(computedPath, bwConstraintValue, null)) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints,
lspType, explicitPathInfo)); lspType, explicitPathInfo, loadBalancing));
return false; return false;
} }
} }
TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath); TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
if (tunnelId == null) { 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) { if (bwConstraintValue != 0) {
computedPath.links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln), computedPath.links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
@ -574,6 +599,114 @@ public class PceManager implements PceService {
return true; return true;
} }
private boolean setupDisjointPaths(DeviceId src, DeviceId dst, List<Constraint> constraints, String tunnelName,
double bwConstraintValue, LspType lspType, CostConstraint costConstraint,
TunnelEndPoint srcEndPoint, TunnelEndPoint dstEndPoint) {
Set<DisjointPath> 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 @Override
public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) { public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
checkNotNull(tunnelId); checkNotNull(tunnelId);
@ -750,6 +883,26 @@ public class PceManager implements PceService {
return tunnelService.downTunnel(appId, tunnel.tunnelId()); return tunnelService.downTunnel(appId, tunnel.tunnelId());
} }
@Override
public boolean releasePath(String loadBalancingPathName) {
checkNotNull(loadBalancingPathName);
List<TunnelId> 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 @Override
public Iterable<Tunnel> queryAllPath() { public Iterable<Tunnel> queryAllPath() {
return tunnelService.queryTunnel(MPLS); return tunnelService.queryTunnel(MPLS);
@ -907,7 +1060,8 @@ public class PceManager implements PceService {
pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
.path().dst().deviceId(), tunnel.tunnelName().value(), constraintList, .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)), 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 //Release that tunnel calling PCInitiate
releasePath(tunnel.tunnelId()); releasePath(tunnel.tunnelId());
} }
@ -1079,7 +1233,8 @@ public class PceManager implements PceService {
links.get(links.size() - 1).dst().deviceId(), links.get(links.size() - 1).dst().deviceId(),
tunnel.tunnelName().value(), constraints, lspType, tunnel.tunnelName().value(), constraints, lspType,
pceStore.getTunnelNameExplicitPathInfoMap(tunnel pceStore.getTunnelNameExplicitPathInfoMap(tunnel
.tunnelName().value()))); .tunnelName().value()), tunnel.annotations()
.value(LOAD_BALANCING_PATH_NAME) != null ? true : false));
} }
break; break;
@ -1115,6 +1270,11 @@ public class PceManager implements PceService {
return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName); return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName);
} }
@Override
public List<TunnelId> queryLoadBalancingPath(String pathName) {
return pceStore.getLoadBalancingTunnelIds(pathName);
}
//Computes path from tunnel store and also path failed to setup. //Computes path from tunnel store and also path failed to setup.
private void callForOptimization() { private void callForOptimization() {
//Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)] //Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]

View File

@ -56,6 +56,35 @@ public interface PceService {
boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType, boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType,
List<ExplicitPathInfo> explicitPathInfo); List<ExplicitPathInfo> 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<Constraint> 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<Constraint> constraints, LspType lspType,
List<ExplicitPathInfo> explicitPathInfo, boolean loadBalancing);
/** /**
* Updates an existing path. * Updates an existing path.
* *
@ -73,6 +102,14 @@ public interface PceService {
*/ */
boolean releasePath(TunnelId tunnelId); 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. * Queries all paths.
* *
@ -95,4 +132,12 @@ public interface PceService {
* @return list of explicit path info * @return list of explicit path info
*/ */
List<ExplicitPathInfo> explicitPathInfoList(String tunnelName); List<ExplicitPathInfo> 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<TunnelId> queryLoadBalancingPath(String pathName);
} }

View File

@ -16,6 +16,7 @@
package org.onosproject.pce.pcestore; package org.onosproject.pce.pcestore;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate; 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.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Service;
import org.onlab.util.KryoNamespace; import org.onlab.util.KryoNamespace;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pceservice.LspType; import org.onosproject.pce.pceservice.LspType;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint; import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
@ -57,6 +59,9 @@ public class DistributedPceStore implements PceStore {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService; protected StorageService storageService;
//Mapping tunnel name with Disjoint paths
private ConsistentMap<String, List<TunnelId>> tunnelNameDisjoinTunnelIdInfo;
// List of Failed path info // List of Failed path info
private DistributedSet<PcePathInfo> failedPathSet; private DistributedSet<PcePathInfo> failedPathSet;
@ -96,6 +101,15 @@ public class DistributedPceStore implements PceStore {
.build())) .build()))
.build(); .build();
tunnelNameDisjoinTunnelIdInfo = storageService.<String, List<TunnelId>>consistentMapBuilder()
.withName("onos-pce-disjointTunnelIds")
.withSerializer(Serializer.using(
new KryoNamespace.Builder()
.register(KryoNamespaces.API)
.register(TunnelId.class)
.build()))
.build();
log.info("Started"); log.info("Started");
} }
@ -157,4 +171,51 @@ public class DistributedPceStore implements PceStore {
return null; 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<TunnelId> 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;
}*/
} }

View File

@ -43,6 +43,8 @@ public final class PcePathInfo {
private List<ExplicitPathInfo> explicitPathInfo; //Explicit path info to compute explicit path private List<ExplicitPathInfo> explicitPathInfo; //Explicit path info to compute explicit path
private boolean loadBalancing; //load balancing option
/** /**
* Initialization of member variables. * Initialization of member variables.
* *
@ -52,19 +54,22 @@ public final class PcePathInfo {
* @param constraints list of constraints * @param constraints list of constraints
* @param lspType lsp type * @param lspType lsp type
* @param explicitPathInfo explicit path info * @param explicitPathInfo explicit path info
* @param loadBalancing load balancing option
*/ */
public PcePathInfo(DeviceId src, public PcePathInfo(DeviceId src,
DeviceId dst, DeviceId dst,
String name, String name,
List<Constraint> constraints, List<Constraint> constraints,
LspType lspType, LspType lspType,
List<ExplicitPathInfo> explicitPathInfo) { List<ExplicitPathInfo> explicitPathInfo,
boolean loadBalancing) {
this.src = src; this.src = src;
this.dst = dst; this.dst = dst;
this.name = name; this.name = name;
this.constraints = constraints; this.constraints = constraints;
this.lspType = lspType; this.lspType = lspType;
this.explicitPathInfo = explicitPathInfo; this.explicitPathInfo = explicitPathInfo;
this.loadBalancing = loadBalancing;
} }
/** /**
@ -77,6 +82,7 @@ public final class PcePathInfo {
this.constraints = null; this.constraints = null;
this.lspType = null; this.lspType = null;
this.explicitPathInfo = null; this.explicitPathInfo = null;
this.loadBalancing = false;
} }
/** /**
@ -187,9 +193,27 @@ public final class PcePathInfo {
this.explicitPathInfo = explicitPathInfo; 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 @Override
public int hashCode() { public int hashCode() {
return Objects.hash(src, dst, name, constraints, lspType, explicitPathInfo); return Objects.hash(src, dst, name, constraints, lspType, explicitPathInfo, loadBalancing);
} }
@Override @Override
@ -204,7 +228,8 @@ public final class PcePathInfo {
Objects.equals(this.name, other.name) && Objects.equals(this.name, other.name) &&
Objects.equals(this.constraints, other.constraints) && Objects.equals(this.constraints, other.constraints) &&
Objects.equals(this.lspType, other.lspType) && 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; return false;
} }
@ -219,6 +244,7 @@ public final class PcePathInfo {
.add("Constraints", constraints) .add("Constraints", constraints)
.add("explicitPathInfo", explicitPathInfo) .add("explicitPathInfo", explicitPathInfo)
.add("LspType", lspType) .add("LspType", lspType)
.add("loadBalancing", loadBalancing)
.toString(); .toString();
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.onosproject.pce.pcestore.api; package org.onosproject.pce.pcestore.api;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pcestore.PcePathInfo; import org.onosproject.pce.pcestore.PcePathInfo;
@ -79,4 +80,35 @@ public interface PceStore {
* @return list of explicit path info * @return list of explicit path info
*/ */
List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName); List<ExplicitPathInfo> 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<TunnelId> 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);
} }

View File

@ -27,5 +27,11 @@
<command> <command>
<action class="org.onosproject.pce.cli.PceDeletePathCommand"/> <action class="org.onosproject.pce.cli.PceDeletePathCommand"/>
</command> </command>
<command>
<action class="org.onosproject.pce.cli.PceQueryLoadBalancingPathCommand"/>
</command>
<command>
<action class="org.onosproject.pce.cli.PceDeleteLoadBalancingPathCommand"/>
</command>
</command-bundle> </command-bundle>
</blueprint> </blueprint>

View File

@ -119,7 +119,7 @@ public class DistributedPceStoreTest {
Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS); Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS);
constraints1.add(bandwidth1); constraints1.add(bandwidth1);
failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null); failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null, false);
// Creates failedPathInfo2 // Creates failedPathInfo2
DeviceId src2 = DeviceId.deviceId("foo2"); DeviceId src2 = DeviceId.deviceId("foo2");
@ -130,7 +130,7 @@ public class DistributedPceStoreTest {
Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS); Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS);
constraints2.add(bandwidth2); constraints2.add(bandwidth2);
failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null); failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null, false);
// Creates failedPathInfo3 // Creates failedPathInfo3
DeviceId src3 = DeviceId.deviceId("foo3"); DeviceId src3 = DeviceId.deviceId("foo3");
@ -141,7 +141,7 @@ public class DistributedPceStoreTest {
Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS); Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS);
constraints3.add(bandwidth3); constraints3.add(bandwidth3);
failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null); failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null, false);
// Creates failedPathInfo4 // Creates failedPathInfo4
DeviceId src4 = DeviceId.deviceId("foo4"); DeviceId src4 = DeviceId.deviceId("foo4");
@ -152,7 +152,7 @@ public class DistributedPceStoreTest {
Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS); Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS);
constraints4.add(bandwidth4); constraints4.add(bandwidth4);
failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null); failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null, false);
} }
@After @After

View File

@ -53,10 +53,10 @@ public class PcePathInfoTest {
Constraint bandwidth13 = BandwidthConstraint.of(300, DataRateUnit.BPS); Constraint bandwidth13 = BandwidthConstraint.of(300, DataRateUnit.BPS);
constraints1.add(bandwidth13); 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 // 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. // Create different object.
DeviceId src2 = DeviceId.deviceId("foo2"); DeviceId src2 = DeviceId.deviceId("foo2");
@ -69,7 +69,7 @@ public class PcePathInfoTest {
Constraint bandwidth22 = BandwidthConstraint.of(800, DataRateUnit.BPS); Constraint bandwidth22 = BandwidthConstraint.of(800, DataRateUnit.BPS);
constraints2.add(bandwidth22); 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) new EqualsTester().addEqualityGroup(pathInfo1, samePathInfo1)
.addEqualityGroup(pathInfo2) .addEqualityGroup(pathInfo2)
@ -93,7 +93,7 @@ public class PcePathInfoTest {
Constraint bandwidth3 = BandwidthConstraint.of(300, DataRateUnit.BPS); Constraint bandwidth3 = BandwidthConstraint.of(300, DataRateUnit.BPS);
constraints.add(bandwidth3); 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(src, is(pathInfo.src()));
assertThat(dst, is(pathInfo.dst())); assertThat(dst, is(pathInfo.dst()));

View File

@ -16,12 +16,15 @@
package org.onosproject.pce.util; package org.onosproject.pce.util;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.pce.pceservice.ExplicitPathInfo; import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pcestore.PcePathInfo; import org.onosproject.pce.pcestore.PcePathInfo;
import org.onosproject.pce.pcestore.api.PceStore; import org.onosproject.pce.pcestore.api.PceStore;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; 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 // Locally maintain with tunnel name as key and corresponding list of explicit path object
private Map<String, List<ExplicitPathInfo>> tunnelNameExplicitPathInfoMap = new HashMap<>(); private Map<String, List<ExplicitPathInfo>> tunnelNameExplicitPathInfoMap = new HashMap<>();
//Mapping tunnel name with Disjoint paths
private Map<String, List<TunnelId>> loadBalancingPathNameTunnelIdInfo = new HashMap<>();
@Override @Override
public boolean existsFailedPathInfo(PcePathInfo pathInfo) { public boolean existsFailedPathInfo(PcePathInfo pathInfo) {
return failedPathInfoSet.contains(pathInfo); return failedPathInfoSet.contains(pathInfo);
@ -77,4 +83,47 @@ public class PceStoreAdapter implements PceStore {
public List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName) { public List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName) {
return tunnelNameExplicitPathInfoMap.get(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<TunnelId> 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;
}*/
} }

View File

@ -286,7 +286,7 @@ public class PcePathResourceTest extends PceResourceTest {
*/ */
@Test @Test
public void testDelete() { public void testDelete() {
expect(pceService.releasePath(anyObject())) expect(pceService.releasePath(TunnelId.valueOf("1")))
.andReturn(true) .andReturn(true)
.anyTimes(); .anyTimes();
replay(pceService); replay(pceService);

View File

@ -16,9 +16,11 @@
package org.onosproject.pceweb; package org.onosproject.pceweb;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.onlab.osgi.ServiceDirectory; import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.IpAddress; import org.onlab.packet.IpAddress;
import org.onlab.util.DataRateUnit; 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.LinkHighlight;
import org.onosproject.ui.topo.Mod; import org.onosproject.ui.topo.Mod;
import org.onosproject.ui.topo.NodeBadge; import org.onosproject.ui.topo.NodeBadge;
import org.onosproject.ui.topo.TopoJson;
import org.onosproject.ui.topo.TopoUtils; import org.onosproject.ui.topo.TopoUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -85,6 +89,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
private static final String DST = "DST"; private static final String DST = "DST";
private static final String SRC = "SRC"; private static final String SRC = "SRC";
private static final String BANDWIDTH = "bw"; private static final String BANDWIDTH = "bw";
private static final String LOADBALANCING = "lb";
private static final String BANDWIDTHTYPE = "bwtype"; private static final String BANDWIDTHTYPE = "bwtype";
private static final String COSTTYPE = "ctype"; private static final String COSTTYPE = "ctype";
private static final String LSPTYPE = "lsptype"; private static final String LSPTYPE = "lsptype";
@ -198,6 +203,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
String bandWidth = string(payload, BANDWIDTH); String bandWidth = string(payload, BANDWIDTH);
String bandWidthType = string(payload, BANDWIDTHTYPE); String bandWidthType = string(payload, BANDWIDTHTYPE);
String costType = string(payload, COSTTYPE); String costType = string(payload, COSTTYPE);
String loadBalancing = string(payload, LOADBALANCING);
String lspType = string(payload, LSPTYPE); String lspType = string(payload, LSPTYPE);
String tunnelName = string(payload, TUNNEL_NAME); String tunnelName = string(payload, TUNNEL_NAME);
@ -226,7 +232,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
} }
if ((src != null) && (dst != null)) { 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) { for (Tunnel tunnel : tunnelSet) {
if (tunnel.type() == MPLS) { if (tunnel.type() == MPLS) {
if (tunnel.state().equals(ACTIVE)) { 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 @Override
public void process(ObjectNode payload) { public void process(ObjectNode payload) {
String tunnelId = string(payload, TUNNEL_ID); String tunnelId = string(payload, TUNNEL_ID);
String pathName = string(payload, "tunnelname");
if (tunnelId == null) { //TODO: if tunnel id null it is load banlanced path
log.error("PCE update path is failed."); if (tunnelId.equals("") && pathName != null) {
findAndSendPathsRemove(STRING_NULL, pathName);
/* List<TunnelId> 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); tunnelSet = tunnelService.queryTunnel(MPLS);
for (Tunnel tunnel : tunnelSet) { for (Tunnel tunnel : tunnelSet) {
if (tunnel.state().equals(ACTIVE)) { if (tunnel.state().equals(ACTIVE)) {
arrayNode.add(tunnel.tunnelId().toString()); //TODO: if it is load balancing need to check whether to send tunnel ID as null or some negative
arrayNode.add(tunnel.tunnelName().toString()); //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 @Override
public void process(ObjectNode payload) { public void process(ObjectNode payload) {
String tunnelIdStr = string(payload, TUNNEL_ID); String tunnelIdStr = string(payload, TUNNEL_ID);
String pathName = string(payload, "tunnelname");
if (tunnelIdStr == null) { if (tunnelIdStr.equals("")) {
log.error("Tunnel Id is NULL."); List<Tunnel> tunnels = Lists.newLinkedList();
return; List<TunnelId> tunnelIds = pceService.queryLoadBalancingPath(pathName);
} for (TunnelId id : tunnelIds) {
Tunnel t = tunnelService.queryTunnel(id);
if (tunnelIdStr.equals(STRING_NULL)) { tunnels.add(t);
log.error("Tunnel Id is NULL."); }
return; if (!tunnels.isEmpty()) {
} highlightsForTunnel(tunnels);
}
if (pceService == null) { } else {
log.error("PCE service is not active"); TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
return; Tunnel t = tunnelService.queryTunnel(tunnelId);
} if (t != null) {
highlightsForTunnel(t);
TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr); }
Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
if (tunnel != null) {
highlightsForTunnel(tunnel);
} }
} }
} }
@ -492,7 +543,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
*/ */
private void findAndSendPaths(ElementId src, ElementId dst, String bandWidth, private void findAndSendPaths(ElementId src, ElementId dst, String bandWidth,
String bandWidthType, String costType, String bandWidthType, String costType,
String lspType, String tunnelName) { String lspType, String tunnelName, String loadBalancing) {
log.debug("src={}; dst={};", src, dst); log.debug("src={}; dst={};", src, dst);
boolean path; boolean path;
List<Constraint> listConstrnt; List<Constraint> listConstrnt;
@ -515,9 +566,17 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
break; break;
} }
boolean loadBalancingOpt = Boolean.parseBoolean(loadBalancing);
//TODO: need to get explicit paths [temporarily using null as the value] //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) { if (!path) {
log.error("setup path is failed"); log.error("setup path is failed");
@ -562,19 +621,24 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
* *
* @param tunnelIdStr tunnelId * @param tunnelIdStr tunnelId
*/ */
private void findAndSendPathsRemove(String tunnelIdStr) { private void findAndSendPathsRemove(String tunnelIdStr, String pathName) {
if (tunnelIdStr != null) {
if (pceService == null) { if (pceService == null) {
log.error("PCE service is not active"); log.error("PCE service is not active");
return; 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) { if (!path) {
log.error("remove path is failed"); log.error("remove path is failed");
} }
}
} }
private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) { private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) {
@ -747,12 +811,22 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
hilightAndSendPaths(highlights); hilightAndSendPaths(highlights);
} }
private void highlightsForTunnel(Tunnel... tunnels) {
highlightsForTunnel(Arrays.asList(tunnels));
}
/** /**
* Handles the event of topology listeners. * Handles the event of topology listeners.
*/ */
private void highlightsForTunnel(Tunnel tunnel) { private void highlightsForTunnel(List<Tunnel> tunnels) {
Highlights highlights = new Highlights(); Highlights highlights = new Highlights();
paths.removeAll(paths); 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) { if (tunnel.path() == null) {
log.error("path does not exist"); log.error("path does not exist");
sendMessage(highlightsMessage(highlights)); sendMessage(highlightsMessage(highlights));
@ -777,6 +851,7 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
} }
} }
paths.add(tunnel.path()); paths.add(tunnel.path());
}
ImmutableSet.Builder<Link> builder = ImmutableSet.builder(); ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
allPathLinks = buildPaths(builder).build(); allPathLinks = buildPaths(builder).build();

View File

@ -121,6 +121,10 @@
addAttribute('pce-cost-type-name', 'pce-cost-type', 'Cost Type', 'checkbox'); 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-igp', 'IGP', 'radio');
addAttribute('pce-cost-type-valname', 'pce-cost-type-te', 'TE', '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. //Add the LSP type related inputs.
p.append('span').text("Lsp Type *"); p.append('span').text("Lsp Type *");
p.append('br'); p.append('br');
@ -200,6 +204,11 @@
return; return;
} }
if (val == 'LoadBalancing') {
constType = 'LB';
return;
}
if (constType == 'TUNNEL') { if (constType == 'TUNNEL') {
p.append('span').text('Tunnel Id: '); p.append('span').text('Tunnel Id: ');
p.append('span').text(val); p.append('span').text(val);
@ -464,6 +473,8 @@
} }
} }
var loadBalancedOption = isChecked('pce-load-balance');
var lspTypeVal = null; var lspTypeVal = null;
if (isChecked('pce-lsp-type-cr')) { if (isChecked('pce-lsp-type-cr')) {
@ -480,6 +491,7 @@
bw: bandValue, bw: bandValue,
bwtype: bandType, bwtype: bandType,
ctype: costTypeVal, ctype: costTypeVal,
lb: loadBalancedOption,
lsptype: lspTypeVal, lsptype: lspTypeVal,
tunnelname: getCheckedValue('pce-tunnel-name-id') tunnelname: getCheckedValue('pce-tunnel-name-id')
}); });
@ -515,7 +527,8 @@
var tunnelNameVal = isChecked('tunnel-id-remove-'+idx); var tunnelNameVal = isChecked('tunnel-id-remove-'+idx);
if (tunnelNameVal) { if (tunnelNameVal) {
wss.sendEvent(remPathmsg, { wss.sendEvent(remPathmsg, {
tunnelid: tunnelNameDataRemove.a[idx] tunnelid: tunnelNameDataRemove.a[idx],
tunnelname: tunnelNameDataRemove.a[++idx]
}); });
} }
idx++; idx++;
@ -530,7 +543,8 @@
var tunnelNameVal = isChecked('tunnel-id-query-'+idx); var tunnelNameVal = isChecked('tunnel-id-query-'+idx);
if (tunnelNameVal) { if (tunnelNameVal) {
wss.sendEvent(showTunnelHighlightMsg, { wss.sendEvent(showTunnelHighlightMsg, {
tunnelid: tunnelNameDataQuery.a[idx] tunnelid: tunnelNameDataQuery.a[idx],
tunnelname: tunnelNameDataQuery.a[++idx]
}); });
} }
idx++; idx++;