blob: 22df937b69b70f01f24f4283a4f4e8f0bf4e859d [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 */
Thomas Vachuskac97aa612015-06-23 16:00:18 -070016package org.onosproject.store.trivial;
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.
Sho SHIMIZU364cbac2015-10-29 15:47:35 -070055 *
56 * @deprecated in Emu Release
Toshio Koide106d4492014-10-28 11:22:02 -070057 */
Sho SHIMIZU364cbac2015-10-29 15:47:35 -070058@Deprecated
Toshio Koide106d4492014-10-28 11:22:02 -070059@Component(immediate = true)
60@Service
61public class SimpleLinkResourceStore implements LinkResourceStore {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070062 private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000));
Toshio Koide106d4492014-10-28 11:22:02 -070063 private final Logger log = getLogger(getClass());
Ray Milkeye97ede92014-11-20 10:43:12 -080064
Toshio Koide106d4492014-10-28 11:22:02 -070065 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
66 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
67 private Map<Link, Set<ResourceAllocation>> freeResources;
68
69 @Activate
70 public void activate() {
71 linkResourceAllocationsMap = new HashMap<>();
72 allocatedResources = new HashMap<>();
73 freeResources = new HashMap<>();
74
75 log.info("Started");
76 }
77
78 @Deactivate
79 public void deactivate() {
80 log.info("Stopped");
81 }
82
Toshio Koide69e52572014-10-30 11:14:09 -070083 /**
84 * Returns free resources for a given link obtaining from topology
85 * information.
86 *
87 * @param link the target link
88 * @return free resources
89 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080090 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080091 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070092 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080093
94 try {
95 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
96 for (int i = 1; i <= waves; i++) {
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -070097 allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
Toshio Koide8e5e91e2014-11-13 12:27:12 -080098 }
99 } catch (NumberFormatException e) {
100 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -0700101 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800102
Sho SHIMIZU63feca72015-05-07 10:44:25 -0700103 BandwidthResource bandwidth = DEFAULT_BANDWIDTH;
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800104 try {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700105 bandwidth = new BandwidthResource(
106 Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH)))));
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800107 } catch (NumberFormatException e) {
108 log.debug("No bandwidth annotation on link %s", link);
109 }
Ray Milkey73257012014-11-20 12:02:27 -0800110 allocations.add(
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800111 new BandwidthResourceAllocation(bandwidth));
Toshio Koide106d4492014-10-28 11:22:02 -0700112 return allocations;
113 }
114
Toshio Koide69e52572014-10-30 11:14:09 -0700115 /**
116 * Finds and returns {@link BandwidthResourceAllocation} object from a given
117 * set.
118 *
119 * @param freeRes a set of ResourceAllocation object.
120 * @return {@link BandwidthResourceAllocation} object if found, otherwise
121 * {@link BandwidthResourceAllocation} object with 0 bandwidth
122 *
123 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800124 private synchronized BandwidthResourceAllocation getBandwidth(
125 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700126 for (ResourceAllocation res : freeRes) {
127 if (res.type() == ResourceType.BANDWIDTH) {
128 return (BandwidthResourceAllocation) res;
129 }
130 }
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700131 return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0)));
Toshio Koide106d4492014-10-28 11:22:02 -0700132 }
133
Toshio Koide69e52572014-10-30 11:14:09 -0700134 /**
135 * Subtracts given resources from free resources for given link.
136 *
137 * @param link the target link
138 * @param allocations the resources to be subtracted
139 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800140 private synchronized void subtractFreeResources(Link link,
141 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700142 // TODO Use lock or version for updating freeResources.
143 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700144 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700145 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
146 for (ResourceAllocation res : subRes) {
147 switch (res.type()) {
148 case BANDWIDTH:
149 BandwidthResourceAllocation ba = getBandwidth(freeRes);
150 double requestedBandwidth =
151 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
152 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
Ray Milkey9a39eca2015-01-05 09:41:01 -0800153 if (newBandwidth < 0.0) {
154 throw new ResourceAllocationException(
155 PositionalParameterStringFormatter.format(
156 "Unable to allocate bandwidth for link {} "
157 + "requested amount is {} current allocation is {}",
158 link,
159 requestedBandwidth,
160 ba));
161 }
Toshio Koide106d4492014-10-28 11:22:02 -0700162 freeRes.remove(ba);
163 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700164 new BandwidthResource(Bandwidth.bps(newBandwidth))));
Toshio Koide106d4492014-10-28 11:22:02 -0700165 break;
166 case LAMBDA:
Ray Milkey9a39eca2015-01-05 09:41:01 -0800167 final boolean lambdaAvailable = freeRes.remove(res);
168 if (!lambdaAvailable) {
169 int requestedLambda =
170 ((LambdaResourceAllocation) res).lambda().toInt();
171 throw new ResourceAllocationException(
172 PositionalParameterStringFormatter.format(
173 "Unable to allocate lambda for link {} lambda is {}",
174 link,
175 requestedLambda));
176 }
Toshio Koide106d4492014-10-28 11:22:02 -0700177 break;
178 default:
179 break;
180 }
181 }
182 freeResources.put(link, freeRes);
183
184 }
185
Toshio Koide69e52572014-10-30 11:14:09 -0700186 /**
187 * Adds given resources to free resources for given link.
188 *
189 * @param link the target link
190 * @param allocations the resources to be added
191 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800192 private synchronized void addFreeResources(Link link,
193 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700194 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700195 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700196 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
197 for (ResourceAllocation res : addRes) {
198 switch (res.type()) {
199 case BANDWIDTH:
200 BandwidthResourceAllocation ba = getBandwidth(freeRes);
201 double requestedBandwidth =
202 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
203 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
204 freeRes.remove(ba);
205 freeRes.add(new BandwidthResourceAllocation(
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700206 new BandwidthResource(Bandwidth.bps(newBandwidth))));
Toshio Koide106d4492014-10-28 11:22:02 -0700207 break;
208 case LAMBDA:
209 checkState(freeRes.add(res));
210 break;
211 default:
212 break;
213 }
214 }
215 freeResources.put(link, freeRes);
216 }
217
218 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800219 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700220 checkNotNull(link);
221 Set<ResourceAllocation> freeRes = freeResources.get(link);
222 if (freeRes == null) {
223 freeRes = readOriginalFreeResources(link);
224 }
225
226 return freeRes;
227 }
228
229 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800230 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700231 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700232 linkResourceAllocationsMap.put(allocations.intentId(), allocations);
Toshio Koide106d4492014-10-28 11:22:02 -0700233 for (Link link : allocations.links()) {
234 subtractFreeResources(link, allocations);
235 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
236 if (linkAllocs == null) {
237 linkAllocs = new HashSet<>();
238 }
239 linkAllocs.add(allocations);
240 allocatedResources.put(link, linkAllocs);
241 }
242 }
243
244 @Override
Ray Milkeye97ede92014-11-20 10:43:12 -0800245 public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700246 checkNotNull(allocations);
Ayaka Koshibee114f042015-05-01 11:43:00 -0700247 linkResourceAllocationsMap.remove(allocations.intentId());
Toshio Koide106d4492014-10-28 11:22:02 -0700248 for (Link link : allocations.links()) {
249 addFreeResources(link, allocations);
250 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
251 if (linkAllocs == null) {
252 log.error("Missing resource allocation.");
253 } else {
254 linkAllocs.remove(allocations);
255 }
256 allocatedResources.put(link, linkAllocs);
257 }
Ray Milkeye97ede92014-11-20 10:43:12 -0800258
259 final List<LinkResourceAllocations> releasedResources =
260 ImmutableList.of(allocations);
261
262 return new LinkResourceEvent(
263 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
264 releasedResources);
Toshio Koide106d4492014-10-28 11:22:02 -0700265 }
266
267 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800268 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700269 checkNotNull(intentId);
270 return linkResourceAllocationsMap.get(intentId);
271 }
272
273 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800274 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700275 checkNotNull(link);
276 Set<LinkResourceAllocations> result = allocatedResources.get(link);
277 if (result == null) {
278 result = Collections.emptySet();
279 }
280 return Collections.unmodifiableSet(result);
281 }
282
283 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800284 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700285 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
286 }
287
Ray Milkeye97ede92014-11-20 10:43:12 -0800288
Toshio Koide106d4492014-10-28 11:22:02 -0700289}