blob: 209e62cb9a35d5d87ae7c385991d077ea4dfe7b8 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -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.net.resource.impl;
Toshio Koide50df38d2014-10-23 10:36:51 -070017
Toshio Koide50df38d2014-10-23 10:36:51 -070018import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
Toshio Koide106d4492014-10-28 11:22:02 -070021import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
Toshio Koide50df38d2014-10-23 10:36:51 -070023import org.apache.felix.scr.annotations.Service;
Changhoon Yoon541ef712015-05-23 17:18:34 +090024import org.onosproject.core.Permission;
Simon Huntff663742015-05-14 13:33:05 -070025import org.onosproject.event.ListenerRegistry;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.event.EventDeliveryService;
27import org.onosproject.net.Link;
28import org.onosproject.net.intent.IntentId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070029import org.onosproject.net.resource.link.BandwidthResourceAllocation;
30import org.onosproject.net.resource.link.BandwidthResourceRequest;
31import org.onosproject.net.resource.link.DefaultLinkResourceAllocations;
32import org.onosproject.net.resource.link.LambdaResource;
33import org.onosproject.net.resource.link.LambdaResourceAllocation;
34import org.onosproject.net.resource.link.LambdaResourceRequest;
35import org.onosproject.net.resource.link.LinkResourceAllocations;
36import org.onosproject.net.resource.link.LinkResourceEvent;
37import org.onosproject.net.resource.link.LinkResourceListener;
38import org.onosproject.net.resource.link.LinkResourceRequest;
39import org.onosproject.net.resource.link.LinkResourceService;
40import org.onosproject.net.resource.link.LinkResourceStore;
41import org.onosproject.net.resource.link.LinkResourceStoreDelegate;
42import org.onosproject.net.resource.link.MplsLabel;
43import org.onosproject.net.resource.link.MplsLabelResourceAllocation;
44import org.onosproject.net.resource.link.MplsLabelResourceRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080045import org.onosproject.net.resource.ResourceAllocation;
46import org.onosproject.net.resource.ResourceRequest;
47import org.onosproject.net.resource.ResourceType;
Toshio Koide50df38d2014-10-23 10:36:51 -070048import org.slf4j.Logger;
49
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080050import java.util.Collections;
51import java.util.HashMap;
52import java.util.HashSet;
53import java.util.Iterator;
54import java.util.Map;
55import java.util.Set;
56
57import static com.google.common.base.Preconditions.checkArgument;
58import static com.google.common.base.Preconditions.checkNotNull;
59import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoon541ef712015-05-23 17:18:34 +090060import static org.onosproject.security.AppGuard.checkPermission;
61
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080062
Toshio Koide50df38d2014-10-23 10:36:51 -070063/**
64 * Provides basic implementation of link resources allocation.
65 */
66@Component(immediate = true)
67@Service
68public class LinkResourceManager implements LinkResourceService {
69
70 private final Logger log = getLogger(getClass());
71
Simon Huntff663742015-05-14 13:33:05 -070072 protected final ListenerRegistry<LinkResourceEvent, LinkResourceListener>
73 listenerRegistry = new ListenerRegistry<>();
Ray Milkeye97ede92014-11-20 10:43:12 -080074
Toshio Koide106d4492014-10-28 11:22:02 -070075 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 private LinkResourceStore store;
Ray Milkeycaa450b2014-10-29 15:54:24 -070077
Ray Milkeye97ede92014-11-20 10:43:12 -080078 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected EventDeliveryService eventDispatcher;
80
Toshio Koide50df38d2014-10-23 10:36:51 -070081 @Activate
82 public void activate() {
Ray Milkeye97ede92014-11-20 10:43:12 -080083 eventDispatcher.addSink(LinkResourceEvent.class, listenerRegistry);
Toshio Koide50df38d2014-10-23 10:36:51 -070084 log.info("Started");
85 }
86
87 @Deactivate
88 public void deactivate() {
89 log.info("Stopped");
90 }
91
Toshio Koide106d4492014-10-28 11:22:02 -070092 /**
93 * Returns available lambdas on specified link.
94 *
95 * @param link the link
96 * @return available lambdas on specified link
97 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -070098 private Set<LambdaResource> getAvailableLambdas(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -070099 checkNotNull(link);
100 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
101 if (resAllocs == null) {
102 return Collections.emptySet();
103 }
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700104 Set<LambdaResource> lambdas = new HashSet<>();
Toshio Koide106d4492014-10-28 11:22:02 -0700105 for (ResourceAllocation res : resAllocs) {
106 if (res.type() == ResourceType.LAMBDA) {
107 lambdas.add(((LambdaResourceAllocation) res).lambda());
108 }
109 }
110 return lambdas;
Toshio Koide9be539e2014-10-23 18:43:30 -0700111 }
112
Michele Santuari4b6019e2014-12-19 11:31:45 +0100113
Toshio Koide106d4492014-10-28 11:22:02 -0700114 /**
115 * Returns available lambdas on specified links.
116 *
117 * @param links the links
118 * @return available lambdas on specified links
119 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700120 private Iterable<LambdaResource> getAvailableLambdas(Iterable<Link> links) {
Toshio Koide106d4492014-10-28 11:22:02 -0700121 checkNotNull(links);
122 Iterator<Link> i = links.iterator();
123 checkArgument(i.hasNext());
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700124 Set<LambdaResource> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
Toshio Koide106d4492014-10-28 11:22:02 -0700125 while (i.hasNext()) {
126 lambdas.retainAll(getAvailableLambdas(i.next()));
127 }
128 return lambdas;
129 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700130
Michele Santuari4b6019e2014-12-19 11:31:45 +0100131
132 /**
133 * Returns available MPLS label on specified link.
134 *
135 * @param link the link
136 * @return available MPLS labels on specified link
137 */
138 private Iterable<MplsLabel> getAvailableMplsLabels(Link link) {
139 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
140 if (resAllocs == null) {
141 return Collections.emptySet();
142 }
143 Set<MplsLabel> mplsLabels = new HashSet<>();
144 for (ResourceAllocation res : resAllocs) {
145 if (res.type() == ResourceType.MPLS_LABEL) {
146
147 mplsLabels.add(((MplsLabelResourceAllocation) res).mplsLabel());
148 }
149 }
150
151 return mplsLabels;
152 }
153
Toshio Koide50df38d2014-10-23 10:36:51 -0700154 @Override
155 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900156 checkPermission(Permission.LINK_WRITE);
157
Toshio Koide106d4492014-10-28 11:22:02 -0700158 // TODO Concatenate multiple bandwidth requests.
159 // TODO Support multiple lambda resource requests.
160 // TODO Throw appropriate exception.
Toshio Koide106d4492014-10-28 11:22:02 -0700161 Set<ResourceAllocation> allocs = new HashSet<>();
Michele Santuari4b6019e2014-12-19 11:31:45 +0100162 Map<Link, Set<ResourceAllocation>> allocsPerLink = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700163 for (ResourceRequest r : req.resources()) {
Toshio Koideca0fcff2014-10-23 14:08:36 -0700164 switch (r.type()) {
165 case BANDWIDTH:
Toshio Koideca0fcff2014-10-23 14:08:36 -0700166 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
Toshio Koide106d4492014-10-28 11:22:02 -0700167 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
Toshio Koideca0fcff2014-10-23 14:08:36 -0700168 break;
169 case LAMBDA:
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700170 Iterator<LambdaResource> lambdaIterator =
Toshio Koide106d4492014-10-28 11:22:02 -0700171 getAvailableLambdas(req.links()).iterator();
Toshio Koide9be539e2014-10-23 18:43:30 -0700172 if (lambdaIterator.hasNext()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700173 allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
174 } else {
175 log.info("Failed to allocate lambda resource.");
176 return null;
Toshio Koide9be539e2014-10-23 18:43:30 -0700177 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700178 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100179 case MPLS_LABEL:
180 for (Link link : req.links()) {
181 if (allocsPerLink.get(link) == null) {
182 allocsPerLink.put(link,
183 new HashSet<ResourceAllocation>());
184 }
185 Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link)
186 .iterator();
187 if (mplsIter.hasNext()) {
188 allocsPerLink.get(link)
189 .add(new MplsLabelResourceAllocation(mplsIter
190 .next()));
191 } else {
192 log.info("Failed to allocate MPLS resource.");
193 break;
194 }
195 }
196 break;
Toshio Koideca0fcff2014-10-23 14:08:36 -0700197 default:
198 break;
199 }
200 }
201
202 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700203 for (Link link : req.links()) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100204 allocations.put(link, new HashSet<ResourceAllocation>(allocs));
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800205 Set<ResourceAllocation> linkAllocs = allocsPerLink.get(link);
206 if (linkAllocs != null) {
207 allocations.get(link).addAll(linkAllocs);
208 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700209 }
Toshio Koide106d4492014-10-28 11:22:02 -0700210 LinkResourceAllocations result =
211 new DefaultLinkResourceAllocations(req, allocations);
212 store.allocateResources(result);
213 return result;
214
Toshio Koide50df38d2014-10-23 10:36:51 -0700215 }
216
217 @Override
218 public void releaseResources(LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900219 checkPermission(Permission.LINK_WRITE);
220
Ray Milkeye97ede92014-11-20 10:43:12 -0800221 final LinkResourceEvent event = store.releaseResources(allocations);
222 if (event != null) {
223 post(event);
224 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700225 }
226
227 @Override
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700228 public LinkResourceAllocations updateResources(LinkResourceRequest req,
Toshio Koide106d4492014-10-28 11:22:02 -0700229 LinkResourceAllocations oldAllocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900230 checkPermission(Permission.LINK_WRITE);
231
232 releaseResources(oldAllocations);
weibit00c94f52014-11-16 07:09:05 -0800233 return requestResources(req);
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700234 }
235
236 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700237 public Iterable<LinkResourceAllocations> getAllocations() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900238 checkPermission(Permission.LINK_READ);
239
Toshio Koide106d4492014-10-28 11:22:02 -0700240 return store.getAllocations();
Toshio Koide50df38d2014-10-23 10:36:51 -0700241 }
242
243 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700244 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900245 checkPermission(Permission.LINK_READ);
246
Toshio Koide106d4492014-10-28 11:22:02 -0700247 return store.getAllocations(link);
Toshio Koide50df38d2014-10-23 10:36:51 -0700248 }
249
250 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700251 public LinkResourceAllocations getAllocations(IntentId intentId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900252 checkPermission(Permission.LINK_READ);
253
Toshio Koide106d4492014-10-28 11:22:02 -0700254 return store.getAllocations(intentId);
Toshio Koide50df38d2014-10-23 10:36:51 -0700255 }
256
257 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700258 public Iterable<ResourceRequest> getAvailableResources(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900259 checkPermission(Permission.LINK_READ);
260
Toshio Koide106d4492014-10-28 11:22:02 -0700261 Set<ResourceAllocation> freeRes = store.getFreeResources(link);
262 Set<ResourceRequest> result = new HashSet<>();
263 for (ResourceAllocation alloc : freeRes) {
264 switch (alloc.type()) {
265 case BANDWIDTH:
266 result.add(new BandwidthResourceRequest(
267 ((BandwidthResourceAllocation) alloc).bandwidth()));
268 break;
269 case LAMBDA:
270 result.add(new LambdaResourceRequest());
271 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100272 case MPLS_LABEL:
273 result.add(new MplsLabelResourceRequest());
Sho SHIMIZU3fa9e8d2015-05-05 11:40:04 -0700274 break;
Toshio Koide106d4492014-10-28 11:22:02 -0700275 default:
276 break;
277 }
278 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700279 return result;
Toshio Koide50df38d2014-10-23 10:36:51 -0700280 }
281
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700282 @Override
weibit00c94f52014-11-16 07:09:05 -0800283 public Iterable<ResourceRequest> getAvailableResources(Link link,
Toshio Koide106d4492014-10-28 11:22:02 -0700284 LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900285 checkPermission(Permission.LINK_READ);
286
weibit00c94f52014-11-16 07:09:05 -0800287 Set<ResourceRequest> result = new HashSet<>();
288 Set<ResourceAllocation> allocatedRes = allocations.getResourceAllocation(link);
289 result = (Set<ResourceRequest>) getAvailableResources(link);
290 result.addAll(allocatedRes);
291 return result;
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700292 }
293
Ray Milkeye97ede92014-11-20 10:43:12 -0800294 @Override
295 public void addListener(LinkResourceListener listener) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900296 checkPermission(Permission.LINK_EVENT);
297
Ray Milkeye97ede92014-11-20 10:43:12 -0800298 listenerRegistry.addListener(listener);
299 }
300
301 @Override
302 public void removeListener(LinkResourceListener listener) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900303 checkPermission(Permission.LINK_EVENT);
304
Ray Milkeye97ede92014-11-20 10:43:12 -0800305 listenerRegistry.removeListener(listener);
306 }
307
308 /**
309 * Posts the specified event to the local event dispatcher.
310 */
311 private void post(LinkResourceEvent event) {
312 if (event != null) {
313 eventDispatcher.post(event);
314 }
315 }
316
317 /**
318 * Store delegate to re-post events emitted from the store.
319 */
320 private class InternalStoreDelegate implements LinkResourceStoreDelegate {
321 @Override
322 public void notify(LinkResourceEvent event) {
323 post(event);
324 }
325 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700326}