mirror of
				https://github.com/opennetworkinglab/onos.git
				synced 2025-10-27 06:11:47 +01:00 
			
		
		
		
	Pce Load Balancing
Change-Id: I417e7473db86fa26f7a2dc46122dcacdeb584108
This commit is contained in:
		
							parent
							
								
									2eb5d84bca
								
							
						
					
					
						commit
						ba1c912fa4
					
				| @ -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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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()); | ||||
|     } | ||||
| } | ||||
| @ -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."); | ||||
|         } | ||||
|  | ||||
| @ -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<TunnelId> rsvpTunnelsWithLocalBw = new ArrayList<>(); | ||||
| 
 | ||||
| @ -421,13 +423,26 @@ public class PceManager implements PceService { | ||||
|     @Override | ||||
|     public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> 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<Constraint> constraints, | ||||
|                              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(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<Path> computedPathSet = Sets.newLinkedHashSet(); | ||||
| 
 | ||||
|         if (loadBalancing) { | ||||
|             return setupDisjointPaths(src, dst, constraints, tunnelName, bwConstraintValue, lspType, costConstraint, | ||||
|                     srcEndPoint, dstEndPoint); | ||||
|         } | ||||
| 
 | ||||
|         if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) { | ||||
|             List<Path> 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<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 | ||||
|     public boolean updatePath(TunnelId tunnelId, List<Constraint> 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<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 | ||||
|     public Iterable<Tunnel> 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<TunnelId> 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)] | ||||
|  | ||||
| @ -56,6 +56,35 @@ public interface PceService { | ||||
|     boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType, | ||||
|                       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. | ||||
|      * | ||||
| @ -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<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); | ||||
| } | ||||
| @ -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<String, List<TunnelId>> tunnelNameDisjoinTunnelIdInfo; | ||||
| 
 | ||||
|     // List of Failed path info | ||||
|     private DistributedSet<PcePathInfo> failedPathSet; | ||||
| 
 | ||||
| @ -96,6 +101,15 @@ public class DistributedPceStore implements PceStore { | ||||
|                                 .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"); | ||||
|     } | ||||
| 
 | ||||
| @ -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<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; | ||||
|     }*/ | ||||
| } | ||||
|  | ||||
| @ -43,6 +43,8 @@ public final class PcePathInfo { | ||||
| 
 | ||||
|     private List<ExplicitPathInfo> 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<Constraint> constraints, | ||||
|                     LspType lspType, | ||||
|                     List<ExplicitPathInfo> explicitPathInfo) { | ||||
|                     List<ExplicitPathInfo> 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(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<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); | ||||
| } | ||||
|  | ||||
| @ -27,5 +27,11 @@ | ||||
|     <command> | ||||
|       <action class="org.onosproject.pce.cli.PceDeletePathCommand"/> | ||||
|     </command> | ||||
|     <command> | ||||
|       <action class="org.onosproject.pce.cli.PceQueryLoadBalancingPathCommand"/> | ||||
|     </command> | ||||
|     <command> | ||||
|       <action class="org.onosproject.pce.cli.PceDeleteLoadBalancingPathCommand"/> | ||||
|     </command> | ||||
|   </command-bundle> | ||||
| </blueprint> | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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())); | ||||
|  | ||||
| @ -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<String, List<ExplicitPathInfo>> tunnelNameExplicitPathInfoMap = new HashMap<>(); | ||||
| 
 | ||||
|     //Mapping tunnel name with Disjoint paths | ||||
|     private Map<String, List<TunnelId>> loadBalancingPathNameTunnelIdInfo = new HashMap<>(); | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean existsFailedPathInfo(PcePathInfo pathInfo) { | ||||
|         return failedPathInfoSet.contains(pathInfo); | ||||
| @ -77,4 +83,47 @@ public class PceStoreAdapter implements PceStore { | ||||
|     public List<ExplicitPathInfo> 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<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; | ||||
|     }*/ | ||||
| } | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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<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); | ||||
|             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<Tunnel> tunnels = Lists.newLinkedList(); | ||||
|                 List<TunnelId> 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<Constraint> 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<Link> buildPaths(ImmutableSet.Builder<Link> 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<Tunnel> 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<Link> builder = ImmutableSet.builder(); | ||||
|         allPathLinks = buildPaths(builder).build(); | ||||
|  | ||||
| @ -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++; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user