blob: 5762c0a14887d52b41053578a1f90117028afe6e [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;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070025import org.onosproject.event.AbstractListenerManager;
Changhoon Yoon541ef712015-05-23 17:18:34 +090026import org.onosproject.core.Permission;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.Link;
28import org.onosproject.net.intent.IntentId;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070029import org.onosproject.net.resource.ResourceAllocation;
30import org.onosproject.net.resource.ResourceRequest;
31import org.onosproject.net.resource.ResourceType;
Brian O'Connor6de2e202015-05-21 14:30:41 -070032import org.onosproject.net.resource.link.BandwidthResourceAllocation;
33import org.onosproject.net.resource.link.BandwidthResourceRequest;
34import org.onosproject.net.resource.link.DefaultLinkResourceAllocations;
35import org.onosproject.net.resource.link.LambdaResource;
36import org.onosproject.net.resource.link.LambdaResourceAllocation;
37import org.onosproject.net.resource.link.LambdaResourceRequest;
38import org.onosproject.net.resource.link.LinkResourceAllocations;
39import org.onosproject.net.resource.link.LinkResourceEvent;
40import org.onosproject.net.resource.link.LinkResourceListener;
41import org.onosproject.net.resource.link.LinkResourceRequest;
42import org.onosproject.net.resource.link.LinkResourceService;
43import org.onosproject.net.resource.link.LinkResourceStore;
44import org.onosproject.net.resource.link.LinkResourceStoreDelegate;
45import org.onosproject.net.resource.link.MplsLabel;
46import org.onosproject.net.resource.link.MplsLabelResourceAllocation;
47import org.onosproject.net.resource.link.MplsLabelResourceRequest;
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;
Changhoon Yoon541ef712015-05-23 17:18:34 +090059import static org.onosproject.security.AppGuard.checkPermission;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070060import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoon541ef712015-05-23 17:18:34 +090061
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
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070068public class LinkResourceManager
69 extends AbstractListenerManager<LinkResourceEvent, LinkResourceListener>
70 implements LinkResourceService {
Toshio Koide50df38d2014-10-23 10:36:51 -070071
72 private final Logger log = getLogger(getClass());
73
Toshio Koide106d4492014-10-28 11:22:02 -070074 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 private LinkResourceStore store;
Ray Milkeycaa450b2014-10-29 15:54:24 -070076
Toshio Koide50df38d2014-10-23 10:36:51 -070077 @Activate
78 public void activate() {
Ray Milkeye97ede92014-11-20 10:43:12 -080079 eventDispatcher.addSink(LinkResourceEvent.class, listenerRegistry);
Toshio Koide50df38d2014-10-23 10:36:51 -070080 log.info("Started");
81 }
82
83 @Deactivate
84 public void deactivate() {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070085 eventDispatcher.removeSink(LinkResourceEvent.class);
Toshio Koide50df38d2014-10-23 10:36:51 -070086 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) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900153 checkPermission(Permission.LINK_WRITE);
154
Toshio Koide106d4492014-10-28 11:22:02 -0700155 // TODO Concatenate multiple bandwidth requests.
156 // TODO Support multiple lambda resource requests.
157 // TODO Throw appropriate exception.
Toshio Koide106d4492014-10-28 11:22:02 -0700158 Set<ResourceAllocation> allocs = new HashSet<>();
Michele Santuari4b6019e2014-12-19 11:31:45 +0100159 Map<Link, Set<ResourceAllocation>> allocsPerLink = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700160 for (ResourceRequest r : req.resources()) {
Toshio Koideca0fcff2014-10-23 14:08:36 -0700161 switch (r.type()) {
162 case BANDWIDTH:
Toshio Koideca0fcff2014-10-23 14:08:36 -0700163 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
Toshio Koide106d4492014-10-28 11:22:02 -0700164 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
Toshio Koideca0fcff2014-10-23 14:08:36 -0700165 break;
166 case LAMBDA:
Sho SHIMIZU94b7ff42015-05-06 17:51:49 -0700167 Iterator<LambdaResource> lambdaIterator =
Toshio Koide106d4492014-10-28 11:22:02 -0700168 getAvailableLambdas(req.links()).iterator();
Toshio Koide9be539e2014-10-23 18:43:30 -0700169 if (lambdaIterator.hasNext()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700170 allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
171 } else {
172 log.info("Failed to allocate lambda resource.");
173 return null;
Toshio Koide9be539e2014-10-23 18:43:30 -0700174 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700175 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100176 case MPLS_LABEL:
177 for (Link link : req.links()) {
178 if (allocsPerLink.get(link) == null) {
179 allocsPerLink.put(link,
180 new HashSet<ResourceAllocation>());
181 }
182 Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link)
183 .iterator();
184 if (mplsIter.hasNext()) {
185 allocsPerLink.get(link)
186 .add(new MplsLabelResourceAllocation(mplsIter
187 .next()));
188 } else {
189 log.info("Failed to allocate MPLS resource.");
190 break;
191 }
192 }
193 break;
Toshio Koideca0fcff2014-10-23 14:08:36 -0700194 default:
195 break;
196 }
197 }
198
199 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700200 for (Link link : req.links()) {
Michele Santuari4b6019e2014-12-19 11:31:45 +0100201 allocations.put(link, new HashSet<ResourceAllocation>(allocs));
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800202 Set<ResourceAllocation> linkAllocs = allocsPerLink.get(link);
203 if (linkAllocs != null) {
204 allocations.get(link).addAll(linkAllocs);
205 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700206 }
Toshio Koide106d4492014-10-28 11:22:02 -0700207 LinkResourceAllocations result =
208 new DefaultLinkResourceAllocations(req, allocations);
209 store.allocateResources(result);
210 return result;
211
Toshio Koide50df38d2014-10-23 10:36:51 -0700212 }
213
214 @Override
215 public void releaseResources(LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900216 checkPermission(Permission.LINK_WRITE);
Ray Milkeye97ede92014-11-20 10:43:12 -0800217 final LinkResourceEvent event = store.releaseResources(allocations);
218 if (event != null) {
219 post(event);
220 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700221 }
222
223 @Override
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700224 public LinkResourceAllocations updateResources(LinkResourceRequest req,
Toshio Koide106d4492014-10-28 11:22:02 -0700225 LinkResourceAllocations oldAllocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900226 checkPermission(Permission.LINK_WRITE);
Changhoon Yoon541ef712015-05-23 17:18:34 +0900227 releaseResources(oldAllocations);
weibit00c94f52014-11-16 07:09:05 -0800228 return requestResources(req);
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700229 }
230
231 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700232 public Iterable<LinkResourceAllocations> getAllocations() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900233 checkPermission(Permission.LINK_READ);
Toshio Koide106d4492014-10-28 11:22:02 -0700234 return store.getAllocations();
Toshio Koide50df38d2014-10-23 10:36:51 -0700235 }
236
237 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700238 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900239 checkPermission(Permission.LINK_READ);
Toshio Koide106d4492014-10-28 11:22:02 -0700240 return store.getAllocations(link);
Toshio Koide50df38d2014-10-23 10:36:51 -0700241 }
242
243 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700244 public LinkResourceAllocations getAllocations(IntentId intentId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900245 checkPermission(Permission.LINK_READ);
Toshio Koide106d4492014-10-28 11:22:02 -0700246 return store.getAllocations(intentId);
Toshio Koide50df38d2014-10-23 10:36:51 -0700247 }
248
249 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700250 public Iterable<ResourceRequest> getAvailableResources(Link link) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900251 checkPermission(Permission.LINK_READ);
252
Toshio Koide106d4492014-10-28 11:22:02 -0700253 Set<ResourceAllocation> freeRes = store.getFreeResources(link);
254 Set<ResourceRequest> result = new HashSet<>();
255 for (ResourceAllocation alloc : freeRes) {
256 switch (alloc.type()) {
257 case BANDWIDTH:
258 result.add(new BandwidthResourceRequest(
259 ((BandwidthResourceAllocation) alloc).bandwidth()));
260 break;
261 case LAMBDA:
262 result.add(new LambdaResourceRequest());
263 break;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100264 case MPLS_LABEL:
265 result.add(new MplsLabelResourceRequest());
Sho SHIMIZU3fa9e8d2015-05-05 11:40:04 -0700266 break;
Toshio Koide106d4492014-10-28 11:22:02 -0700267 default:
268 break;
269 }
270 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700271 return result;
Toshio Koide50df38d2014-10-23 10:36:51 -0700272 }
273
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700274 @Override
weibit00c94f52014-11-16 07:09:05 -0800275 public Iterable<ResourceRequest> getAvailableResources(Link link,
Toshio Koide106d4492014-10-28 11:22:02 -0700276 LinkResourceAllocations allocations) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900277 checkPermission(Permission.LINK_READ);
278
weibit00c94f52014-11-16 07:09:05 -0800279 Set<ResourceAllocation> allocatedRes = allocations.getResourceAllocation(link);
Sho SHIMIZU716c8e92015-07-02 11:35:34 -0700280 Set<ResourceRequest> result = Sets.newHashSet(getAvailableResources(link));
Sho SHIMIZUc6154852015-07-02 11:53:10 -0700281 result.removeAll(allocatedRes);
weibit00c94f52014-11-16 07:09:05 -0800282 return result;
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700283 }
284
Ray Milkeye97ede92014-11-20 10:43:12 -0800285 /**
286 * Store delegate to re-post events emitted from the store.
287 */
288 private class InternalStoreDelegate implements LinkResourceStoreDelegate {
289 @Override
290 public void notify(LinkResourceEvent event) {
291 post(event);
292 }
293 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700294}