blob: 6b02edd9553669cbfbb1c5856ce7b7fe8d1bcf39 [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;
Simon Huntff663742015-05-14 13:33:05 -070024import org.onosproject.event.ListenerRegistry;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.event.EventDeliveryService;
26import org.onosproject.net.Link;
27import org.onosproject.net.intent.IntentId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070028import org.onosproject.net.resource.link.BandwidthResourceAllocation;
29import org.onosproject.net.resource.link.BandwidthResourceRequest;
30import org.onosproject.net.resource.link.DefaultLinkResourceAllocations;
31import org.onosproject.net.resource.link.LambdaResource;
32import org.onosproject.net.resource.link.LambdaResourceAllocation;
33import org.onosproject.net.resource.link.LambdaResourceRequest;
34import org.onosproject.net.resource.link.LinkResourceAllocations;
35import org.onosproject.net.resource.link.LinkResourceEvent;
36import org.onosproject.net.resource.link.LinkResourceListener;
37import org.onosproject.net.resource.link.LinkResourceRequest;
38import org.onosproject.net.resource.link.LinkResourceService;
39import org.onosproject.net.resource.link.LinkResourceStore;
40import org.onosproject.net.resource.link.LinkResourceStoreDelegate;
41import org.onosproject.net.resource.link.MplsLabel;
42import org.onosproject.net.resource.link.MplsLabelResourceAllocation;
43import org.onosproject.net.resource.link.MplsLabelResourceRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.resource.ResourceAllocation;
45import org.onosproject.net.resource.ResourceRequest;
46import org.onosproject.net.resource.ResourceType;
Toshio Koide50df38d2014-10-23 10:36:51 -070047import org.slf4j.Logger;
48
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080049import java.util.Collections;
50import java.util.HashMap;
51import java.util.HashSet;
52import java.util.Iterator;
53import java.util.Map;
54import java.util.Set;
55
56import static com.google.common.base.Preconditions.checkArgument;
57import static com.google.common.base.Preconditions.checkNotNull;
58import static org.slf4j.LoggerFactory.getLogger;
59
Toshio Koide50df38d2014-10-23 10:36:51 -070060/**
61 * Provides basic implementation of link resources allocation.
62 */
63@Component(immediate = true)
64@Service
65public class LinkResourceManager implements LinkResourceService {
66
67 private final Logger log = getLogger(getClass());
68
Simon Huntff663742015-05-14 13:33:05 -070069 protected final ListenerRegistry<LinkResourceEvent, LinkResourceListener>
70 listenerRegistry = new ListenerRegistry<>();
Ray Milkeye97ede92014-11-20 10:43:12 -080071
Toshio Koide106d4492014-10-28 11:22:02 -070072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 private LinkResourceStore store;
Ray Milkeycaa450b2014-10-29 15:54:24 -070074
Ray Milkeye97ede92014-11-20 10:43:12 -080075 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected EventDeliveryService eventDispatcher;
77
Toshio Koide50df38d2014-10-23 10:36:51 -070078 @Activate
79 public void activate() {
Ray Milkeye97ede92014-11-20 10:43:12 -080080 eventDispatcher.addSink(LinkResourceEvent.class, listenerRegistry);
Toshio Koide50df38d2014-10-23 10:36:51 -070081 log.info("Started");
82 }
83
84 @Deactivate
85 public void deactivate() {
86 log.info("Stopped");
87 }
88
Toshio Koide106d4492014-10-28 11:22:02 -070089 /**
90 * Returns available lambdas on specified link.
91 *
92 * @param link the link
93 * @return available lambdas on specified link
94 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -070095 private Set<LambdaResource> getAvailableLambdas(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -070096 checkNotNull(link);
97 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
98 if (resAllocs == null) {
99 return Collections.emptySet();
100 }
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700101 Set<LambdaResource> lambdas = new HashSet<>();
Toshio Koide106d4492014-10-28 11:22:02 -0700102 for (ResourceAllocation res : resAllocs) {
103 if (res.type() == ResourceType.LAMBDA) {
104 lambdas.add(((LambdaResourceAllocation) res).lambda());
105 }
106 }
107 return lambdas;
Toshio Koide9be539e2014-10-23 18:43:30 -0700108 }
109
Michele Santuari4b6019e2014-12-19 11:31:45 +0100110
Toshio Koide106d4492014-10-28 11:22:02 -0700111 /**
112 * Returns available lambdas on specified links.
113 *
114 * @param links the links
115 * @return available lambdas on specified links
116 */
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700117 private Iterable<LambdaResource> getAvailableLambdas(Iterable<Link> links) {
Toshio Koide106d4492014-10-28 11:22:02 -0700118 checkNotNull(links);
119 Iterator<Link> i = links.iterator();
120 checkArgument(i.hasNext());
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700121 Set<LambdaResource> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
Toshio Koide106d4492014-10-28 11:22:02 -0700122 while (i.hasNext()) {
123 lambdas.retainAll(getAvailableLambdas(i.next()));
124 }
125 return lambdas;
126 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700127
Michele Santuari4b6019e2014-12-19 11:31:45 +0100128
129 /**
130 * Returns available MPLS label on specified link.
131 *
132 * @param link the link
133 * @return available MPLS labels on specified link
134 */
135 private Iterable<MplsLabel> getAvailableMplsLabels(Link link) {
136 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
137 if (resAllocs == null) {
138 return Collections.emptySet();
139 }
140 Set<MplsLabel> mplsLabels = new HashSet<>();
141 for (ResourceAllocation res : resAllocs) {
142 if (res.type() == ResourceType.MPLS_LABEL) {
143
144 mplsLabels.add(((MplsLabelResourceAllocation) res).mplsLabel());
145 }
146 }
147
148 return mplsLabels;
149 }
150
Toshio Koide50df38d2014-10-23 10:36:51 -0700151 @Override
152 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
Toshio Koide106d4492014-10-28 11:22:02 -0700153 // TODO Concatenate multiple bandwidth requests.
154 // TODO Support multiple lambda resource requests.
155 // TODO Throw appropriate exception.
Toshio Koide106d4492014-10-28 11:22:02 -0700156 Set<ResourceAllocation> allocs = new HashSet<>();
Michele Santuari4b6019e2014-12-19 11:31:45 +0100157 Map<Link, Set<ResourceAllocation>> allocsPerLink = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700158 for (ResourceRequest r : req.resources()) {
Toshio Koideca0fcff2014-10-23 14:08:36 -0700159 switch (r.type()) {
160 case BANDWIDTH:
Toshio Koideca0fcff2014-10-23 14:08:36 -0700161 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
Toshio Koide106d4492014-10-28 11:22:02 -0700162 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
Toshio Koideca0fcff2014-10-23 14:08:36 -0700163 break;
164 case LAMBDA:
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700165 Iterator<LambdaResource> lambdaIterator =
Toshio Koide106d4492014-10-28 11:22:02 -0700166 getAvailableLambdas(req.links()).iterator();
Toshio Koide9be539e2014-10-23 18:43:30 -0700167 if (lambdaIterator.hasNext()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700168 allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
169 } else {
170 log.info("Failed to allocate lambda resource.");
171 return null;
Toshio Koide9be539e2014-10-23 18:43:30 -0700172 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700173 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100174 case MPLS_LABEL:
175 for (Link link : req.links()) {
176 if (allocsPerLink.get(link) == null) {
177 allocsPerLink.put(link,
178 new HashSet<ResourceAllocation>());
179 }
180 Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link)
181 .iterator();
182 if (mplsIter.hasNext()) {
183 allocsPerLink.get(link)
184 .add(new MplsLabelResourceAllocation(mplsIter
185 .next()));
186 } else {
187 log.info("Failed to allocate MPLS resource.");
188 break;
189 }
190 }
191 break;
Toshio Koideca0fcff2014-10-23 14:08:36 -0700192 default:
193 break;
194 }
195 }
196
197 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700198 for (Link link : req.links()) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100199 allocations.put(link, new HashSet<ResourceAllocation>(allocs));
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800200 Set<ResourceAllocation> linkAllocs = allocsPerLink.get(link);
201 if (linkAllocs != null) {
202 allocations.get(link).addAll(linkAllocs);
203 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700204 }
Toshio Koide106d4492014-10-28 11:22:02 -0700205 LinkResourceAllocations result =
206 new DefaultLinkResourceAllocations(req, allocations);
207 store.allocateResources(result);
208 return result;
209
Toshio Koide50df38d2014-10-23 10:36:51 -0700210 }
211
212 @Override
213 public void releaseResources(LinkResourceAllocations allocations) {
Ray Milkeye97ede92014-11-20 10:43:12 -0800214 final LinkResourceEvent event = store.releaseResources(allocations);
215 if (event != null) {
216 post(event);
217 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700218 }
219
220 @Override
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700221 public LinkResourceAllocations updateResources(LinkResourceRequest req,
Toshio Koide106d4492014-10-28 11:22:02 -0700222 LinkResourceAllocations oldAllocations) {
weibit00c94f52014-11-16 07:09:05 -0800223 releaseResources(oldAllocations);
224 return requestResources(req);
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700225 }
226
227 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700228 public Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700229 return store.getAllocations();
Toshio Koide50df38d2014-10-23 10:36:51 -0700230 }
231
232 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700233 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700234 return store.getAllocations(link);
Toshio Koide50df38d2014-10-23 10:36:51 -0700235 }
236
237 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700238 public LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700239 return store.getAllocations(intentId);
Toshio Koide50df38d2014-10-23 10:36:51 -0700240 }
241
242 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700243 public Iterable<ResourceRequest> getAvailableResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700244 Set<ResourceAllocation> freeRes = store.getFreeResources(link);
245 Set<ResourceRequest> result = new HashSet<>();
246 for (ResourceAllocation alloc : freeRes) {
247 switch (alloc.type()) {
248 case BANDWIDTH:
249 result.add(new BandwidthResourceRequest(
250 ((BandwidthResourceAllocation) alloc).bandwidth()));
251 break;
252 case LAMBDA:
253 result.add(new LambdaResourceRequest());
254 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100255 case MPLS_LABEL:
256 result.add(new MplsLabelResourceRequest());
Sho SHIMIZU3fa9e8d2015-05-05 11:40:04 -0700257 break;
Toshio Koide106d4492014-10-28 11:22:02 -0700258 default:
259 break;
260 }
261 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700262 return result;
Toshio Koide50df38d2014-10-23 10:36:51 -0700263 }
264
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700265 @Override
weibit00c94f52014-11-16 07:09:05 -0800266 public Iterable<ResourceRequest> getAvailableResources(Link link,
Toshio Koide106d4492014-10-28 11:22:02 -0700267 LinkResourceAllocations allocations) {
weibit00c94f52014-11-16 07:09:05 -0800268 Set<ResourceRequest> result = new HashSet<>();
269 Set<ResourceAllocation> allocatedRes = allocations.getResourceAllocation(link);
270 result = (Set<ResourceRequest>) getAvailableResources(link);
271 result.addAll(allocatedRes);
272 return result;
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700273 }
274
Ray Milkeye97ede92014-11-20 10:43:12 -0800275 @Override
276 public void addListener(LinkResourceListener listener) {
277 listenerRegistry.addListener(listener);
278 }
279
280 @Override
281 public void removeListener(LinkResourceListener listener) {
282 listenerRegistry.removeListener(listener);
283 }
284
285 /**
286 * Posts the specified event to the local event dispatcher.
287 */
288 private void post(LinkResourceEvent event) {
289 if (event != null) {
290 eventDispatcher.post(event);
291 }
292 }
293
294 /**
295 * Store delegate to re-post events emitted from the store.
296 */
297 private class InternalStoreDelegate implements LinkResourceStoreDelegate {
298 @Override
299 public void notify(LinkResourceEvent event) {
300 post(event);
301 }
302 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700303}