blob: 52f60afb324ffbfe38acd2ad8c074423cb1358c1 [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 Koide69e52572014-10-30 11:14:09 -070018import static com.google.common.base.Preconditions.checkNotNull;
19import static com.google.common.base.Preconditions.checkState;
Toshio Koide106d4492014-10-28 11:22:02 -070020import static org.slf4j.LoggerFactory.getLogger;
21
22import java.util.Collections;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.Map;
26import java.util.Set;
27
28import org.apache.felix.scr.annotations.Activate;
29import org.apache.felix.scr.annotations.Component;
30import org.apache.felix.scr.annotations.Deactivate;
31import org.apache.felix.scr.annotations.Service;
Toshio Koide8e5e91e2014-11-13 12:27:12 -080032import org.onlab.onos.net.AnnotationKeys;
33import org.onlab.onos.net.Annotations;
Toshio Koide106d4492014-10-28 11:22:02 -070034import org.onlab.onos.net.Link;
35import org.onlab.onos.net.intent.IntentId;
36import org.onlab.onos.net.resource.Bandwidth;
37import org.onlab.onos.net.resource.BandwidthResourceAllocation;
38import org.onlab.onos.net.resource.Lambda;
39import org.onlab.onos.net.resource.LambdaResourceAllocation;
40import org.onlab.onos.net.resource.LinkResourceAllocations;
41import org.onlab.onos.net.resource.LinkResourceStore;
42import org.onlab.onos.net.resource.ResourceAllocation;
43import org.onlab.onos.net.resource.ResourceType;
44import org.slf4j.Logger;
45
46/**
47 * Manages link resources using trivial in-memory structures implementation.
48 */
49@Component(immediate = true)
50@Service
51public class SimpleLinkResourceStore implements LinkResourceStore {
52 private final Logger log = getLogger(getClass());
53 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
54 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
55 private Map<Link, Set<ResourceAllocation>> freeResources;
56
57 @Activate
58 public void activate() {
59 linkResourceAllocationsMap = new HashMap<>();
60 allocatedResources = new HashMap<>();
61 freeResources = new HashMap<>();
62
63 log.info("Started");
64 }
65
66 @Deactivate
67 public void deactivate() {
68 log.info("Stopped");
69 }
70
Toshio Koide69e52572014-10-30 11:14:09 -070071 /**
72 * Returns free resources for a given link obtaining from topology
73 * information.
74 *
75 * @param link the target link
76 * @return free resources
77 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080078 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080079 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070080 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080081
82 try {
83 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
84 for (int i = 1; i <= waves; i++) {
85 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
86 }
87 } catch (NumberFormatException e) {
88 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -070089 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -080090
91 try {
92 int bandwidth = Integer.parseInt(annotations.value(AnnotationKeys.BANDWIDTH));
93 allocations.add(
94 new BandwidthResourceAllocation(Bandwidth.valueOf(bandwidth)));
95 } catch (NumberFormatException e) {
96 log.debug("No bandwidth annotation on link %s", link);
97 }
98
Toshio Koide106d4492014-10-28 11:22:02 -070099 return allocations;
100 }
101
Toshio Koide69e52572014-10-30 11:14:09 -0700102 /**
103 * Finds and returns {@link BandwidthResourceAllocation} object from a given
104 * set.
105 *
106 * @param freeRes a set of ResourceAllocation object.
107 * @return {@link BandwidthResourceAllocation} object if found, otherwise
108 * {@link BandwidthResourceAllocation} object with 0 bandwidth
109 *
110 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800111 private synchronized BandwidthResourceAllocation getBandwidth(
112 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700113 for (ResourceAllocation res : freeRes) {
114 if (res.type() == ResourceType.BANDWIDTH) {
115 return (BandwidthResourceAllocation) res;
116 }
117 }
118 return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
119 }
120
Toshio Koide69e52572014-10-30 11:14:09 -0700121 /**
122 * Subtracts given resources from free resources for given link.
123 *
124 * @param link the target link
125 * @param allocations the resources to be subtracted
126 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800127 private synchronized void subtractFreeResources(Link link,
128 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700129 // TODO Use lock or version for updating freeResources.
130 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700131 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700132 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
133 for (ResourceAllocation res : subRes) {
134 switch (res.type()) {
135 case BANDWIDTH:
136 BandwidthResourceAllocation ba = getBandwidth(freeRes);
137 double requestedBandwidth =
138 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
139 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
140 checkState(newBandwidth >= 0.0);
141 freeRes.remove(ba);
142 freeRes.add(new BandwidthResourceAllocation(
143 Bandwidth.valueOf(newBandwidth)));
144 break;
145 case LAMBDA:
146 checkState(freeRes.remove(res));
147 break;
148 default:
149 break;
150 }
151 }
152 freeResources.put(link, freeRes);
153
154 }
155
Toshio Koide69e52572014-10-30 11:14:09 -0700156 /**
157 * Adds given resources to free resources for given link.
158 *
159 * @param link the target link
160 * @param allocations the resources to be added
161 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800162 private synchronized void addFreeResources(Link link,
163 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700164 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700165 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700166 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
167 for (ResourceAllocation res : addRes) {
168 switch (res.type()) {
169 case BANDWIDTH:
170 BandwidthResourceAllocation ba = getBandwidth(freeRes);
171 double requestedBandwidth =
172 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
173 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
174 freeRes.remove(ba);
175 freeRes.add(new BandwidthResourceAllocation(
176 Bandwidth.valueOf(newBandwidth)));
177 break;
178 case LAMBDA:
179 checkState(freeRes.add(res));
180 break;
181 default:
182 break;
183 }
184 }
185 freeResources.put(link, freeRes);
186 }
187
188 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800189 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700190 checkNotNull(link);
191 Set<ResourceAllocation> freeRes = freeResources.get(link);
192 if (freeRes == null) {
193 freeRes = readOriginalFreeResources(link);
194 }
195
196 return freeRes;
197 }
198
199 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800200 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700201 checkNotNull(allocations);
202 linkResourceAllocationsMap.put(allocations.intendId(), allocations);
203 for (Link link : allocations.links()) {
204 subtractFreeResources(link, allocations);
205 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
206 if (linkAllocs == null) {
207 linkAllocs = new HashSet<>();
208 }
209 linkAllocs.add(allocations);
210 allocatedResources.put(link, linkAllocs);
211 }
212 }
213
214 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800215 public synchronized void releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700216 checkNotNull(allocations);
Yuta HIGUCHIc9c9e222014-11-04 09:17:08 -0800217 linkResourceAllocationsMap.remove(allocations.intendId());
Toshio Koide106d4492014-10-28 11:22:02 -0700218 for (Link link : allocations.links()) {
219 addFreeResources(link, allocations);
220 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
221 if (linkAllocs == null) {
222 log.error("Missing resource allocation.");
223 } else {
224 linkAllocs.remove(allocations);
225 }
226 allocatedResources.put(link, linkAllocs);
227 }
228 }
229
230 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800231 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700232 checkNotNull(intentId);
233 return linkResourceAllocationsMap.get(intentId);
234 }
235
236 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800237 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700238 checkNotNull(link);
239 Set<LinkResourceAllocations> result = allocatedResources.get(link);
240 if (result == null) {
241 result = Collections.emptySet();
242 }
243 return Collections.unmodifiableSet(result);
244 }
245
246 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800247 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700248 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
249 }
250
251}