blob: 0d9d09ca9ffce3488d66057483dde18ffc66b8ca [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;
Ray Milkey9a39eca2015-01-05 09:41:01 -080029import org.onlab.util.PositionalParameterStringFormatter;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.AnnotationKeys;
31import org.onosproject.net.Annotations;
32import org.onosproject.net.Link;
33import org.onosproject.net.intent.IntentId;
34import org.onosproject.net.resource.Bandwidth;
35import org.onosproject.net.resource.BandwidthResourceAllocation;
36import org.onosproject.net.resource.Lambda;
37import org.onosproject.net.resource.LambdaResourceAllocation;
38import org.onosproject.net.resource.LinkResourceAllocations;
39import org.onosproject.net.resource.LinkResourceEvent;
40import org.onosproject.net.resource.LinkResourceStore;
41import org.onosproject.net.resource.ResourceAllocation;
Ray Milkey9a39eca2015-01-05 09:41:01 -080042import org.onosproject.net.resource.ResourceAllocationException;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.resource.ResourceType;
Toshio Koide106d4492014-10-28 11:22:02 -070044import org.slf4j.Logger;
45
Ray Milkeye97ede92014-11-20 10:43:12 -080046import com.google.common.collect.ImmutableList;
47
48import static com.google.common.base.Preconditions.checkNotNull;
49import static com.google.common.base.Preconditions.checkState;
50import static org.slf4j.LoggerFactory.getLogger;
51
Toshio Koide106d4492014-10-28 11:22:02 -070052/**
53 * Manages link resources using trivial in-memory structures implementation.
54 */
55@Component(immediate = true)
56@Service
57public class SimpleLinkResourceStore implements LinkResourceStore {
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -080058 private static final Bandwidth DEFAULT_BANDWIDTH = Bandwidth.mbps(1_000);
Toshio Koide106d4492014-10-28 11:22:02 -070059 private final Logger log = getLogger(getClass());
Ray Milkeye97ede92014-11-20 10:43:12 -080060
Toshio Koide106d4492014-10-28 11:22:02 -070061 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
62 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
63 private Map<Link, Set<ResourceAllocation>> freeResources;
64
65 @Activate
66 public void activate() {
67 linkResourceAllocationsMap = new HashMap<>();
68 allocatedResources = new HashMap<>();
69 freeResources = new HashMap<>();
70
71 log.info("Started");
72 }
73
74 @Deactivate
75 public void deactivate() {
76 log.info("Stopped");
77 }
78
Toshio Koide69e52572014-10-30 11:14:09 -070079 /**
80 * Returns free resources for a given link obtaining from topology
81 * information.
82 *
83 * @param link the target link
84 * @return free resources
85 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080086 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080087 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070088 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080089
90 try {
91 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
92 for (int i = 1; i <= waves; i++) {
93 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
94 }
95 } catch (NumberFormatException e) {
96 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -070097 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -080098
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -080099 Bandwidth bandwidth = DEFAULT_BANDWIDTH;
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800100 try {
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800101 bandwidth = Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH))));
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800102 } catch (NumberFormatException e) {
103 log.debug("No bandwidth annotation on link %s", link);
104 }
Ray Milkey73257012014-11-20 12:02:27 -0800105 allocations.add(
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800106 new BandwidthResourceAllocation(bandwidth));
Toshio Koide106d4492014-10-28 11:22:02 -0700107 return allocations;
108 }
109
Toshio Koide69e52572014-10-30 11:14:09 -0700110 /**
111 * Finds and returns {@link BandwidthResourceAllocation} object from a given
112 * set.
113 *
114 * @param freeRes a set of ResourceAllocation object.
115 * @return {@link BandwidthResourceAllocation} object if found, otherwise
116 * {@link BandwidthResourceAllocation} object with 0 bandwidth
117 *
118 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800119 private synchronized BandwidthResourceAllocation getBandwidth(
120 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700121 for (ResourceAllocation res : freeRes) {
122 if (res.type() == ResourceType.BANDWIDTH) {
123 return (BandwidthResourceAllocation) res;
124 }
125 }
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800126 return new BandwidthResourceAllocation(Bandwidth.bps(0));
Toshio Koide106d4492014-10-28 11:22:02 -0700127 }
128
Toshio Koide69e52572014-10-30 11:14:09 -0700129 /**
130 * Subtracts given resources from free resources for given link.
131 *
132 * @param link the target link
133 * @param allocations the resources to be subtracted
134 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800135 private synchronized void subtractFreeResources(Link link,
136 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700137 // TODO Use lock or version for updating freeResources.
138 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700139 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700140 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
141 for (ResourceAllocation res : subRes) {
142 switch (res.type()) {
143 case BANDWIDTH:
144 BandwidthResourceAllocation ba = getBandwidth(freeRes);
145 double requestedBandwidth =
146 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
147 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
Ray Milkey9a39eca2015-01-05 09:41:01 -0800148 if (newBandwidth < 0.0) {
149 throw new ResourceAllocationException(
150 PositionalParameterStringFormatter.format(
151 "Unable to allocate bandwidth for link {} "
152 + "requested amount is {} current allocation is {}",
153 link,
154 requestedBandwidth,
155 ba));
156 }
Toshio Koide106d4492014-10-28 11:22:02 -0700157 freeRes.remove(ba);
158 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800159 Bandwidth.bps(newBandwidth)));
Toshio Koide106d4492014-10-28 11:22:02 -0700160 break;
161 case LAMBDA:
Ray Milkey9a39eca2015-01-05 09:41:01 -0800162 final boolean lambdaAvailable = freeRes.remove(res);
163 if (!lambdaAvailable) {
164 int requestedLambda =
165 ((LambdaResourceAllocation) res).lambda().toInt();
166 throw new ResourceAllocationException(
167 PositionalParameterStringFormatter.format(
168 "Unable to allocate lambda for link {} lambda is {}",
169 link,
170 requestedLambda));
171 }
Toshio Koide106d4492014-10-28 11:22:02 -0700172 break;
173 default:
174 break;
175 }
176 }
177 freeResources.put(link, freeRes);
178
179 }
180
Toshio Koide69e52572014-10-30 11:14:09 -0700181 /**
182 * Adds given resources to free resources for given link.
183 *
184 * @param link the target link
185 * @param allocations the resources to be added
186 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800187 private synchronized void addFreeResources(Link link,
188 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700189 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700190 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700191 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
192 for (ResourceAllocation res : addRes) {
193 switch (res.type()) {
194 case BANDWIDTH:
195 BandwidthResourceAllocation ba = getBandwidth(freeRes);
196 double requestedBandwidth =
197 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
198 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
199 freeRes.remove(ba);
200 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800201 Bandwidth.bps(newBandwidth)));
Toshio Koide106d4492014-10-28 11:22:02 -0700202 break;
203 case LAMBDA:
204 checkState(freeRes.add(res));
205 break;
206 default:
207 break;
208 }
209 }
210 freeResources.put(link, freeRes);
211 }
212
213 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800214 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700215 checkNotNull(link);
216 Set<ResourceAllocation> freeRes = freeResources.get(link);
217 if (freeRes == null) {
218 freeRes = readOriginalFreeResources(link);
219 }
220
221 return freeRes;
222 }
223
224 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800225 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700226 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700227 linkResourceAllocationsMap.put(allocations.intentId(), allocations);
Toshio Koide106d4492014-10-28 11:22:02 -0700228 for (Link link : allocations.links()) {
229 subtractFreeResources(link, allocations);
230 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
231 if (linkAllocs == null) {
232 linkAllocs = new HashSet<>();
233 }
234 linkAllocs.add(allocations);
235 allocatedResources.put(link, linkAllocs);
236 }
237 }
238
239 @Override
Ray Milkeye97ede92014-11-20 10:43:12 -0800240 public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700241 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700242 linkResourceAllocationsMap.remove(allocations.intentId());
Toshio Koide106d4492014-10-28 11:22:02 -0700243 for (Link link : allocations.links()) {
244 addFreeResources(link, allocations);
245 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
246 if (linkAllocs == null) {
247 log.error("Missing resource allocation.");
248 } else {
249 linkAllocs.remove(allocations);
250 }
251 allocatedResources.put(link, linkAllocs);
252 }
Ray Milkeye97ede92014-11-20 10:43:12 -0800253
254 final List<LinkResourceAllocations> releasedResources =
255 ImmutableList.of(allocations);
256
257 return new LinkResourceEvent(
258 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
259 releasedResources);
Toshio Koide106d4492014-10-28 11:22:02 -0700260 }
261
262 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800263 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700264 checkNotNull(intentId);
265 return linkResourceAllocationsMap.get(intentId);
266 }
267
268 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800269 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700270 checkNotNull(link);
271 Set<LinkResourceAllocations> result = allocatedResources.get(link);
272 if (result == null) {
273 result = Collections.emptySet();
274 }
275 return Collections.unmodifiableSet(result);
276 }
277
278 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800279 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700280 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
281 }
282
Ray Milkeye97ede92014-11-20 10:43:12 -0800283
Toshio Koide106d4492014-10-28 11:22:02 -0700284}