blob: a093fa5c6fe7fe5f4738a73f6886e48ea5ed8dd4 [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 {
Ray Milkey73257012014-11-20 12:02:27 -080052 private static final int DEFAULT_BANDWIDTH = 1_000;
Toshio Koide106d4492014-10-28 11:22:02 -070053 private final Logger log = getLogger(getClass());
54 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
55 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
56 private Map<Link, Set<ResourceAllocation>> freeResources;
57
58 @Activate
59 public void activate() {
60 linkResourceAllocationsMap = new HashMap<>();
61 allocatedResources = new HashMap<>();
62 freeResources = new HashMap<>();
63
64 log.info("Started");
65 }
66
67 @Deactivate
68 public void deactivate() {
69 log.info("Stopped");
70 }
71
Toshio Koide69e52572014-10-30 11:14:09 -070072 /**
73 * Returns free resources for a given link obtaining from topology
74 * information.
75 *
76 * @param link the target link
77 * @return free resources
78 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080079 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide8e5e91e2014-11-13 12:27:12 -080080 Annotations annotations = link.annotations();
Toshio Koide106d4492014-10-28 11:22:02 -070081 Set<ResourceAllocation> allocations = new HashSet<>();
Toshio Koide8e5e91e2014-11-13 12:27:12 -080082
83 try {
84 int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
85 for (int i = 1; i <= waves; i++) {
86 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
87 }
88 } catch (NumberFormatException e) {
89 log.debug("No optical.wave annotation on link %s", link);
Toshio Koide106d4492014-10-28 11:22:02 -070090 }
Toshio Koide8e5e91e2014-11-13 12:27:12 -080091
Ray Milkey73257012014-11-20 12:02:27 -080092 int bandwidth = DEFAULT_BANDWIDTH;
Toshio Koide8e5e91e2014-11-13 12:27:12 -080093 try {
Ray Milkey73257012014-11-20 12:02:27 -080094 bandwidth = Integer.parseInt(annotations.value(AnnotationKeys.BANDWIDTH));
Toshio Koide8e5e91e2014-11-13 12:27:12 -080095 } catch (NumberFormatException e) {
96 log.debug("No bandwidth annotation on link %s", link);
97 }
Ray Milkey73257012014-11-20 12:02:27 -080098 allocations.add(
99 new BandwidthResourceAllocation(Bandwidth.valueOf(bandwidth)));
Toshio Koide106d4492014-10-28 11:22:02 -0700100 return allocations;
101 }
102
Toshio Koide69e52572014-10-30 11:14:09 -0700103 /**
104 * Finds and returns {@link BandwidthResourceAllocation} object from a given
105 * set.
106 *
107 * @param freeRes a set of ResourceAllocation object.
108 * @return {@link BandwidthResourceAllocation} object if found, otherwise
109 * {@link BandwidthResourceAllocation} object with 0 bandwidth
110 *
111 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800112 private synchronized BandwidthResourceAllocation getBandwidth(
113 Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -0700114 for (ResourceAllocation res : freeRes) {
115 if (res.type() == ResourceType.BANDWIDTH) {
116 return (BandwidthResourceAllocation) res;
117 }
118 }
119 return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
120 }
121
Toshio Koide69e52572014-10-30 11:14:09 -0700122 /**
123 * Subtracts given resources from free resources for given link.
124 *
125 * @param link the target link
126 * @param allocations the resources to be subtracted
127 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800128 private synchronized void subtractFreeResources(Link link,
129 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700130 // TODO Use lock or version for updating freeResources.
131 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700132 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700133 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
134 for (ResourceAllocation res : subRes) {
135 switch (res.type()) {
136 case BANDWIDTH:
137 BandwidthResourceAllocation ba = getBandwidth(freeRes);
138 double requestedBandwidth =
139 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
140 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
141 checkState(newBandwidth >= 0.0);
142 freeRes.remove(ba);
143 freeRes.add(new BandwidthResourceAllocation(
144 Bandwidth.valueOf(newBandwidth)));
145 break;
146 case LAMBDA:
147 checkState(freeRes.remove(res));
148 break;
149 default:
150 break;
151 }
152 }
153 freeResources.put(link, freeRes);
154
155 }
156
Toshio Koide69e52572014-10-30 11:14:09 -0700157 /**
158 * Adds given resources to free resources for given link.
159 *
160 * @param link the target link
161 * @param allocations the resources to be added
162 */
Toshio Koide8e5e91e2014-11-13 12:27:12 -0800163 private synchronized void addFreeResources(Link link,
164 LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700165 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700166 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700167 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
168 for (ResourceAllocation res : addRes) {
169 switch (res.type()) {
170 case BANDWIDTH:
171 BandwidthResourceAllocation ba = getBandwidth(freeRes);
172 double requestedBandwidth =
173 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
174 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
175 freeRes.remove(ba);
176 freeRes.add(new BandwidthResourceAllocation(
177 Bandwidth.valueOf(newBandwidth)));
178 break;
179 case LAMBDA:
180 checkState(freeRes.add(res));
181 break;
182 default:
183 break;
184 }
185 }
186 freeResources.put(link, freeRes);
187 }
188
189 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800190 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700191 checkNotNull(link);
192 Set<ResourceAllocation> freeRes = freeResources.get(link);
193 if (freeRes == null) {
194 freeRes = readOriginalFreeResources(link);
195 }
196
197 return freeRes;
198 }
199
200 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800201 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700202 checkNotNull(allocations);
203 linkResourceAllocationsMap.put(allocations.intendId(), allocations);
204 for (Link link : allocations.links()) {
205 subtractFreeResources(link, allocations);
206 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
207 if (linkAllocs == null) {
208 linkAllocs = new HashSet<>();
209 }
210 linkAllocs.add(allocations);
211 allocatedResources.put(link, linkAllocs);
212 }
213 }
214
215 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800216 public synchronized void releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700217 checkNotNull(allocations);
Yuta HIGUCHIc9c9e222014-11-04 09:17:08 -0800218 linkResourceAllocationsMap.remove(allocations.intendId());
Toshio Koide106d4492014-10-28 11:22:02 -0700219 for (Link link : allocations.links()) {
220 addFreeResources(link, allocations);
221 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
222 if (linkAllocs == null) {
223 log.error("Missing resource allocation.");
224 } else {
225 linkAllocs.remove(allocations);
226 }
227 allocatedResources.put(link, linkAllocs);
228 }
229 }
230
231 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800232 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700233 checkNotNull(intentId);
234 return linkResourceAllocationsMap.get(intentId);
235 }
236
237 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800238 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700239 checkNotNull(link);
240 Set<LinkResourceAllocations> result = allocatedResources.get(link);
241 if (result == null) {
242 result = Collections.emptySet();
243 }
244 return Collections.unmodifiableSet(result);
245 }
246
247 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800248 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700249 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
250 }
251
252}