blob: 8af6fa371cfa0dc4c17a9aa21ad30c80db7ffaf9 [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
18import static com.google.common.base.Preconditions.*;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.Collections;
22import java.util.HashMap;
23import java.util.HashSet;
24import java.util.Map;
25import java.util.Set;
26
27import org.apache.felix.scr.annotations.Activate;
28import org.apache.felix.scr.annotations.Component;
29import org.apache.felix.scr.annotations.Deactivate;
30import org.apache.felix.scr.annotations.Service;
31import org.onlab.onos.net.Link;
32import org.onlab.onos.net.intent.IntentId;
33import org.onlab.onos.net.resource.Bandwidth;
34import org.onlab.onos.net.resource.BandwidthResourceAllocation;
35import org.onlab.onos.net.resource.Lambda;
36import org.onlab.onos.net.resource.LambdaResourceAllocation;
37import org.onlab.onos.net.resource.LinkResourceAllocations;
38import org.onlab.onos.net.resource.LinkResourceStore;
39import org.onlab.onos.net.resource.ResourceAllocation;
40import org.onlab.onos.net.resource.ResourceType;
41import org.slf4j.Logger;
42
43/**
44 * Manages link resources using trivial in-memory structures implementation.
45 */
46@Component(immediate = true)
47@Service
48public class SimpleLinkResourceStore implements LinkResourceStore {
49 private final Logger log = getLogger(getClass());
50 private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
51 private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
52 private Map<Link, Set<ResourceAllocation>> freeResources;
53
54 @Activate
55 public void activate() {
56 linkResourceAllocationsMap = new HashMap<>();
57 allocatedResources = new HashMap<>();
58 freeResources = new HashMap<>();
59
60 log.info("Started");
61 }
62
63 @Deactivate
64 public void deactivate() {
65 log.info("Stopped");
66 }
67
68 private Set<ResourceAllocation> readOriginalFreeResources(Link link) {
69 // TODO read capacity and lambda resources from topology
70 Set<ResourceAllocation> allocations = new HashSet<>();
71 for (int i = 1; i <= 100; i++) {
72 allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
73 }
74 allocations.add(new BandwidthResourceAllocation(Bandwidth.valueOf(1000000)));
75 return allocations;
76 }
77
78 private BandwidthResourceAllocation getBandwidth(Set<ResourceAllocation> freeRes) {
79 for (ResourceAllocation res : freeRes) {
80 if (res.type() == ResourceType.BANDWIDTH) {
81 return (BandwidthResourceAllocation) res;
82 }
83 }
84 return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
85 }
86
87 private void subtractFreeResources(Link link, LinkResourceAllocations allocations) {
88 // TODO Use lock or version for updating freeResources.
89 checkNotNull(link);
90 Set<ResourceAllocation> freeRes = freeResources.get(link);
91 checkNotNull(freeRes);
92 freeRes = new HashSet<>(freeRes);
93 Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
94 for (ResourceAllocation res : subRes) {
95 switch (res.type()) {
96 case BANDWIDTH:
97 BandwidthResourceAllocation ba = getBandwidth(freeRes);
98 double requestedBandwidth =
99 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
100 double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
101 checkState(newBandwidth >= 0.0);
102 freeRes.remove(ba);
103 freeRes.add(new BandwidthResourceAllocation(
104 Bandwidth.valueOf(newBandwidth)));
105 break;
106 case LAMBDA:
107 checkState(freeRes.remove(res));
108 break;
109 default:
110 break;
111 }
112 }
113 freeResources.put(link, freeRes);
114
115 }
116
117 private void addFreeResources(Link link, LinkResourceAllocations allocations) {
118 // TODO Use lock or version for updating freeResources.
119 Set<ResourceAllocation> freeRes = freeResources.get(link);
120 checkNotNull(freeRes);
121 freeRes = new HashSet<>(freeRes);
122 Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
123 for (ResourceAllocation res : addRes) {
124 switch (res.type()) {
125 case BANDWIDTH:
126 BandwidthResourceAllocation ba = getBandwidth(freeRes);
127 double requestedBandwidth =
128 ((BandwidthResourceAllocation) res).bandwidth().toDouble();
129 double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
130 freeRes.remove(ba);
131 freeRes.add(new BandwidthResourceAllocation(
132 Bandwidth.valueOf(newBandwidth)));
133 break;
134 case LAMBDA:
135 checkState(freeRes.add(res));
136 break;
137 default:
138 break;
139 }
140 }
141 freeResources.put(link, freeRes);
142 }
143
144 @Override
145 public Set<ResourceAllocation> getFreeResources(Link link) {
146 checkNotNull(link);
147 Set<ResourceAllocation> freeRes = freeResources.get(link);
148 if (freeRes == null) {
149 freeRes = readOriginalFreeResources(link);
150 }
151
152 return freeRes;
153 }
154
155 @Override
156 public void allocateResources(LinkResourceAllocations allocations) {
157 checkNotNull(allocations);
158 linkResourceAllocationsMap.put(allocations.intendId(), allocations);
159 for (Link link : allocations.links()) {
160 subtractFreeResources(link, allocations);
161 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
162 if (linkAllocs == null) {
163 linkAllocs = new HashSet<>();
164 }
165 linkAllocs.add(allocations);
166 allocatedResources.put(link, linkAllocs);
167 }
168 }
169
170 @Override
171 public void releaseResources(LinkResourceAllocations allocations) {
172 checkNotNull(allocations);
173 linkResourceAllocationsMap.remove(allocations);
174 for (Link link : allocations.links()) {
175 addFreeResources(link, allocations);
176 Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
177 if (linkAllocs == null) {
178 log.error("Missing resource allocation.");
179 } else {
180 linkAllocs.remove(allocations);
181 }
182 allocatedResources.put(link, linkAllocs);
183 }
184 }
185
186 @Override
187 public LinkResourceAllocations getAllocations(IntentId intentId) {
188 checkNotNull(intentId);
189 return linkResourceAllocationsMap.get(intentId);
190 }
191
192 @Override
193 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
194 checkNotNull(link);
195 Set<LinkResourceAllocations> result = allocatedResources.get(link);
196 if (result == null) {
197 result = Collections.emptySet();
198 }
199 return Collections.unmodifiableSet(result);
200 }
201
202 @Override
203 public Iterable<LinkResourceAllocations> getAllocations() {
204 return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
205 }
206
207}