blob: 78cd341b102f0a0dd15f8c6f820df6ce95f6a361 [file] [log] [blame]
Toshio Koide106d4492014-10-28 11:22:02 -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 */
16package org.onlab.onos.store.trivial.impl;
17
Toshio Koide69e52572014-10-30 11:14:09 -070018import static com.google.common.base.Preconditions.checkNotNull;
19import static com.google.common.base.Preconditions.checkState;
Toshio Koide106d4492014-10-28 11:22:02 -070020import static org.slf4j.LoggerFactory.getLogger;
21
22import java.util.Collections;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.Map;
26import java.util.Set;
27
28import org.apache.felix.scr.annotations.Activate;
29import org.apache.felix.scr.annotations.Component;
30import org.apache.felix.scr.annotations.Deactivate;
31import org.apache.felix.scr.annotations.Service;
32import org.onlab.onos.net.Link;
33import org.onlab.onos.net.intent.IntentId;
34import org.onlab.onos.net.resource.Bandwidth;
35import org.onlab.onos.net.resource.BandwidthResourceAllocation;
36import org.onlab.onos.net.resource.Lambda;
37import org.onlab.onos.net.resource.LambdaResourceAllocation;
38import org.onlab.onos.net.resource.LinkResourceAllocations;
39import org.onlab.onos.net.resource.LinkResourceStore;
40import org.onlab.onos.net.resource.ResourceAllocation;
41import org.onlab.onos.net.resource.ResourceType;
42import org.slf4j.Logger;
43
44/**
45 * Manages link resources using trivial in-memory structures implementation.
46 */
47@Component(immediate = true)
48@Service
49public class SimpleLinkResourceStore implements LinkResourceStore {
50 private final Logger log = getLogger(getClass());
51 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
52 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
53 private Map<Link, Set<ResourceAllocation>> freeResources;
54
55 @Activate
56 public void activate() {
57 linkResourceAllocationsMap = new HashMap<>();
58 allocatedResources = new HashMap<>();
59 freeResources = new HashMap<>();
60
61 log.info("Started");
62 }
63
64 @Deactivate
65 public void deactivate() {
66 log.info("Stopped");
67 }
68
Toshio Koide69e52572014-10-30 11:14:09 -070069 /**
70 * Returns free resources for a given link obtaining from topology
71 * information.
72 *
73 * @param link the target link
74 * @return free resources
75 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080076 private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -070077 // TODO read capacity and lambda resources from topology
78 Set<ResourceAllocation> allocations = new HashSet<>();
79 for (int i = 1; i <= 100; i++) {
80 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
81 }
82 allocations.add(new BandwidthResourceAllocation(Bandwidth.valueOf(1000000)));
83 return allocations;
84 }
85
Toshio Koide69e52572014-10-30 11:14:09 -070086 /**
87 * Finds and returns {@link BandwidthResourceAllocation} object from a given
88 * set.
89 *
90 * @param freeRes a set of ResourceAllocation object.
91 * @return {@link BandwidthResourceAllocation} object if found, otherwise
92 * {@link BandwidthResourceAllocation} object with 0 bandwidth
93 *
94 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -080095 private synchronized BandwidthResourceAllocation getBandwidth(Set<ResourceAllocation> freeRes) {
Toshio Koide106d4492014-10-28 11:22:02 -070096 for (ResourceAllocation res : freeRes) {
97 if (res.type() == ResourceType.BANDWIDTH) {
98 return (BandwidthResourceAllocation) res;
99 }
100 }
101 return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
102 }
103
Toshio Koide69e52572014-10-30 11:14:09 -0700104 /**
105 * Subtracts given resources from free resources for given link.
106 *
107 * @param link the target link
108 * @param allocations the resources to be subtracted
109 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800110 private synchronized void subtractFreeResources(Link link, LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700111 // TODO Use lock or version for updating freeResources.
112 checkNotNull(link);
Toshio Koide69e52572014-10-30 11:14:09 -0700113 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700114 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
115 for (ResourceAllocation res : subRes) {
116 switch (res.type()) {
117 case BANDWIDTH:
118 BandwidthResourceAllocation ba = getBandwidth(freeRes);
119 double requestedBandwidth =
120 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
121 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
122 checkState(newBandwidth >= 0.0);
123 freeRes.remove(ba);
124 freeRes.add(new BandwidthResourceAllocation(
125 Bandwidth.valueOf(newBandwidth)));
126 break;
127 case LAMBDA:
128 checkState(freeRes.remove(res));
129 break;
130 default:
131 break;
132 }
133 }
134 freeResources.put(link, freeRes);
135
136 }
137
Toshio Koide69e52572014-10-30 11:14:09 -0700138 /**
139 * Adds given resources to free resources for given link.
140 *
141 * @param link the target link
142 * @param allocations the resources to be added
143 */
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800144 private synchronized void addFreeResources(Link link, LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700145 // TODO Use lock or version for updating freeResources.
Toshio Koide69e52572014-10-30 11:14:09 -0700146 Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
Toshio Koide106d4492014-10-28 11:22:02 -0700147 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
148 for (ResourceAllocation res : addRes) {
149 switch (res.type()) {
150 case BANDWIDTH:
151 BandwidthResourceAllocation ba = getBandwidth(freeRes);
152 double requestedBandwidth =
153 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
154 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
155 freeRes.remove(ba);
156 freeRes.add(new BandwidthResourceAllocation(
157 Bandwidth.valueOf(newBandwidth)));
158 break;
159 case LAMBDA:
160 checkState(freeRes.add(res));
161 break;
162 default:
163 break;
164 }
165 }
166 freeResources.put(link, freeRes);
167 }
168
169 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800170 public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700171 checkNotNull(link);
172 Set<ResourceAllocation> freeRes = freeResources.get(link);
173 if (freeRes == null) {
174 freeRes = readOriginalFreeResources(link);
175 }
176
177 return freeRes;
178 }
179
180 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800181 public synchronized void allocateResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700182 checkNotNull(allocations);
183 linkResourceAllocationsMap.put(allocations.intendId(), allocations);
184 for (Link link : allocations.links()) {
185 subtractFreeResources(link, allocations);
186 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
187 if (linkAllocs == null) {
188 linkAllocs = new HashSet<>();
189 }
190 linkAllocs.add(allocations);
191 allocatedResources.put(link, linkAllocs);
192 }
193 }
194
195 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800196 public synchronized void releaseResources(LinkResourceAllocations allocations) {
Toshio Koide106d4492014-10-28 11:22:02 -0700197 checkNotNull(allocations);
Yuta HIGUCHIc9c9e222014-11-04 09:17:08 -0800198 linkResourceAllocationsMap.remove(allocations.intendId());
Toshio Koide106d4492014-10-28 11:22:02 -0700199 for (Link link : allocations.links()) {
200 addFreeResources(link, allocations);
201 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
202 if (linkAllocs == null) {
203 log.error("Missing resource allocation.");
204 } else {
205 linkAllocs.remove(allocations);
206 }
207 allocatedResources.put(link, linkAllocs);
208 }
209 }
210
211 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800212 public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
Toshio Koide106d4492014-10-28 11:22:02 -0700213 checkNotNull(intentId);
214 return linkResourceAllocationsMap.get(intentId);
215 }
216
217 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800218 public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
Toshio Koide106d4492014-10-28 11:22:02 -0700219 checkNotNull(link);
220 Set<LinkResourceAllocations> result = allocatedResources.get(link);
221 if (result == null) {
222 result = Collections.emptySet();
223 }
224 return Collections.unmodifiableSet(result);
225 }
226
227 @Override
Yuta HIGUCHId45886c2014-11-07 15:15:45 -0800228 public synchronized Iterable<LinkResourceAllocations> getAllocations() {
Toshio Koide106d4492014-10-28 11:22:02 -0700229 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
230 }
231
232}