blob: 77b918a08fc1e1c3a5e55c7f79b735b0acb15ce2 [file] [log] [blame]
Toshio Koide106d4492014-10-28 11:22:02 -07001/*
Ray Milkey9a39eca2015-01-05 09:41:01 -08002 * Copyright 2014-2015 Open Networking Laboratory
Toshio Koide106d4492014-10-28 11:22:02 -07003 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.store.trivial.impl;
Toshio Koide106d4492014-10-28 11:22:02 -070017
Toshio Koide106d4492014-10-28 11:22:02 -070018import java.util.Collections;
19import java.util.HashMap;
20import java.util.HashSet;
Ray Milkeye97ede92014-11-20 10:43:12 -080021import java.util.List;
Toshio Koide106d4492014-10-28 11:22:02 -070022import java.util.Map;
23import java.util.Set;
24
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Service;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070029import org.onlab.util.Bandwidth;
Ray Milkey9a39eca2015-01-05 09:41:01 -080030import org.onlab.util.PositionalParameterStringFormatter;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.AnnotationKeys;
32import org.onosproject.net.Annotations;
33import org.onosproject.net.Link;
34import org.onosproject.net.intent.IntentId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070035import org.onosproject.net.resource.link.BandwidthResource;
36import org.onosproject.net.resource.link.BandwidthResourceAllocation;
37import org.onosproject.net.resource.link.LambdaResource;
38import org.onosproject.net.resource.link.LambdaResourceAllocation;
39import org.onosproject.net.resource.link.LinkResourceAllocations;
40import org.onosproject.net.resource.link.LinkResourceEvent;
41import org.onosproject.net.resource.link.LinkResourceStore;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.resource.ResourceAllocation;
Ray Milkey9a39eca2015-01-05 09:41:01 -080043import org.onosproject.net.resource.ResourceAllocationException;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.resource.ResourceType;
Toshio Koide106d4492014-10-28 11:22:02 -070045import org.slf4j.Logger;
46
Ray Milkeye97ede92014-11-20 10:43:12 -080047import com.google.common.collect.ImmutableList;
48
49import static com.google.common.base.Preconditions.checkNotNull;
50import static com.google.common.base.Preconditions.checkState;
51import static org.slf4j.LoggerFactory.getLogger;
52
Toshio Koide106d4492014-10-28 11:22:02 -070053/**
54 * Manages link resources using trivial in-memory structures implementation.
55 */
56@Component(immediate = true)
57@Service
58public class SimpleLinkResourceStore implements LinkResourceStore {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070059 private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000));
Toshio Koide106d4492014-10-28 11:22:02 -070060 private final Logger log = getLogger(getClass());
Ray Milkeye97ede92014-11-20 10:43:12 -080061
Toshio Koide106d4492014-10-28 11:22:02 -070062 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
63 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
64 private Map<Link, Set<ResourceAllocation>> freeResources;
65
66 @Activate
67 public void activate() {
68 linkResourceAllocationsMap = new HashMap<>();
69 allocatedResources = new HashMap<>();
70 freeResources = new HashMap<>();
71
72 log.info("Started");
73 }
74
75 @Deactivate
76 public void deactivate() {
77 log.info("Stopped");
78 }
79
Toshio Koide69e52572014-10-30 11:14:09 -070080 /**
81 * Returns free resources for a given link obtaining from topology
82 * information.
83 *
84 * @param link the target link
85 * @return free resources
86 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080087 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080088 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070089 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080090
91 try {
92 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
93 for (int i = 1; i <= waves; i++) {
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -070094 allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
Toshio Koide8e5e91e2014-11-13 12:27:12 -080095 }
96 } catch (NumberFormatException e) {
97 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -070098 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -080099
Sho SHIMIZU63feca72015-05-07 10:44:25 -0700100 BandwidthResource bandwidth = DEFAULT_BANDWIDTH;
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800101 try {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700102 bandwidth = new BandwidthResource(
103 Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH)))));
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800104 } catch (NumberFormatException e) {
105 log.debug("No bandwidth annotation on link %s", link);
106 }
Ray Milkey73257012014-11-20 12:02:27 -0800107 allocations.add(
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800108 new BandwidthResourceAllocation(bandwidth));
Toshio Koide106d4492014-10-28 11:22:02 -0700109 return allocations;
110 }
111
Toshio Koide69e52572014-10-30 11:14:09 -0700112 /**
113 * Finds and returns {@link BandwidthResourceAllocation} object from a given
114 * set.
115 *
116 * @param freeRes a set of ResourceAllocation object.
117 * @return {@link BandwidthResourceAllocation} object if found, otherwise
118 * {@link BandwidthResourceAllocation} object with 0 bandwidth
119 *
120 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800121 private synchronized BandwidthResourceAllocation getBandwidth(
122 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700123 for (ResourceAllocation res : freeRes) {
124 if (res.type() == ResourceType.BANDWIDTH) {
125 return (BandwidthResourceAllocation) res;
126 }
127 }
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700128 return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0)));
Toshio Koide106d4492014-10-28 11:22:02 -0700129 }
130
Toshio Koide69e52572014-10-30 11:14:09 -0700131 /**
132 * Subtracts given resources from free resources for given link.
133 *
134 * @param link the target link
135 * @param allocations the resources to be subtracted
136 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800137 private synchronized void subtractFreeResources(Link link,
138 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700139 // TODO Use lock or version for updating freeResources.
140 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700141 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700142 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
143 for (ResourceAllocation res : subRes) {
144 switch (res.type()) {
145 case BANDWIDTH:
146 BandwidthResourceAllocation ba = getBandwidth(freeRes);
147 double requestedBandwidth =
148 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
149 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
Ray Milkey9a39eca2015-01-05 09:41:01 -0800150 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 {}",
155 link,
156 requestedBandwidth,
157 ba));
158 }
Toshio Koide106d4492014-10-28 11:22:02 -0700159 freeRes.remove(ba);
160 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700161 new BandwidthResource(Bandwidth.bps(newBandwidth))));
Toshio Koide106d4492014-10-28 11:22:02 -0700162 break;
163 case LAMBDA:
Ray Milkey9a39eca2015-01-05 09:41:01 -0800164 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 {}",
171 link,
172 requestedLambda));
173 }
Toshio Koide106d4492014-10-28 11:22:02 -0700174 break;
175 default:
176 break;
177 }
178 }
179 freeResources.put(link, freeRes);
180
181 }
182
Toshio Koide69e52572014-10-30 11:14:09 -0700183 /**
184 * Adds given resources to free resources for given link.
185 *
186 * @param link the target link
187 * @param allocations the resources to be added
188 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800189 private synchronized void addFreeResources(Link link,
190 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700191 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700192 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700193 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
194 for (ResourceAllocation res : addRes) {
195 switch (res.type()) {
196 case BANDWIDTH:
197 BandwidthResourceAllocation ba = getBandwidth(freeRes);
198 double requestedBandwidth =
199 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
200 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
201 freeRes.remove(ba);
202 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700203 new BandwidthResource(Bandwidth.bps(newBandwidth))));
Toshio Koide106d4492014-10-28 11:22:02 -0700204 break;
205 case LAMBDA:
206 checkState(freeRes.add(res));
207 break;
208 default:
209 break;
210 }
211 }
212 freeResources.put(link, freeRes);
213 }
214
215 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800216 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700217 checkNotNull(link);
218 Set<ResourceAllocation> freeRes = freeResources.get(link);
219 if (freeRes == null) {
220 freeRes = readOriginalFreeResources(link);
221 }
222
223 return freeRes;
224 }
225
226 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800227 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700228 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700229 linkResourceAllocationsMap.put(allocations.intentId(), allocations);
Toshio Koide106d4492014-10-28 11:22:02 -0700230 for (Link link : allocations.links()) {
231 subtractFreeResources(link, allocations);
232 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
233 if (linkAllocs == null) {
234 linkAllocs = new HashSet<>();
235 }
236 linkAllocs.add(allocations);
237 allocatedResources.put(link, linkAllocs);
238 }
239 }
240
241 @Override
Ray Milkeye97ede92014-11-20 10:43:12 -0800242 public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700243 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700244 linkResourceAllocationsMap.remove(allocations.intentId());
Toshio Koide106d4492014-10-28 11:22:02 -0700245 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.");
250 } else {
251 linkAllocs.remove(allocations);
252 }
253 allocatedResources.put(link, linkAllocs);
254 }
Ray Milkeye97ede92014-11-20 10:43:12 -0800255
256 final List<LinkResourceAllocations> releasedResources =
257 ImmutableList.of(allocations);
258
259 return new LinkResourceEvent(
260 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
261 releasedResources);
Toshio Koide106d4492014-10-28 11:22:02 -0700262 }
263
264 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800265 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700266 checkNotNull(intentId);
267 return linkResourceAllocationsMap.get(intentId);
268 }
269
270 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800271 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700272 checkNotNull(link);
273 Set<LinkResourceAllocations> result = allocatedResources.get(link);
274 if (result == null) {
275 result = Collections.emptySet();
276 }
277 return Collections.unmodifiableSet(result);
278 }
279
280 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800281 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700282 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
283 }
284
Ray Milkeye97ede92014-11-20 10:43:12 -0800285
Toshio Koide106d4492014-10-28 11:22:02 -0700286}