mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-05 04:06:49 +02:00
ONOS-6306 Lamda resource allocation aware PCE
Change-Id: I9c6cc729c7bbfdc68f591f868e8d7143f207d5d3
This commit is contained in:
parent
ac8b229375
commit
02f8d2efd6
@ -46,6 +46,7 @@ import org.onosproject.net.resource.ResourceAllocation;
|
||||
import org.onosproject.net.resource.Resource;
|
||||
import org.onosproject.net.resource.ResourceService;
|
||||
import org.onosproject.net.resource.Resources;
|
||||
import org.onosproject.net.topology.AdapterLinkWeigher;
|
||||
import org.onosproject.net.topology.LinkWeight;
|
||||
import org.onosproject.net.topology.Topology;
|
||||
import org.onosproject.net.topology.TopologyEdge;
|
||||
@ -54,7 +55,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -63,6 +66,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.onosproject.net.OchSignal.toFlexGrid;
|
||||
import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
|
||||
|
||||
/**
|
||||
@ -129,41 +133,79 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
resources.add(dstPortResource);
|
||||
|
||||
// Calculate available light paths
|
||||
Set<Path> paths = getOpticalPaths(intent);
|
||||
|
||||
if (paths.isEmpty()) {
|
||||
throw new OpticalIntentCompilationException("Unable to find suitable lightpath for intent " + intent);
|
||||
}
|
||||
Stream<Path> paths = getOpticalPaths(intent);
|
||||
|
||||
// Static or dynamic lambda allocation
|
||||
String staticLambda = srcPort.annotations().value(AnnotationKeys.STATIC_LAMBDA);
|
||||
OchPort srcOchPort = (OchPort) srcPort;
|
||||
OchPort dstOchPort = (OchPort) dstPort;
|
||||
|
||||
Path firstPath = paths.iterator().next();
|
||||
// FIXME: need to actually reserve the lambda for static lambda's
|
||||
// static lambda case: early return
|
||||
if (staticLambda != null) {
|
||||
allocateResources(intent, resources);
|
||||
|
||||
OchSignal lambda = new OchSignal(Frequency.ofHz(Long.parseLong(staticLambda)),
|
||||
srcOchPort.lambda().channelSpacing(),
|
||||
srcOchPort.lambda().slotGranularity());
|
||||
return ImmutableList.of(createIntent(intent, firstPath, lambda));
|
||||
srcOchPort.lambda().channelSpacing(),
|
||||
srcOchPort.lambda().slotGranularity());
|
||||
log.debug("Using staticalluy assigned lambda : {}", lambda);
|
||||
|
||||
List<Resource> res = new ArrayList<>();
|
||||
|
||||
Path satPath = paths.filter(path -> {
|
||||
// FIXME trimming both ends (staticLambda assigned ports)
|
||||
// Proper fix is to let device advertise static lambda as resource.
|
||||
LinkedList<Link> links = new LinkedList<>(path.links());
|
||||
links.pollFirst();
|
||||
links.pollLast();
|
||||
|
||||
List<Resource> r = convertToResources(links, toFlexGrid(lambda));
|
||||
if (r.stream().allMatch(resourceService::isAvailable)) {
|
||||
// FIXME bad practice to have side-effect during stream
|
||||
res.addAll(r);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}).findFirst().orElse(null);
|
||||
|
||||
if (satPath == null) {
|
||||
// FIXME doing something very wrong to preserve old behavior
|
||||
// as a fallback
|
||||
log.warn("No feasible path between {}-{} using {}",
|
||||
src, dst, lambda);
|
||||
|
||||
satPath = getOpticalPaths(intent).iterator().next();
|
||||
if (satPath == null) {
|
||||
throw new OpticalIntentCompilationException(
|
||||
"Unable to find suitable lightpath for intent " + intent);
|
||||
}
|
||||
return ImmutableList.of(createIntent(intent, satPath, lambda));
|
||||
}
|
||||
|
||||
resources.addAll(res);
|
||||
allocateResources(intent, resources);
|
||||
|
||||
return ImmutableList.of(createIntent(intent, satPath, lambda));
|
||||
}
|
||||
|
||||
// FIXME: also check destination OCh port
|
||||
// non-tunable case: early return
|
||||
if (!srcOchPort.isTunable() || !dstOchPort.isTunable()) {
|
||||
allocateResources(intent, resources);
|
||||
|
||||
Path firstPath = paths.findAny().orElse(null);
|
||||
if (firstPath == null) {
|
||||
throw new OpticalIntentCompilationException("Unable to find suitable lightpath for intent " + intent);
|
||||
}
|
||||
OchSignal lambda = srcOchPort.lambda();
|
||||
// TODO apply the same as static lambda case above
|
||||
// - pick feasible path
|
||||
// - allocate resources
|
||||
//resources.addAll(convertToResources(firstPath.links(), toFlexGrid(lambda)));
|
||||
allocateResources(intent, resources);
|
||||
return ImmutableList.of(createIntent(intent, firstPath, lambda));
|
||||
}
|
||||
|
||||
// remaining cases
|
||||
// Use first path that the required resources are available
|
||||
Optional<Map.Entry<Path, List<OchSignal>>> found = paths.stream()
|
||||
Optional<Map.Entry<Path, List<OchSignal>>> found = paths
|
||||
.map(path -> Maps.immutableEntry(path, findFirstAvailableOch(path)))
|
||||
.filter(entry -> !entry.getValue().isEmpty())
|
||||
.filter(entry -> convertToResources(entry.getKey().links(),
|
||||
@ -192,7 +234,6 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
.key(parentIntent.key())
|
||||
.src(parentIntent.getSrc())
|
||||
.dst(parentIntent.getDst())
|
||||
// calling paths.iterator().next() is safe because of non-empty set
|
||||
.path(path)
|
||||
.lambda(lambda)
|
||||
.signalType(signalType)
|
||||
@ -205,7 +246,12 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
// reserve all of required resources
|
||||
List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), resources);
|
||||
if (allocations.isEmpty()) {
|
||||
log.info("Resource allocation for {} failed (resource request: {})", intent, resources);
|
||||
log.error("Resource allocation for {} failed (resource request: {})", intent.id(), resources);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("requested resources:\n\t{}", resources.stream()
|
||||
.map(Resource::toString)
|
||||
.collect(Collectors.joining("\n\t")));
|
||||
}
|
||||
throw new OpticalIntentCompilationException("Unable to allocate resources: " + resources);
|
||||
}
|
||||
}
|
||||
@ -219,7 +265,7 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
return findFirstLambda(lambdas, slotCount());
|
||||
}
|
||||
|
||||
private List<Resource> convertToResources(List<Link> links, List<OchSignal> lambda) {
|
||||
private List<Resource> convertToResources(List<Link> links, Collection<OchSignal> lambda) {
|
||||
return links.stream()
|
||||
.flatMap(x -> Stream.of(
|
||||
Resources.discrete(x.src().deviceId(), x.src().port()).resource(),
|
||||
@ -299,7 +345,7 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
* @param intent optical connectivity intent
|
||||
* @return set of paths in WDM topology
|
||||
*/
|
||||
private Set<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
|
||||
private Stream<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
|
||||
// Route in WDM topology
|
||||
Topology topology = topologyService.currentTopology();
|
||||
LinkWeight weight = new LinkWeight() {
|
||||
@ -335,9 +381,21 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
|
||||
|
||||
ConnectPoint start = intent.getSrc();
|
||||
ConnectPoint end = intent.getDst();
|
||||
Set<Path> paths = topologyService.getPaths(topology, start.deviceId(),
|
||||
end.deviceId(), weight);
|
||||
|
||||
Stream<Path> paths = topologyService.getKShortestPaths(topology,
|
||||
start.deviceId(),
|
||||
end.deviceId(),
|
||||
AdapterLinkWeigher.adapt(weight));
|
||||
if (log.isDebugEnabled()) {
|
||||
return paths
|
||||
.map(path -> {
|
||||
// no-op map stage to add debug logging
|
||||
log.debug("Candidate path: {}",
|
||||
path.links().stream()
|
||||
.map(lk -> lk.src() + "-" + lk.dst())
|
||||
.collect(Collectors.toList()));
|
||||
return path;
|
||||
});
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user