2 * Copyright 2014-2015 Open Networking Laboratory
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.onosproject.store.trivial;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
25 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component;
27 import org.apache.felix.scr.annotations.Deactivate;
28 import org.apache.felix.scr.annotations.Service;
29 import org.onlab.util.Bandwidth;
30 import org.onlab.util.PositionalParameterStringFormatter;
31 import org.onosproject.net.AnnotationKeys;
32 import org.onosproject.net.Annotations;
33 import org.onosproject.net.Link;
34 import org.onosproject.net.intent.IntentId;
35 import org.onosproject.net.resource.link.BandwidthResource;
36 import org.onosproject.net.resource.link.BandwidthResourceAllocation;
37 import org.onosproject.net.resource.link.LambdaResource;
38 import org.onosproject.net.resource.link.LambdaResourceAllocation;
39 import org.onosproject.net.resource.link.LinkResourceAllocations;
40 import org.onosproject.net.resource.link.LinkResourceEvent;
41 import org.onosproject.net.resource.link.LinkResourceStore;
42 import org.onosproject.net.resource.ResourceAllocation;
43 import org.onosproject.net.resource.ResourceAllocationException;
44 import org.onosproject.net.resource.ResourceType;
45 import org.slf4j.Logger;
47 import com.google.common.collect.ImmutableList;
49 import static com.google.common.base.Preconditions.checkNotNull;
50 import static com.google.common.base.Preconditions.checkState;
51 import static org.slf4j.LoggerFactory.getLogger;
54 * Manages link resources using trivial in-memory structures implementation.
56 @Component(immediate = true)
58 public class SimpleLinkResourceStore implements LinkResourceStore {
59 private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000));
60 private final Logger log = getLogger(getClass());
62 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
63 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
64 private Map<Link, Set<ResourceAllocation>> freeResources;
67 public void activate() {
68 linkResourceAllocationsMap = new HashMap<>();
69 allocatedResources = new HashMap<>();
70 freeResources = new HashMap<>();
76 public void deactivate() {
81 * Returns free resources for a given link obtaining from topology
84 * @param link the target link
85 * @return free resources
87 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
88 Annotations annotations = link.annotations();
89 Set<ResourceAllocation> allocations = new HashSet<>();
92 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
93 for (int i = 1; i <= waves; i++) {
94 allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
96 } catch (NumberFormatException e) {
97 log.debug("No optical.wave annotation on link %s", link);
100 BandwidthResource bandwidth = DEFAULT_BANDWIDTH;
102 bandwidth = new BandwidthResource(
103 Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH)))));
104 } catch (NumberFormatException e) {
105 log.debug("No bandwidth annotation on link %s", link);
108 new BandwidthResourceAllocation(bandwidth));
113 * Finds and returns {@link BandwidthResourceAllocation} object from a given
116 * @param freeRes a set of ResourceAllocation object.
117 * @return {@link BandwidthResourceAllocation} object if found, otherwise
118 * {@link BandwidthResourceAllocation} object with 0 bandwidth
121 private synchronized BandwidthResourceAllocation getBandwidth(
122 Set<ResourceAllocation> freeRes) {
123 for (ResourceAllocation res : freeRes) {
124 if (res.type() == ResourceType.BANDWIDTH) {
125 return (BandwidthResourceAllocation) res;
128 return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0)));
132 * Subtracts given resources from free resources for given link.
134 * @param link the target link
135 * @param allocations the resources to be subtracted
137 private synchronized void subtractFreeResources(Link link,
138 LinkResourceAllocations allocations) {
139 // TODO Use lock or version for updating freeResources.
141 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
142 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
143 for (ResourceAllocation res : subRes) {
144 switch (res.type()) {
146 BandwidthResourceAllocation ba = getBandwidth(freeRes);
147 double requestedBandwidth =
148 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
149 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
150 if (newBandwidth < 0.0) {
151 throw new ResourceAllocationException(
152 PositionalParameterStringFormatter.format(
153 "Unable to allocate bandwidth for link {} "
154 + "requested amount is {} current allocation is {}",
160 freeRes.add(new BandwidthResourceAllocation(
161 new BandwidthResource(Bandwidth.bps(newBandwidth))));
164 final boolean lambdaAvailable = freeRes.remove(res);
165 if (!lambdaAvailable) {
166 int requestedLambda =
167 ((LambdaResourceAllocation) res).lambda().toInt();
168 throw new ResourceAllocationException(
169 PositionalParameterStringFormatter.format(
170 "Unable to allocate lambda for link {} lambda is {}",
179 freeResources.put(link, freeRes);
184 * Adds given resources to free resources for given link.
186 * @param link the target link
187 * @param allocations the resources to be added
189 private synchronized void addFreeResources(Link link,
190 LinkResourceAllocations allocations) {
191 // TODO Use lock or version for updating freeResources.
192 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
193 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
194 for (ResourceAllocation res : addRes) {
195 switch (res.type()) {
197 BandwidthResourceAllocation ba = getBandwidth(freeRes);
198 double requestedBandwidth =
199 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
200 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
202 freeRes.add(new BandwidthResourceAllocation(
203 new BandwidthResource(Bandwidth.bps(newBandwidth))));
206 checkState(freeRes.add(res));
212 freeResources.put(link, freeRes);
216 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
218 Set<ResourceAllocation> freeRes = freeResources.get(link);
219 if (freeRes == null) {
220 freeRes = readOriginalFreeResources(link);
227 public synchronized void allocateResources(LinkResourceAllocations allocations) {
228 checkNotNull(allocations);
229 linkResourceAllocationsMap.put(allocations.intentId(), allocations);
230 for (Link link : allocations.links()) {
231 subtractFreeResources(link, allocations);
232 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
233 if (linkAllocs == null) {
234 linkAllocs = new HashSet<>();
236 linkAllocs.add(allocations);
237 allocatedResources.put(link, linkAllocs);
242 public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
243 checkNotNull(allocations);
244 linkResourceAllocationsMap.remove(allocations.intentId());
245 for (Link link : allocations.links()) {
246 addFreeResources(link, allocations);
247 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
248 if (linkAllocs == null) {
249 log.error("Missing resource allocation.");
251 linkAllocs.remove(allocations);
253 allocatedResources.put(link, linkAllocs);
256 final List<LinkResourceAllocations> releasedResources =
257 ImmutableList.of(allocations);
259 return new LinkResourceEvent(
260 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
265 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
266 checkNotNull(intentId);
267 return linkResourceAllocationsMap.get(intentId);
271 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
273 Set<LinkResourceAllocations> result = allocatedResources.get(link);
274 if (result == null) {
275 result = Collections.emptySet();
277 return Collections.unmodifiableSet(result);
281 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
282 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());