Toshio Koide

Initial implementation of LinkResourceStore for single instance env.

1 +/*
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 + */
16 +package org.onlab.onos.net.resource;
17 +
18 +import java.util.Set;
19 +
20 +import org.onlab.onos.net.Link;
21 +import org.onlab.onos.net.intent.IntentId;
22 +
23 +
24 +/**
25 + * Manages link resources.
26 + */
27 +public interface LinkResourceStore {
28 + Set<ResourceAllocation> getFreeResources(Link link);
29 +
30 + void allocateResources(LinkResourceAllocations allocations);
31 +
32 + void releaseResources(LinkResourceAllocations allocations);
33 +
34 + LinkResourceAllocations getAllocations(IntentId intentId);
35 +
36 + Iterable<LinkResourceAllocations> getAllocations(Link link);
37 +
38 + Iterable<LinkResourceAllocations> getAllocations();
39 +}
...@@ -15,10 +15,13 @@ ...@@ -15,10 +15,13 @@
15 */ 15 */
16 package org.onlab.onos.net.resource.impl; 16 package org.onlab.onos.net.resource.impl;
17 17
18 +import static com.google.common.base.Preconditions.checkArgument;
19 +import static com.google.common.base.Preconditions.checkNotNull;
18 import static org.slf4j.LoggerFactory.getLogger; 20 import static org.slf4j.LoggerFactory.getLogger;
19 21
20 -import java.util.ArrayList; 22 +import java.util.Collections;
21 import java.util.HashMap; 23 import java.util.HashMap;
24 +import java.util.HashSet;
22 import java.util.Iterator; 25 import java.util.Iterator;
23 import java.util.Map; 26 import java.util.Map;
24 import java.util.Set; 27 import java.util.Set;
...@@ -26,6 +29,8 @@ import java.util.Set; ...@@ -26,6 +29,8 @@ import java.util.Set;
26 import org.apache.felix.scr.annotations.Activate; 29 import org.apache.felix.scr.annotations.Activate;
27 import org.apache.felix.scr.annotations.Component; 30 import org.apache.felix.scr.annotations.Component;
28 import org.apache.felix.scr.annotations.Deactivate; 31 import org.apache.felix.scr.annotations.Deactivate;
32 +import org.apache.felix.scr.annotations.Reference;
33 +import org.apache.felix.scr.annotations.ReferenceCardinality;
29 import org.apache.felix.scr.annotations.Service; 34 import org.apache.felix.scr.annotations.Service;
30 import org.onlab.onos.net.Link; 35 import org.onlab.onos.net.Link;
31 import org.onlab.onos.net.intent.IntentId; 36 import org.onlab.onos.net.intent.IntentId;
...@@ -33,15 +38,16 @@ import org.onlab.onos.net.resource.BandwidthResourceAllocation; ...@@ -33,15 +38,16 @@ import org.onlab.onos.net.resource.BandwidthResourceAllocation;
33 import org.onlab.onos.net.resource.BandwidthResourceRequest; 38 import org.onlab.onos.net.resource.BandwidthResourceRequest;
34 import org.onlab.onos.net.resource.Lambda; 39 import org.onlab.onos.net.resource.Lambda;
35 import org.onlab.onos.net.resource.LambdaResourceAllocation; 40 import org.onlab.onos.net.resource.LambdaResourceAllocation;
41 +import org.onlab.onos.net.resource.LambdaResourceRequest;
36 import org.onlab.onos.net.resource.LinkResourceAllocations; 42 import org.onlab.onos.net.resource.LinkResourceAllocations;
37 import org.onlab.onos.net.resource.LinkResourceRequest; 43 import org.onlab.onos.net.resource.LinkResourceRequest;
38 import org.onlab.onos.net.resource.LinkResourceService; 44 import org.onlab.onos.net.resource.LinkResourceService;
45 +import org.onlab.onos.net.resource.LinkResourceStore;
39 import org.onlab.onos.net.resource.ResourceAllocation; 46 import org.onlab.onos.net.resource.ResourceAllocation;
40 import org.onlab.onos.net.resource.ResourceRequest; 47 import org.onlab.onos.net.resource.ResourceRequest;
48 +import org.onlab.onos.net.resource.ResourceType;
41 import org.slf4j.Logger; 49 import org.slf4j.Logger;
42 50
43 -import com.google.common.collect.Sets;
44 -
45 /** 51 /**
46 * Provides basic implementation of link resources allocation. 52 * Provides basic implementation of link resources allocation.
47 */ 53 */
...@@ -51,7 +57,8 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -51,7 +57,8 @@ public class LinkResourceManager implements LinkResourceService {
51 57
52 private final Logger log = getLogger(getClass()); 58 private final Logger log = getLogger(getClass());
53 59
54 - LinkResourceAllocations savedAllocations; 60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + private LinkResourceStore store;
55 62
56 @Activate 63 @Activate
57 public void activate() { 64 public void activate() {
...@@ -63,30 +70,65 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -63,30 +70,65 @@ public class LinkResourceManager implements LinkResourceService {
63 log.info("Stopped"); 70 log.info("Stopped");
64 } 71 }
65 72
66 - private Iterable<Lambda> getAvailableLambdas(Iterable<Link> links) { 73 + /**
67 - return Sets.newHashSet(Lambda.valueOf(7)); 74 + * Returns available lambdas on specified link.
75 + *
76 + * @param link the link
77 + * @return available lambdas on specified link
78 + */
79 + private Set<Lambda> getAvailableLambdas(Link link) {
80 + checkNotNull(link);
81 + Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
82 + if (resAllocs == null) {
83 + return Collections.emptySet();
84 + }
85 + Set<Lambda> lambdas = new HashSet<>();
86 + for (ResourceAllocation res : resAllocs) {
87 + if (res.type() == ResourceType.LAMBDA) {
88 + lambdas.add(((LambdaResourceAllocation) res).lambda());
89 + }
90 + }
91 + return lambdas;
68 } 92 }
69 93
70 - double usedBandwidth = 0.0; 94 + /**
95 + * Returns available lambdas on specified links.
96 + *
97 + * @param links the links
98 + * @return available lambdas on specified links
99 + */
100 + private Iterable<Lambda> getAvailableLambdas(Iterable<Link> links) {
101 + checkNotNull(links);
102 + Iterator<Link> i = links.iterator();
103 + checkArgument(i.hasNext());
104 + Set<Lambda> lambdas = new HashSet<>(getAvailableLambdas(i.next()));
105 + while (i.hasNext()) {
106 + lambdas.retainAll(getAvailableLambdas(i.next()));
107 + }
108 + return lambdas;
109 + }
71 110
72 @Override 111 @Override
73 public LinkResourceAllocations requestResources(LinkResourceRequest req) { 112 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
74 - // TODO implement it using a resource data store. 113 + // TODO Concatenate multiple bandwidth requests.
114 + // TODO Support multiple lambda resource requests.
115 + // TODO Throw appropriate exception.
75 116
76 - ResourceAllocation alloc = null; 117 + Set<ResourceAllocation> allocs = new HashSet<>();
77 for (ResourceRequest r : req.resources()) { 118 for (ResourceRequest r : req.resources()) {
78 switch (r.type()) { 119 switch (r.type()) {
79 case BANDWIDTH: 120 case BANDWIDTH:
80 - log.info("requestResources() always returns requested bandwidth");
81 BandwidthResourceRequest br = (BandwidthResourceRequest) r; 121 BandwidthResourceRequest br = (BandwidthResourceRequest) r;
82 - alloc = new BandwidthResourceAllocation(br.bandwidth()); 122 + allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
83 - usedBandwidth += br.bandwidth().toDouble();
84 break; 123 break;
85 case LAMBDA: 124 case LAMBDA:
86 - log.info("requestResources() always returns lambda 7"); 125 + Iterator<Lambda> lambdaIterator =
87 - Iterator<Lambda> lambdaIterator = getAvailableLambdas(req.links()).iterator(); 126 + getAvailableLambdas(req.links()).iterator();
88 if (lambdaIterator.hasNext()) { 127 if (lambdaIterator.hasNext()) {
89 - alloc = new LambdaResourceAllocation(lambdaIterator.next()); 128 + allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
129 + } else {
130 + log.info("Failed to allocate lambda resource.");
131 + return null;
90 } 132 }
91 break; 133 break;
92 default: 134 default:
...@@ -96,56 +138,66 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -96,56 +138,66 @@ public class LinkResourceManager implements LinkResourceService {
96 138
97 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>(); 139 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
98 for (Link link : req.links()) { 140 for (Link link : req.links()) {
99 - allocations.put(link, Sets.newHashSet(alloc)); 141 + allocations.put(link, allocs);
100 } 142 }
101 - savedAllocations = new DefaultLinkResourceAllocations(req, allocations); 143 + LinkResourceAllocations result =
102 - return savedAllocations; 144 + new DefaultLinkResourceAllocations(req, allocations);
145 + store.allocateResources(result);
146 + return result;
147 +
103 } 148 }
104 149
105 @Override 150 @Override
106 public void releaseResources(LinkResourceAllocations allocations) { 151 public void releaseResources(LinkResourceAllocations allocations) {
107 - // TODO Auto-generated method stub 152 + store.releaseResources(allocations);
108 -
109 } 153 }
110 154
111 @Override 155 @Override
112 public LinkResourceAllocations updateResources(LinkResourceRequest req, 156 public LinkResourceAllocations updateResources(LinkResourceRequest req,
113 LinkResourceAllocations oldAllocations) { 157 LinkResourceAllocations oldAllocations) {
158 + // TODO
114 return null; 159 return null;
115 } 160 }
116 161
117 @Override 162 @Override
118 public Iterable<LinkResourceAllocations> getAllocations() { 163 public Iterable<LinkResourceAllocations> getAllocations() {
119 - // TODO Auto-generated method stub 164 + return store.getAllocations();
120 - return null;
121 } 165 }
122 166
123 @Override 167 @Override
124 public Iterable<LinkResourceAllocations> getAllocations(Link link) { 168 public Iterable<LinkResourceAllocations> getAllocations(Link link) {
125 - ArrayList<LinkResourceAllocations> retval = new ArrayList<>(0); 169 + return store.getAllocations(link);
126 - if (savedAllocations != null) {
127 - retval.add(savedAllocations);
128 - }
129 - return retval;
130 } 170 }
131 171
132 @Override 172 @Override
133 public LinkResourceAllocations getAllocations(IntentId intentId) { 173 public LinkResourceAllocations getAllocations(IntentId intentId) {
134 - // TODO Auto-generated method stub 174 + return store.getAllocations(intentId);
135 - return null;
136 } 175 }
137 176
138 @Override 177 @Override
139 public Iterable<ResourceRequest> getAvailableResources(Link link) { 178 public Iterable<ResourceRequest> getAvailableResources(Link link) {
140 - BandwidthResourceRequest bw = new BandwidthResourceRequest(usedBandwidth); 179 + Set<ResourceAllocation> freeRes = store.getFreeResources(link);
141 - ArrayList<ResourceRequest> result = new ArrayList<>(); 180 + Set<ResourceRequest> result = new HashSet<>();
142 - result.add(bw); 181 + for (ResourceAllocation alloc : freeRes) {
182 + switch (alloc.type()) {
183 + case BANDWIDTH:
184 + result.add(new BandwidthResourceRequest(
185 + ((BandwidthResourceAllocation) alloc).bandwidth()));
186 + break;
187 + case LAMBDA:
188 + result.add(new LambdaResourceRequest());
189 + break;
190 + default:
191 + break;
192 + }
193 + }
143 return result; 194 return result;
144 } 195 }
145 196
146 @Override 197 @Override
147 public ResourceRequest getAvailableResources(Link link, 198 public ResourceRequest getAvailableResources(Link link,
148 LinkResourceAllocations allocations) { 199 LinkResourceAllocations allocations) {
200 + // TODO
149 return null; 201 return null;
150 } 202 }
151 203
......
1 +/*
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 + */
16 +package org.onlab.onos.store.trivial.impl;
17 +
18 +import static com.google.common.base.Preconditions.*;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import java.util.Collections;
22 +import java.util.HashMap;
23 +import java.util.HashSet;
24 +import java.util.Map;
25 +import java.util.Set;
26 +
27 +import org.apache.felix.scr.annotations.Activate;
28 +import org.apache.felix.scr.annotations.Component;
29 +import org.apache.felix.scr.annotations.Deactivate;
30 +import org.apache.felix.scr.annotations.Service;
31 +import org.onlab.onos.net.Link;
32 +import org.onlab.onos.net.intent.IntentId;
33 +import org.onlab.onos.net.resource.Bandwidth;
34 +import org.onlab.onos.net.resource.BandwidthResourceAllocation;
35 +import org.onlab.onos.net.resource.Lambda;
36 +import org.onlab.onos.net.resource.LambdaResourceAllocation;
37 +import org.onlab.onos.net.resource.LinkResourceAllocations;
38 +import org.onlab.onos.net.resource.LinkResourceStore;
39 +import org.onlab.onos.net.resource.ResourceAllocation;
40 +import org.onlab.onos.net.resource.ResourceType;
41 +import org.slf4j.Logger;
42 +
43 +/**
44 + * Manages link resources using trivial in-memory structures implementation.
45 + */
46 +@Component(immediate = true)
47 +@Service
48 +public 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 +}