/* * 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. * * @deprecated in Emu Release */ @Deprecated @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 linkResourceAllocationsMap; private Map> allocatedResources; private Map> 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 readOriginalFreeResources(Link link) { Annotations annotations = link.annotations(); Set 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 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 freeRes = new HashSet<>(getFreeResources(link)); Set 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 freeRes = new HashSet<>(getFreeResources(link)); Set 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 getFreeResources(Link link) { checkNotNull(link); Set 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 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 linkAllocs = allocatedResources.get(link); if (linkAllocs == null) { log.error("Missing resource allocation."); } else { linkAllocs.remove(allocations); } allocatedResources.put(link, linkAllocs); } final List 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 getAllocations(Link link) { checkNotNull(link); Set result = allocatedResources.get(link); if (result == null) { result = Collections.emptySet(); } return Collections.unmodifiableSet(result); } @Override public synchronized Iterable getAllocations() { return Collections.unmodifiableCollection(linkResourceAllocationsMap.values()); } }