use of org.onosproject.net.resource.Resource in project onos by opennetworkinglab.
the class OpticalOduIntentCompiler method compile.
@Override
public List<Intent> compile(OpticalOduIntent intent, List<Intent> installable) {
// Check if ports are OduClt ports
ConnectPoint src = intent.getSrc();
ConnectPoint dst = intent.getDst();
Port srcPort = deviceService.getPort(src.deviceId(), src.port());
Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
checkArgument(srcPort instanceof OduCltPort);
checkArgument(dstPort instanceof OduCltPort);
log.debug("Compiling optical ODU intent between {} and {}", src, dst);
// Release of intent resources here is only a temporary solution for handling the
// case of recompiling due to intent restoration (when intent state is FAILED).
// TODO: try to release intent resources in IntentManager.
resourceService.release(intent.key());
// Check OduClt ports availability
Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource();
Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource();
// If ports are not available, compilation fails
if (!Stream.of(srcPortResource, dstPortResource).allMatch(resourceService::isAvailable)) {
throw new OpticalIntentCompilationException("Ports for the intent are not available. Intent: " + intent);
}
List<Resource> intentResources = new ArrayList<>();
intentResources.add(srcPortResource);
intentResources.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);
}
// Use first path that can be successfully reserved
for (Path path : paths) {
// Find available Tributary Slots on both directions of path
Map<LinkKey, Set<TributarySlot>> slotsMap = findAvailableTributarySlots(intent, path);
if (slotsMap.isEmpty()) {
continue;
}
List<Resource> tributarySlotResources = convertToResources(slotsMap);
if (!tributarySlotResources.stream().allMatch(resourceService::isAvailable)) {
continue;
}
intentResources.addAll(tributarySlotResources);
allocateResources(intent, intentResources);
List<FlowRule> rules = new LinkedList<>();
// Create rules for forward and reverse path
rules = createRules(intent, intent.getSrc(), intent.getDst(), path, slotsMap, false);
if (intent.isBidirectional()) {
rules.addAll(createRules(intent, intent.getDst(), intent.getSrc(), path, slotsMap, true));
}
return Collections.singletonList(new FlowRuleIntent(appId, intent.key(), rules, ImmutableSet.copyOf(path.links()), PathIntent.ProtectionType.PRIMARY, intent.resourceGroup()));
}
throw new OpticalIntentCompilationException("Unable to find suitable lightpath for intent " + intent);
}
use of org.onosproject.net.resource.Resource in project onos by opennetworkinglab.
the class OpticalCircuitIntentCompiler method compile.
private List<Intent> compile(OpticalCircuitIntent intent, ConnectPoint src, ConnectPoint dst, Optional<OpticalConnectivityIntent> existingConnectivity, List<Resource> resources, boolean supportsMultiplexing) {
OpticalConnectivityIntent connectivityIntent;
List<Resource> required;
if (existingConnectivity.isPresent()) {
connectivityIntent = existingConnectivity.get();
required = resources;
} else {
// Find OCh ports with available resources
Pair<OchPort, OchPort> ochPorts = findPorts(intent.getSrc(), intent.getDst(), intent.getSignalType());
if (ochPorts == null) {
throw new OpticalIntentCompilationException("Unable to find suitable OCH ports for intent " + intent);
}
ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number());
ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number());
// Create optical connectivity intent
// In this case the channel and path optionally specified in this circuit intent
// are used to create the connectivity intent
connectivityIntent = OpticalConnectivityIntent.builder().appId(appId).src(srcCP).dst(dstCP).priority(OPTICAL_CONNECTIVITY_INTENT_PRIORITY).signalType(ochPorts.getLeft().signalType()).bidirectional(intent.isBidirectional()).ochSignal(intent.ochSignal()).suggestedPath(intent.suggestedPath()).resourceGroup(intent.resourceGroup()).build();
if (!supportsMultiplexing) {
required = resources;
} else {
List<Resource> slots = availableSlotResources(srcCP, dstCP, intent.getSignalType());
if (slots.isEmpty()) {
throw new OpticalIntentCompilationException("Unable to find Tributary Slots for intent " + intent);
}
required = ImmutableList.<Resource>builder().addAll(resources).addAll(slots).build();
}
}
if (resourceService.allocate(intent.key(), required).isEmpty()) {
throw new OpticalIntentCompilationException("Unable to allocate resources for intent " + intent + ": resources=" + required);
}
intentService.submit(connectivityIntent);
// Save circuit to connectivity intent mapping
intentSetMultimap.allocateMapping(connectivityIntent.id(), intent.id());
FlowRuleIntent circuitIntent = createFlowRule(intent, connectivityIntent, required.stream().flatMap(x -> Tools.stream(x.valueAs(TributarySlot.class))).collect(Collectors.toSet()));
return ImmutableList.of(circuitIntent);
}
use of org.onosproject.net.resource.Resource in project onos by opennetworkinglab.
the class ResourcesCommand method printResource.
private void printResource(Resource resource, int level) {
// workaround to preserve the original behavior of ResourceService#getRegisteredResources
Set<Resource> children;
if (resource instanceof DiscreteResource) {
children = resourceService.getRegisteredResources(((DiscreteResource) resource).id());
} else {
children = Collections.emptySet();
}
if (resource.equals(Resource.ROOT)) {
print("ROOT");
} else {
String resourceName = resource.simpleTypeName();
if (resource instanceof ContinuousResource) {
if (availablesOnly) {
// Get the total resource
double total = ((ContinuousResource) resource).value();
// Get allocated resource
double allocated = resourceService.getResourceAllocations(resource.id()).stream().mapToDouble(rA -> ((ContinuousResource) rA.resource()).value()).sum();
// Difference
double difference = total - allocated;
print("%s%s: %f", Strings.repeat(" ", level), resourceName, difference);
} else {
print("%s%s: %f", Strings.repeat(" ", level), resourceName, ((ContinuousResource) resource).value());
}
// Continuous resource is terminal node, stop here
return;
} else {
String availability = "";
if (availablesOnly && !children.isEmpty()) {
// intermediate nodes cannot be omitted, print availability
if (resourceService.isAvailable(resource)) {
availability = " ✔";
} else {
availability = " ✘";
}
}
String toString = String.valueOf(resource.valueAs(Object.class).orElse(""));
if (toString.startsWith(resourceName)) {
print("%s%s%s", Strings.repeat(" ", level), toString, availability);
} else {
print("%s%s: %s%s", Strings.repeat(" ", level), resourceName, toString, availability);
}
}
}
// Classify children into aggregatable terminal resources and everything else
Set<Class<?>> aggregatableTypes = ImmutableSet.<Class<?>>builder().add(VlanId.class).add(MplsLabel.class).build();
// (last() resource name) -> { Resource }
Multimap<String, Resource> aggregatables = ArrayListMultimap.create();
List<Resource> nonAggregatable = new ArrayList<>();
for (Resource r : children) {
if (!isPrintTarget(r)) {
// A
continue;
}
if (r instanceof DiscreteResource) {
if (resourceService.getRegisteredResources(((DiscreteResource) r).id()).isEmpty()) {
// resource which has children should be printed
continue;
}
}
if (r instanceof ContinuousResource) {
// non-aggregatable terminal node
nonAggregatable.add(r);
} else if (Iterables.any(aggregatableTypes, r::isTypeOf)) {
// aggregatable & terminal node
String simpleName = r.simpleTypeName();
aggregatables.put(simpleName, r);
} else {
nonAggregatable.add(r);
}
}
// print aggregated (terminal)
aggregatables.asMap().entrySet().forEach(e -> {
// for each type...
String resourceName = e.getKey();
RangeSet<Long> rangeSet = TreeRangeSet.create();
// aggregate into RangeSet
e.getValue().stream().map(res -> {
if (res.isTypeOf(VlanId.class)) {
return (long) res.valueAs(VlanId.class).get().toShort();
} else if (res.isTypeOf(MplsLabel.class)) {
return (long) res.valueAs(MplsLabel.class).get().toInt();
} else if (res.isTypeOf(TributarySlot.class)) {
return res.valueAs(TributarySlot.class).get().index();
}
// TODO support Lambda (OchSignal types)
return 0L;
}).map(Range::singleton).map(range -> range.canonical(DiscreteDomain.longs())).forEach(rangeSet::add);
print("%s%s: %s", Strings.repeat(" ", level + 1), resourceName, rangeSet);
});
// print non-aggregatables (recurse)
if (sort) {
nonAggregatable.stream().sorted((o1, o2) -> String.valueOf(o1.id()).compareTo(String.valueOf(o2.id()))).forEach(r -> printResource(r, level + 1));
} else {
nonAggregatable.forEach(r -> printResource(r, level + 1));
}
}
use of org.onosproject.net.resource.Resource in project onos by opennetworkinglab.
the class ConnectivityIntentCompiler method allocateBandwidth.
/**
* Allocates the bandwidth specified as intent constraint on each link
* composing the intent, if a bandwidth constraint is specified.
*
* @param intent the intent requesting bandwidth allocation
* @param connectPoints the connect points composing the intent path computed
*/
protected void allocateBandwidth(ConnectivityIntent intent, List<ConnectPoint> connectPoints) {
// Retrieve bandwidth constraint if exists
List<Constraint> constraints = intent.constraints();
if (constraints == null) {
return;
}
Optional<Constraint> constraint = constraints.stream().filter(c -> c instanceof BandwidthConstraint).findAny();
// If there is no bandwidth constraint continue
if (!constraint.isPresent()) {
return;
}
BandwidthConstraint bwConstraint = (BandwidthConstraint) constraint.get();
double bw = bwConstraint.bandwidth().bps();
// If a resource group is set on the intent, the resource consumer is
// set equal to it. Otherwise it's set to the intent key
ResourceConsumer newResourceConsumer = intent.resourceGroup() != null ? intent.resourceGroup() : intent.key();
// Get the list of current resource allocations
Collection<ResourceAllocation> resourceAllocations = resourceService.getResourceAllocations(newResourceConsumer);
// Get the list of resources already allocated from resource allocations
List<Resource> resourcesAllocated = resourcesFromAllocations(resourceAllocations);
// Get the list of resource ids for resources already allocated
List<ResourceId> idsResourcesAllocated = resourceIds(resourcesAllocated);
// Create the list of incoming resources requested. Exclude resources
// already allocated.
List<Resource> incomingResources = resources(connectPoints, bw).stream().filter(r -> !resourcesAllocated.contains(r)).collect(Collectors.toList());
if (incomingResources.isEmpty()) {
return;
}
// Create the list of resources to be added, meaning their key is not
// present in the resources already allocated
List<Resource> resourcesToAdd = incomingResources.stream().filter(r -> !idsResourcesAllocated.contains(r.id())).collect(Collectors.toList());
// Resources to updated are all the new valid resources except the
// resources to be added
List<Resource> resourcesToUpdate = Lists.newArrayList(incomingResources);
resourcesToUpdate.removeAll(resourcesToAdd);
// If there are no resources to update skip update procedures
if (!resourcesToUpdate.isEmpty()) {
// Remove old resources that need to be updated
// TODO: use transaction updates when available in the resource service
List<ResourceAllocation> resourceAllocationsToUpdate = resourceAllocations.stream().filter(rA -> resourceIds(resourcesToUpdate).contains(rA.resource().id())).collect(Collectors.toList());
log.debug("Releasing bandwidth for intent {}: {} bps", newResourceConsumer, resourcesToUpdate);
resourceService.release(resourceAllocationsToUpdate);
// Update resourcesToAdd with the list of both the new resources and
// the resources to update
resourcesToAdd.addAll(resourcesToUpdate);
}
// remove them
if (intent.resourceGroup() != null) {
// Get the list of current resource allocations made by intent key
Collection<ResourceAllocation> resourceAllocationsByKey = resourceService.getResourceAllocations(intent.key());
resourceService.release(Lists.newArrayList(resourceAllocationsByKey));
}
// Allocate resources
log.debug("Allocating bandwidth for intent {}: {} bps", newResourceConsumer, resourcesToAdd);
List<ResourceAllocation> allocations = resourceService.allocate(newResourceConsumer, resourcesToAdd);
if (allocations.isEmpty()) {
log.debug("No resources allocated for intent {}", newResourceConsumer);
}
log.debug("Done allocating bandwidth for intent {}", newResourceConsumer);
}
use of org.onosproject.net.resource.Resource in project onos by opennetworkinglab.
the class ResourceDeviceListener method unregisterPortResource.
private void unregisterPortResource(Device device, Port port) {
DiscreteResource portResource = Resources.discrete(device.id(), port.number()).resource();
List<Resource> allResources = getDescendantResources(portResource);
adminService.unregister(Lists.transform(allResources, Resource::id));
}
Aggregations