blob: e48b2cbe81094e3daaa0ffeb88f9e2645a702c83 [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
Sho SHIMIZU716c8e92015-07-02 11:35:34 -070018import com.google.common.collect.Sets;
Toshio Koide50df38d2014-10-23 10:36:51 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
Toshio Koide106d4492014-10-28 11:22:02 -070022import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
Toshio Koide50df38d2014-10-23 10:36:51 -070024import org.apache.felix.scr.annotations.Service;
Changhoon Yoon541ef712015-05-23 17:18:34 +090025import org.onosproject.core.Permission;
Simon Huntff663742015-05-14 13:33:05 -070026import org.onosproject.event.ListenerRegistry;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.event.EventDeliveryService;
28import org.onosproject.net.Link;
29import org.onosproject.net.intent.IntentId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070030import org.onosproject.net.resource.link.BandwidthResourceAllocation;
31import org.onosproject.net.resource.link.BandwidthResourceRequest;
32import org.onosproject.net.resource.link.DefaultLinkResourceAllocations;
33import org.onosproject.net.resource.link.LambdaResource;
34import org.onosproject.net.resource.link.LambdaResourceAllocation;
35import org.onosproject.net.resource.link.LambdaResourceRequest;
36import org.onosproject.net.resource.link.LinkResourceAllocations;
37import org.onosproject.net.resource.link.LinkResourceEvent;
38import org.onosproject.net.resource.link.LinkResourceListener;
39import org.onosproject.net.resource.link.LinkResourceRequest;
40import org.onosproject.net.resource.link.LinkResourceService;
41import org.onosproject.net.resource.link.LinkResourceStore;
42import org.onosproject.net.resource.link.LinkResourceStoreDelegate;
43import org.onosproject.net.resource.link.MplsLabel;
44import org.onosproject.net.resource.link.MplsLabelResourceAllocation;
45import org.onosproject.net.resource.link.MplsLabelResourceRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.resource.ResourceAllocation;
47import org.onosproject.net.resource.ResourceRequest;
48import org.onosproject.net.resource.ResourceType;
Toshio Koide50df38d2014-10-23 10:36:51 -070049import org.slf4j.Logger;
50
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080051import java.util.Collections;
52import java.util.HashMap;
53import java.util.HashSet;
54import java.util.Iterator;
55import java.util.Map;
56import java.util.Set;
57
58import static com.google.common.base.Preconditions.checkArgument;
59import static com.google.common.base.Preconditions.checkNotNull;
60import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoon541ef712015-05-23 17:18:34 +090061import static org.onosproject.security.AppGuard.checkPermission;
62
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080063
Toshio Koide50df38d2014-10-23 10:36:51 -070064/**
65 * Provides basic implementation of link resources allocation.
66 */
67@Component(immediate = true)
68@Service
69public class LinkResourceManager implements LinkResourceService {
70
71 private final Logger log = getLogger(getClass());
72
Simon Huntff663742015-05-14 13:33:05 -070073 protected final ListenerRegistry<LinkResourceEvent, LinkResourceListener>
74 listenerRegistry = new ListenerRegistry<>();
Ray Milkeye97ede92014-11-20 10:43:12 -080075
Toshio Koide106d4492014-10-28 11:22:02 -070076 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 private LinkResourceStore store;
Ray Milkeycaa450b2014-10-29 15:54:24 -070078
Ray Milkeye97ede92014-11-20 10:43:12 -080079 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 protected EventDeliveryService eventDispatcher;
81
Toshio Koide50df38d2014-10-23 10:36:51 -070082 @Activate
83 public void activate() {
Ray Milkeye97ede92014-11-20 10:43:12 -080084 eventDispatcher.addSink(LinkResourceEvent.class, listenerRegistry);
Toshio Koide50df38d2014-10-23 10:36:51 -070085 log.info("Started");
86 }
87
88 @Deactivate
89 public void deactivate() {
90 log.info("Stopped");
91 }
92
Toshio Koide106d4492014-10-28 11:22:02 -070093 /**
94 * Returns available lambdas on specified link.
95 *
96 * @param link the link
97 * @return available lambdas on specified link
98 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -070099 private Set<LambdaResource> getAvailableLambdas(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700100 checkNotNull(link);
101 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
102 if (resAllocs == null) {
103 return Collections.emptySet();
104 }
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700105 Set<LambdaResource> lambdas = new HashSet<>();
Toshio Koide106d4492014-10-28 11:22:02 -0700106 for (ResourceAllocation res : resAllocs) {
107 if (res.type() == ResourceType.LAMBDA) {
108 lambdas.add(((LambdaResourceAllocation) res).lambda());
109 }
110 }
111 return lambdas;
Toshio Koide9be539e2014-10-23 18:43:30 -0700112 }
113
Michele Santuari4b6019e2014-12-19 11:31:45 +0100114
Toshio Koide106d4492014-10-28 11:22:02 -0700115 /**
116 * Returns available lambdas on specified links.
117 *
118 * @param links the links
119 * @return available lambdas on specified links
120 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700121 private Iterable<LambdaResource> getAvailableLambdas(Iterable<Link> links) {
Toshio Koide106d4492014-10-28 11:22:02 -0700122 checkNotNull(links);
123 Iterator<Link> i = links.iterator();
124 checkArgument(i.hasNext());
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700125 Set<LambdaResource> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
Toshio Koide106d4492014-10-28 11:22:02 -0700126 while (i.hasNext()) {
127 lambdas.retainAll(getAvailableLambdas(i.next()));
128 }
129 return lambdas;
130 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700131
Michele Santuari4b6019e2014-12-19 11:31:45 +0100132
133 /**
134 * Returns available MPLS label on specified link.
135 *
136 * @param link the link
137 * @return available MPLS labels on specified link
138 */
139 private Iterable<MplsLabel> getAvailableMplsLabels(Link link) {
140 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
141 if (resAllocs == null) {
142 return Collections.emptySet();
143 }
144 Set<MplsLabel> mplsLabels = new HashSet<>();
145 for (ResourceAllocation res : resAllocs) {
146 if (res.type() == ResourceType.MPLS_LABEL) {
147
148 mplsLabels.add(((MplsLabelResourceAllocation) res).mplsLabel());
149 }
150 }
151
152 return mplsLabels;
153 }
154
Toshio Koide50df38d2014-10-23 10:36:51 -0700155 @Override
156 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900157 checkPermission(Permission.LINK_WRITE);
158
Toshio Koide106d4492014-10-28 11:22:02 -0700159 // TODO Concatenate multiple bandwidth requests.
160 // TODO Support multiple lambda resource requests.
161 // TODO Throw appropriate exception.
Toshio Koide106d4492014-10-28 11:22:02 -0700162 Set<ResourceAllocation> allocs = new HashSet<>();
Michele Santuari4b6019e2014-12-19 11:31:45 +0100163 Map<Link, Set<ResourceAllocation>> allocsPerLink = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700164 for (ResourceRequest r : req.resources()) {
Toshio Koideca0fcff2014-10-23 14:08:36 -0700165 switch (r.type()) {
166 case BANDWIDTH:
Toshio Koideca0fcff2014-10-23 14:08:36 -0700167 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
Toshio Koide106d4492014-10-28 11:22:02 -0700168 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
Toshio Koideca0fcff2014-10-23 14:08:36 -0700169 break;
170 case LAMBDA:
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700171 Iterator<LambdaResource> lambdaIterator =
Toshio Koide106d4492014-10-28 11:22:02 -0700172 getAvailableLambdas(req.links()).iterator();
Toshio Koide9be539e2014-10-23 18:43:30 -0700173 if (lambdaIterator.hasNext()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700174 allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
175 } else {
176 log.info("Failed to allocate lambda resource.");
177 return null;
Toshio Koide9be539e2014-10-23 18:43:30 -0700178 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700179 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100180 case MPLS_LABEL:
181 for (Link link : req.links()) {
182 if (allocsPerLink.get(link) == null) {
183 allocsPerLink.put(link,
184 new HashSet<ResourceAllocation>());
185 }
186 Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link)
187 .iterator();
188 if (mplsIter.hasNext()) {
189 allocsPerLink.get(link)
190 .add(new MplsLabelResourceAllocation(mplsIter
191 .next()));
192 } else {
193 log.info("Failed to allocate MPLS resource.");
194 break;
195 }
196 }
197 break;
Toshio Koideca0fcff2014-10-23 14:08:36 -0700198 default:
199 break;
200 }
201 }
202
203 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700204 for (Link link : req.links()) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100205 allocations.put(link, new HashSet<ResourceAllocation>(allocs));
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800206 Set<ResourceAllocation> linkAllocs = allocsPerLink.get(link);
207 if (linkAllocs != null) {
208 allocations.get(link).addAll(linkAllocs);
209 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700210 }
Toshio Koide106d4492014-10-28 11:22:02 -0700211 LinkResourceAllocations result =
212 new DefaultLinkResourceAllocations(req, allocations);
213 store.allocateResources(result);
214 return result;
215
Toshio Koide50df38d2014-10-23 10:36:51 -0700216 }
217
218 @Override
219 public void releaseResources(LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900220 checkPermission(Permission.LINK_WRITE);
221
Ray Milkeye97ede92014-11-20 10:43:12 -0800222 final LinkResourceEvent event = store.releaseResources(allocations);
223 if (event != null) {
224 post(event);
225 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700226 }
227
228 @Override
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700229 public LinkResourceAllocations updateResources(LinkResourceRequest req,
Toshio Koide106d4492014-10-28 11:22:02 -0700230 LinkResourceAllocations oldAllocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900231 checkPermission(Permission.LINK_WRITE);
232
233 releaseResources(oldAllocations);
weibit00c94f52014-11-16 07:09:05 -0800234 return requestResources(req);
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700235 }
236
237 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700238 public Iterable<LinkResourceAllocations> getAllocations() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900239 checkPermission(Permission.LINK_READ);
240
Toshio Koide106d4492014-10-28 11:22:02 -0700241 return store.getAllocations();
Toshio Koide50df38d2014-10-23 10:36:51 -0700242 }
243
244 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700245 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900246 checkPermission(Permission.LINK_READ);
247
Toshio Koide106d4492014-10-28 11:22:02 -0700248 return store.getAllocations(link);
Toshio Koide50df38d2014-10-23 10:36:51 -0700249 }
250
251 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700252 public LinkResourceAllocations getAllocations(IntentId intentId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900253 checkPermission(Permission.LINK_READ);
254
Toshio Koide106d4492014-10-28 11:22:02 -0700255 return store.getAllocations(intentId);
Toshio Koide50df38d2014-10-23 10:36:51 -0700256 }
257
258 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700259 public Iterable<ResourceRequest> getAvailableResources(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900260 checkPermission(Permission.LINK_READ);
261
Toshio Koide106d4492014-10-28 11:22:02 -0700262 Set<ResourceAllocation> freeRes = store.getFreeResources(link);
263 Set<ResourceRequest> result = new HashSet<>();
264 for (ResourceAllocation alloc : freeRes) {
265 switch (alloc.type()) {
266 case BANDWIDTH:
267 result.add(new BandwidthResourceRequest(
268 ((BandwidthResourceAllocation) alloc).bandwidth()));
269 break;
270 case LAMBDA:
271 result.add(new LambdaResourceRequest());
272 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100273 case MPLS_LABEL:
274 result.add(new MplsLabelResourceRequest());
Sho SHIMIZU3fa9e8d2015-05-05 11:40:04 -0700275 break;
Toshio Koide106d4492014-10-28 11:22:02 -0700276 default:
277 break;
278 }
279 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700280 return result;
Toshio Koide50df38d2014-10-23 10:36:51 -0700281 }
282
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700283 @Override
weibit00c94f52014-11-16 07:09:05 -0800284 public Iterable<ResourceRequest> getAvailableResources(Link link,
Toshio Koide106d4492014-10-28 11:22:02 -0700285 LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900286 checkPermission(Permission.LINK_READ);
287
weibit00c94f52014-11-16 07:09:05 -0800288 Set<ResourceAllocation> allocatedRes = allocations.getResourceAllocation(link);
Sho SHIMIZU716c8e92015-07-02 11:35:34 -0700289 Set<ResourceRequest> result = Sets.newHashSet(getAvailableResources(link));
weibit00c94f52014-11-16 07:09:05 -0800290 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}