blob: 9f5d763b569afc48300159eda1999c53475417ca [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -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 */
Toshio Koide5c0a7262014-10-23 14:50:21 -070016package org.onlab.onos.net.resource.impl;
Toshio Koide50df38d2014-10-23 10:36:51 -070017
Toshio Koide106d4492014-10-28 11:22:02 -070018import static com.google.common.base.Preconditions.checkArgument;
19import static com.google.common.base.Preconditions.checkNotNull;
Toshio Koide50df38d2014-10-23 10:36:51 -070020import static org.slf4j.LoggerFactory.getLogger;
21
Toshio Koide106d4492014-10-28 11:22:02 -070022import java.util.Collections;
Toshio Koideca0fcff2014-10-23 14:08:36 -070023import java.util.HashMap;
Toshio Koide106d4492014-10-28 11:22:02 -070024import java.util.HashSet;
Toshio Koide9be539e2014-10-23 18:43:30 -070025import java.util.Iterator;
Toshio Koideca0fcff2014-10-23 14:08:36 -070026import java.util.Map;
27import java.util.Set;
28
Toshio Koide50df38d2014-10-23 10:36:51 -070029import org.apache.felix.scr.annotations.Activate;
30import org.apache.felix.scr.annotations.Component;
31import org.apache.felix.scr.annotations.Deactivate;
Toshio Koide106d4492014-10-28 11:22:02 -070032import org.apache.felix.scr.annotations.Reference;
33import org.apache.felix.scr.annotations.ReferenceCardinality;
Toshio Koide50df38d2014-10-23 10:36:51 -070034import org.apache.felix.scr.annotations.Service;
Ray Milkeye97ede92014-11-20 10:43:12 -080035import org.onlab.onos.event.AbstractListenerRegistry;
36import org.onlab.onos.event.EventDeliveryService;
Toshio Koide50df38d2014-10-23 10:36:51 -070037import org.onlab.onos.net.Link;
38import org.onlab.onos.net.intent.IntentId;
Toshio Koide5c0a7262014-10-23 14:50:21 -070039import org.onlab.onos.net.resource.BandwidthResourceAllocation;
40import org.onlab.onos.net.resource.BandwidthResourceRequest;
Yuta HIGUCHIadac04a2014-11-13 00:02:45 -080041import org.onlab.onos.net.resource.DefaultLinkResourceAllocations;
Toshio Koide5c0a7262014-10-23 14:50:21 -070042import org.onlab.onos.net.resource.Lambda;
43import org.onlab.onos.net.resource.LambdaResourceAllocation;
Toshio Koide106d4492014-10-28 11:22:02 -070044import org.onlab.onos.net.resource.LambdaResourceRequest;
Toshio Koide5c0a7262014-10-23 14:50:21 -070045import org.onlab.onos.net.resource.LinkResourceAllocations;
Ray Milkeye97ede92014-11-20 10:43:12 -080046import org.onlab.onos.net.resource.LinkResourceEvent;
47import org.onlab.onos.net.resource.LinkResourceListener;
Toshio Koide5c0a7262014-10-23 14:50:21 -070048import org.onlab.onos.net.resource.LinkResourceRequest;
49import org.onlab.onos.net.resource.LinkResourceService;
Toshio Koide106d4492014-10-28 11:22:02 -070050import org.onlab.onos.net.resource.LinkResourceStore;
Ray Milkeye97ede92014-11-20 10:43:12 -080051import org.onlab.onos.net.resource.LinkResourceStoreDelegate;
Toshio Koide5c0a7262014-10-23 14:50:21 -070052import org.onlab.onos.net.resource.ResourceAllocation;
53import org.onlab.onos.net.resource.ResourceRequest;
Toshio Koide106d4492014-10-28 11:22:02 -070054import org.onlab.onos.net.resource.ResourceType;
Toshio Koide50df38d2014-10-23 10:36:51 -070055import org.slf4j.Logger;
56
57/**
58 * Provides basic implementation of link resources allocation.
59 */
60@Component(immediate = true)
61@Service
62public class LinkResourceManager implements LinkResourceService {
63
64 private final Logger log = getLogger(getClass());
65
Ray Milkeye97ede92014-11-20 10:43:12 -080066 protected final AbstractListenerRegistry<LinkResourceEvent, LinkResourceListener>
67 listenerRegistry = new AbstractListenerRegistry<>();
68
Toshio Koide106d4492014-10-28 11:22:02 -070069 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 private LinkResourceStore store;
Ray Milkeycaa450b2014-10-29 15:54:24 -070071
Ray Milkeye97ede92014-11-20 10:43:12 -080072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected EventDeliveryService eventDispatcher;
74
Toshio Koide50df38d2014-10-23 10:36:51 -070075 @Activate
76 public void activate() {
Ray Milkeye97ede92014-11-20 10:43:12 -080077 eventDispatcher.addSink(LinkResourceEvent.class, listenerRegistry);
Toshio Koide50df38d2014-10-23 10:36:51 -070078 log.info("Started");
79 }
80
81 @Deactivate
82 public void deactivate() {
83 log.info("Stopped");
84 }
85
Toshio Koide106d4492014-10-28 11:22:02 -070086 /**
87 * Returns available lambdas on specified link.
88 *
89 * @param link the link
90 * @return available lambdas on specified link
91 */
92 private Set<Lambda> getAvailableLambdas(Link link) {
93 checkNotNull(link);
94 Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
95 if (resAllocs == null) {
96 return Collections.emptySet();
97 }
98 Set<Lambda> lambdas = new HashSet<>();
99 for (ResourceAllocation res : resAllocs) {
100 if (res.type() == ResourceType.LAMBDA) {
101 lambdas.add(((LambdaResourceAllocation) res).lambda());
102 }
103 }
104 return lambdas;
Toshio Koide9be539e2014-10-23 18:43:30 -0700105 }
106
Toshio Koide106d4492014-10-28 11:22:02 -0700107 /**
108 * Returns available lambdas on specified links.
109 *
110 * @param links the links
111 * @return available lambdas on specified links
112 */
113 private Iterable<Lambda> getAvailableLambdas(Iterable<Link> links) {
114 checkNotNull(links);
115 Iterator<Link> i = links.iterator();
116 checkArgument(i.hasNext());
117 Set<Lambda> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
118 while (i.hasNext()) {
119 lambdas.retainAll(getAvailableLambdas(i.next()));
120 }
121 return lambdas;
122 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700123
Toshio Koide50df38d2014-10-23 10:36:51 -0700124 @Override
125 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
Toshio Koide106d4492014-10-28 11:22:02 -0700126 // TODO Concatenate multiple bandwidth requests.
127 // TODO Support multiple lambda resource requests.
128 // TODO Throw appropriate exception.
Toshio Koideca0fcff2014-10-23 14:08:36 -0700129
Toshio Koide106d4492014-10-28 11:22:02 -0700130 Set<ResourceAllocation> allocs = new HashSet<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700131 for (ResourceRequest r : req.resources()) {
Toshio Koideca0fcff2014-10-23 14:08:36 -0700132 switch (r.type()) {
133 case BANDWIDTH:
Toshio Koideca0fcff2014-10-23 14:08:36 -0700134 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
Toshio Koide106d4492014-10-28 11:22:02 -0700135 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
Toshio Koideca0fcff2014-10-23 14:08:36 -0700136 break;
137 case LAMBDA:
Toshio Koide106d4492014-10-28 11:22:02 -0700138 Iterator<Lambda> lambdaIterator =
139 getAvailableLambdas(req.links()).iterator();
Toshio Koide9be539e2014-10-23 18:43:30 -0700140 if (lambdaIterator.hasNext()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700141 allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
142 } else {
143 log.info("Failed to allocate lambda resource.");
144 return null;
Toshio Koide9be539e2014-10-23 18:43:30 -0700145 }
Toshio Koideca0fcff2014-10-23 14:08:36 -0700146 break;
147 default:
148 break;
149 }
150 }
151
152 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
Toshio Koide9be539e2014-10-23 18:43:30 -0700153 for (Link link : req.links()) {
Toshio Koide106d4492014-10-28 11:22:02 -0700154 allocations.put(link, allocs);
Toshio Koideca0fcff2014-10-23 14:08:36 -0700155 }
Toshio Koide106d4492014-10-28 11:22:02 -0700156 LinkResourceAllocations result =
157 new DefaultLinkResourceAllocations(req, allocations);
158 store.allocateResources(result);
159 return result;
160
Toshio Koide50df38d2014-10-23 10:36:51 -0700161 }
162
163 @Override
164 public void releaseResources(LinkResourceAllocations allocations) {
Ray Milkeye97ede92014-11-20 10:43:12 -0800165 final LinkResourceEvent event = store.releaseResources(allocations);
166 if (event != null) {
167 post(event);
168 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700169 }
170
171 @Override
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700172 public LinkResourceAllocations updateResources(LinkResourceRequest req,
Toshio Koide106d4492014-10-28 11:22:02 -0700173 LinkResourceAllocations oldAllocations) {
weibit00c94f52014-11-16 07:09:05 -0800174 releaseResources(oldAllocations);
175 return requestResources(req);
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700176 }
177
178 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700179 public Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700180 return store.getAllocations();
Toshio Koide50df38d2014-10-23 10:36:51 -0700181 }
182
183 @Override
Toshio Koide50df38d2014-10-23 10:36:51 -0700184 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700185 return store.getAllocations(link);
Toshio Koide50df38d2014-10-23 10:36:51 -0700186 }
187
188 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700189 public LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700190 return store.getAllocations(intentId);
Toshio Koide50df38d2014-10-23 10:36:51 -0700191 }
192
193 @Override
Toshio Koide9be539e2014-10-23 18:43:30 -0700194 public Iterable<ResourceRequest> getAvailableResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700195 Set<ResourceAllocation> freeRes = store.getFreeResources(link);
196 Set<ResourceRequest> result = new HashSet<>();
197 for (ResourceAllocation alloc : freeRes) {
198 switch (alloc.type()) {
199 case BANDWIDTH:
200 result.add(new BandwidthResourceRequest(
201 ((BandwidthResourceAllocation) alloc).bandwidth()));
202 break;
203 case LAMBDA:
204 result.add(new LambdaResourceRequest());
205 break;
206 default:
207 break;
208 }
209 }
Ray Milkeycaa450b2014-10-29 15:54:24 -0700210 return result;
Toshio Koide50df38d2014-10-23 10:36:51 -0700211 }
212
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700213 @Override
weibit00c94f52014-11-16 07:09:05 -0800214 public Iterable<ResourceRequest> getAvailableResources(Link link,
Toshio Koide106d4492014-10-28 11:22:02 -0700215 LinkResourceAllocations allocations) {
weibit00c94f52014-11-16 07:09:05 -0800216 Set<ResourceRequest> result = new HashSet<>();
217 Set<ResourceAllocation> allocatedRes = allocations.getResourceAllocation(link);
218 result = (Set<ResourceRequest>) getAvailableResources(link);
219 result.addAll(allocatedRes);
220 return result;
Thomas Vachuskaf9976952014-10-24 11:55:05 -0700221 }
222
Ray Milkeye97ede92014-11-20 10:43:12 -0800223 @Override
224 public void addListener(LinkResourceListener listener) {
225 listenerRegistry.addListener(listener);
226 }
227
228 @Override
229 public void removeListener(LinkResourceListener listener) {
230 listenerRegistry.removeListener(listener);
231 }
232
233 /**
234 * Posts the specified event to the local event dispatcher.
235 */
236 private void post(LinkResourceEvent event) {
237 if (event != null) {
238 eventDispatcher.post(event);
239 }
240 }
241
242 /**
243 * Store delegate to re-post events emitted from the store.
244 */
245 private class InternalStoreDelegate implements LinkResourceStoreDelegate {
246 @Override
247 public void notify(LinkResourceEvent event) {
248 post(event);
249 }
250 }
Toshio Koide50df38d2014-10-23 10:36:51 -0700251}