diff options
Diffstat (limited to 'framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java')
-rw-r--r-- | framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java new file mode 100644 index 00000000..58b446cf --- /dev/null +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java @@ -0,0 +1,286 @@ +/* + * Copyright 2014-2015 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.store.trivial; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.Bandwidth; +import org.onlab.util.PositionalParameterStringFormatter; +import org.onosproject.net.AnnotationKeys; +import org.onosproject.net.Annotations; +import org.onosproject.net.Link; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.link.BandwidthResource; +import org.onosproject.net.resource.link.BandwidthResourceAllocation; +import org.onosproject.net.resource.link.LambdaResource; +import org.onosproject.net.resource.link.LambdaResourceAllocation; +import org.onosproject.net.resource.link.LinkResourceAllocations; +import org.onosproject.net.resource.link.LinkResourceEvent; +import org.onosproject.net.resource.link.LinkResourceStore; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceAllocationException; +import org.onosproject.net.resource.ResourceType; +import org.slf4j.Logger; + +import com.google.common.collect.ImmutableList; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Manages link resources using trivial in-memory structures implementation. + */ +@Component(immediate = true) +@Service +public class SimpleLinkResourceStore implements LinkResourceStore { + private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000)); + private final Logger log = getLogger(getClass()); + + private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap; + private Map<Link, Set<LinkResourceAllocations>> allocatedResources; + private Map<Link, Set<ResourceAllocation>> freeResources; + + @Activate + public void activate() { + linkResourceAllocationsMap = new HashMap<>(); + allocatedResources = new HashMap<>(); + freeResources = new HashMap<>(); + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } + + /** + * Returns free resources for a given link obtaining from topology + * information. + * + * @param link the target link + * @return free resources + */ + private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) { + Annotations annotations = link.annotations(); + Set<ResourceAllocation> allocations = new HashSet<>(); + + try { + int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES)); + for (int i = 1; i <= waves; i++) { + allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i))); + } + } catch (NumberFormatException e) { + log.debug("No optical.wave annotation on link %s", link); + } + + BandwidthResource bandwidth = DEFAULT_BANDWIDTH; + try { + bandwidth = new BandwidthResource( + Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH))))); + } catch (NumberFormatException e) { + log.debug("No bandwidth annotation on link %s", link); + } + allocations.add( + new BandwidthResourceAllocation(bandwidth)); + return allocations; + } + + /** + * Finds and returns {@link BandwidthResourceAllocation} object from a given + * set. + * + * @param freeRes a set of ResourceAllocation object. + * @return {@link BandwidthResourceAllocation} object if found, otherwise + * {@link BandwidthResourceAllocation} object with 0 bandwidth + * + */ + private synchronized BandwidthResourceAllocation getBandwidth( + Set<ResourceAllocation> freeRes) { + for (ResourceAllocation res : freeRes) { + if (res.type() == ResourceType.BANDWIDTH) { + return (BandwidthResourceAllocation) res; + } + } + return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0))); + } + + /** + * Subtracts given resources from free resources for given link. + * + * @param link the target link + * @param allocations the resources to be subtracted + */ + private synchronized void subtractFreeResources(Link link, + LinkResourceAllocations allocations) { + // TODO Use lock or version for updating freeResources. + checkNotNull(link); + Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link)); + Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link); + for (ResourceAllocation res : subRes) { + switch (res.type()) { + case BANDWIDTH: + BandwidthResourceAllocation ba = getBandwidth(freeRes); + double requestedBandwidth = + ((BandwidthResourceAllocation) res).bandwidth().toDouble(); + double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth; + if (newBandwidth < 0.0) { + throw new ResourceAllocationException( + PositionalParameterStringFormatter.format( + "Unable to allocate bandwidth for link {} " + + "requested amount is {} current allocation is {}", + link, + requestedBandwidth, + ba)); + } + freeRes.remove(ba); + freeRes.add(new BandwidthResourceAllocation( + new BandwidthResource(Bandwidth.bps(newBandwidth)))); + break; + case LAMBDA: + final boolean lambdaAvailable = freeRes.remove(res); + if (!lambdaAvailable) { + int requestedLambda = + ((LambdaResourceAllocation) res).lambda().toInt(); + throw new ResourceAllocationException( + PositionalParameterStringFormatter.format( + "Unable to allocate lambda for link {} lambda is {}", + link, + requestedLambda)); + } + break; + default: + break; + } + } + freeResources.put(link, freeRes); + + } + + /** + * Adds given resources to free resources for given link. + * + * @param link the target link + * @param allocations the resources to be added + */ + private synchronized void addFreeResources(Link link, + LinkResourceAllocations allocations) { + // TODO Use lock or version for updating freeResources. + Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link)); + Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link); + for (ResourceAllocation res : addRes) { + switch (res.type()) { + case BANDWIDTH: + BandwidthResourceAllocation ba = getBandwidth(freeRes); + double requestedBandwidth = + ((BandwidthResourceAllocation) res).bandwidth().toDouble(); + double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth; + freeRes.remove(ba); + freeRes.add(new BandwidthResourceAllocation( + new BandwidthResource(Bandwidth.bps(newBandwidth)))); + break; + case LAMBDA: + checkState(freeRes.add(res)); + break; + default: + break; + } + } + freeResources.put(link, freeRes); + } + + @Override + public synchronized Set<ResourceAllocation> getFreeResources(Link link) { + checkNotNull(link); + Set<ResourceAllocation> freeRes = freeResources.get(link); + if (freeRes == null) { + freeRes = readOriginalFreeResources(link); + } + + return freeRes; + } + + @Override + public synchronized void allocateResources(LinkResourceAllocations allocations) { + checkNotNull(allocations); + linkResourceAllocationsMap.put(allocations.intentId(), allocations); + for (Link link : allocations.links()) { + subtractFreeResources(link, allocations); + Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link); + if (linkAllocs == null) { + linkAllocs = new HashSet<>(); + } + linkAllocs.add(allocations); + allocatedResources.put(link, linkAllocs); + } + } + + @Override + public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) { + checkNotNull(allocations); + linkResourceAllocationsMap.remove(allocations.intentId()); + for (Link link : allocations.links()) { + addFreeResources(link, allocations); + Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link); + if (linkAllocs == null) { + log.error("Missing resource allocation."); + } else { + linkAllocs.remove(allocations); + } + allocatedResources.put(link, linkAllocs); + } + + final List<LinkResourceAllocations> releasedResources = + ImmutableList.of(allocations); + + return new LinkResourceEvent( + LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE, + releasedResources); + } + + @Override + public synchronized LinkResourceAllocations getAllocations(IntentId intentId) { + checkNotNull(intentId); + return linkResourceAllocationsMap.get(intentId); + } + + @Override + public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) { + checkNotNull(link); + Set<LinkResourceAllocations> result = allocatedResources.get(link); + if (result == null) { + result = Collections.emptySet(); + } + return Collections.unmodifiableSet(result); + } + + @Override + public synchronized Iterable<LinkResourceAllocations> getAllocations() { + return Collections.unmodifiableCollection(linkResourceAllocationsMap.values()); + } + + +} |