blob: 76e0ff6a6aac9aac9eeb4d59a84f47ad9a69aa72 [file] [log] [blame]
Toshio Koide106d4492014-10-28 11:22:02 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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 */
16package org.onlab.onos.store.trivial.impl;
17
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;
Toshio Koide8e5e91e2014-11-13 12:27:12 -080029import org.onlab.onos.net.AnnotationKeys;
30import org.onlab.onos.net.Annotations;
Toshio Koide106d4492014-10-28 11:22:02 -070031import org.onlab.onos.net.Link;
32import org.onlab.onos.net.intent.IntentId;
33import org.onlab.onos.net.resource.Bandwidth;
34import org.onlab.onos.net.resource.BandwidthResourceAllocation;
35import org.onlab.onos.net.resource.Lambda;
36import org.onlab.onos.net.resource.LambdaResourceAllocation;
37import org.onlab.onos.net.resource.LinkResourceAllocations;
Ray Milkeye97ede92014-11-20 10:43:12 -080038import org.onlab.onos.net.resource.LinkResourceEvent;
Toshio Koide106d4492014-10-28 11:22:02 -070039import org.onlab.onos.net.resource.LinkResourceStore;
40import org.onlab.onos.net.resource.ResourceAllocation;
41import org.onlab.onos.net.resource.ResourceType;
42import org.slf4j.Logger;
43
Ray Milkeye97ede92014-11-20 10:43:12 -080044import com.google.common.collect.ImmutableList;
45
46import static com.google.common.base.Preconditions.checkNotNull;
47import static com.google.common.base.Preconditions.checkState;
48import static org.slf4j.LoggerFactory.getLogger;
49
Toshio Koide106d4492014-10-28 11:22:02 -070050/**
51 * Manages link resources using trivial in-memory structures implementation.
52 */
53@Component(immediate = true)
54@Service
55public class SimpleLinkResourceStore implements LinkResourceStore {
Ray Milkey73257012014-11-20 12:02:27 -080056 private static final int DEFAULT_BANDWIDTH = 1_000;
Toshio Koide106d4492014-10-28 11:22:02 -070057 private final Logger log = getLogger(getClass());
Ray Milkeye97ede92014-11-20 10:43:12 -080058
Toshio Koide106d4492014-10-28 11:22:02 -070059 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
60 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
61 private Map<Link, Set<ResourceAllocation>> freeResources;
62
63 @Activate
64 public void activate() {
65 linkResourceAllocationsMap = new HashMap<>();
66 allocatedResources = new HashMap<>();
67 freeResources = new HashMap<>();
68
69 log.info("Started");
70 }
71
72 @Deactivate
73 public void deactivate() {
74 log.info("Stopped");
75 }
76
Toshio Koide69e52572014-10-30 11:14:09 -070077 /**
78 * Returns free resources for a given link obtaining from topology
79 * information.
80 *
81 * @param link the target link
82 * @return free resources
83 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080084 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080085 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070086 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080087
88 try {
89 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
90 for (int i = 1; i <= waves; i++) {
91 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
92 }
93 } catch (NumberFormatException e) {
94 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -070095 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -080096
Ray Milkey73257012014-11-20 12:02:27 -080097 int bandwidth = DEFAULT_BANDWIDTH;
Toshio Koide8e5e91e2014-11-13 12:27:12 -080098 try {
Ray Milkey73257012014-11-20 12:02:27 -080099 bandwidth = Integer.parseInt(annotations.value(AnnotationKeys.BANDWIDTH));
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800100 } catch (NumberFormatException e) {
101 log.debug("No bandwidth annotation on link %s", link);
102 }
Ray Milkey73257012014-11-20 12:02:27 -0800103 allocations.add(
104 new BandwidthResourceAllocation(Bandwidth.valueOf(bandwidth)));
Toshio Koide106d4492014-10-28 11:22:02 -0700105 return allocations;
106 }
107
Toshio Koide69e52572014-10-30 11:14:09 -0700108 /**
109 * Finds and returns {@link BandwidthResourceAllocation} object from a given
110 * set.
111 *
112 * @param freeRes a set of ResourceAllocation object.
113 * @return {@link BandwidthResourceAllocation} object if found, otherwise
114 * {@link BandwidthResourceAllocation} object with 0 bandwidth
115 *
116 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800117 private synchronized BandwidthResourceAllocation getBandwidth(
118 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700119 for (ResourceAllocation res : freeRes) {
120 if (res.type() == ResourceType.BANDWIDTH) {
121 return (BandwidthResourceAllocation) res;
122 }
123 }
124 return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
125 }
126
Toshio Koide69e52572014-10-30 11:14:09 -0700127 /**
128 * Subtracts given resources from free resources for given link.
129 *
130 * @param link the target link
131 * @param allocations the resources to be subtracted
132 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800133 private synchronized void subtractFreeResources(Link link,
134 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700135 // TODO Use lock or version for updating freeResources.
136 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700137 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700138 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
139 for (ResourceAllocation res : subRes) {
140 switch (res.type()) {
141 case BANDWIDTH:
142 BandwidthResourceAllocation ba = getBandwidth(freeRes);
143 double requestedBandwidth =
144 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
145 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
146 checkState(newBandwidth >= 0.0);
147 freeRes.remove(ba);
148 freeRes.add(new BandwidthResourceAllocation(
149 Bandwidth.valueOf(newBandwidth)));
150 break;
151 case LAMBDA:
152 checkState(freeRes.remove(res));
153 break;
154 default:
155 break;
156 }
157 }
158 freeResources.put(link, freeRes);
159
160 }
161
Toshio Koide69e52572014-10-30 11:14:09 -0700162 /**
163 * Adds given resources to free resources for given link.
164 *
165 * @param link the target link
166 * @param allocations the resources to be added
167 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800168 private synchronized void addFreeResources(Link link,
169 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700170 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700171 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700172 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
173 for (ResourceAllocation res : addRes) {
174 switch (res.type()) {
175 case BANDWIDTH:
176 BandwidthResourceAllocation ba = getBandwidth(freeRes);
177 double requestedBandwidth =
178 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
179 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
180 freeRes.remove(ba);
181 freeRes.add(new BandwidthResourceAllocation(
182 Bandwidth.valueOf(newBandwidth)));
183 break;
184 case LAMBDA:
185 checkState(freeRes.add(res));
186 break;
187 default:
188 break;
189 }
190 }
191 freeResources.put(link, freeRes);
192 }
193
194 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800195 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700196 checkNotNull(link);
197 Set<ResourceAllocation> freeRes = freeResources.get(link);
198 if (freeRes == null) {
199 freeRes = readOriginalFreeResources(link);
200 }
201
202 return freeRes;
203 }
204
205 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800206 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700207 checkNotNull(allocations);
208 linkResourceAllocationsMap.put(allocations.intendId(), allocations);
209 for (Link link : allocations.links()) {
210 subtractFreeResources(link, allocations);
211 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
212 if (linkAllocs == null) {
213 linkAllocs = new HashSet<>();
214 }
215 linkAllocs.add(allocations);
216 allocatedResources.put(link, linkAllocs);
217 }
218 }
219
220 @Override
Ray Milkeye97ede92014-11-20 10:43:12 -0800221 public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700222 checkNotNull(allocations);
Yuta HIGUCHIc9c9e222014-11-04 09:17:08 -0800223 linkResourceAllocationsMap.remove(allocations.intendId());
Toshio Koide106d4492014-10-28 11:22:02 -0700224 for (Link link : allocations.links()) {
225 addFreeResources(link, allocations);
226 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
227 if (linkAllocs == null) {
228 log.error("Missing resource allocation.");
229 } else {
230 linkAllocs.remove(allocations);
231 }
232 allocatedResources.put(link, linkAllocs);
233 }
Ray Milkeye97ede92014-11-20 10:43:12 -0800234
235 final List<LinkResourceAllocations> releasedResources =
236 ImmutableList.of(allocations);
237
238 return new LinkResourceEvent(
239 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
240 releasedResources);
Toshio Koide106d4492014-10-28 11:22:02 -0700241 }
242
243 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800244 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700245 checkNotNull(intentId);
246 return linkResourceAllocationsMap.get(intentId);
247 }
248
249 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800250 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700251 checkNotNull(link);
252 Set<LinkResourceAllocations> result = allocatedResources.get(link);
253 if (result == null) {
254 result = Collections.emptySet();
255 }
256 return Collections.unmodifiableSet(result);
257 }
258
259 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800260 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700261 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
262 }
263
Ray Milkeye97ede92014-11-20 10:43:12 -0800264
Toshio Koide106d4492014-10-28 11:22:02 -0700265}