Brian O'Connor

Applied some fixes to Intents

- Use classname instead of class in IntentId
- Added hashcode and equals to LambdaResourceAllocation
- Untrack resources in IntentManger during uninstall
- Refactored common code in OpticalPathIntentInstaller
- Copied SimpleLinkResourceStore to DistributedLinkResourceStore
- Added a few unserializable files to KryoNamespaces

Change-Id: Ic35d102244972d5cf0c64482fd99e8c9bb1293a6
...@@ -19,6 +19,7 @@ import org.onlab.onos.core.ApplicationId; ...@@ -19,6 +19,7 @@ import org.onlab.onos.core.ApplicationId;
19 import org.onlab.onos.net.NetworkResource; 19 import org.onlab.onos.net.NetworkResource;
20 import org.onlab.onos.net.flow.BatchOperationTarget; 20 import org.onlab.onos.net.flow.BatchOperationTarget;
21 21
22 +import java.util.Arrays;
22 import java.util.Collection; 23 import java.util.Collection;
23 import java.util.Objects; 24 import java.util.Objects;
24 25
...@@ -93,9 +94,10 @@ public abstract class Intent implements BatchOperationTarget { ...@@ -93,9 +94,10 @@ public abstract class Intent implements BatchOperationTarget {
93 * @param fields intent fields 94 * @param fields intent fields
94 * @return intent identifier 95 * @return intent identifier
95 */ 96 */
96 - protected static IntentId id(Object... fields) { 97 + protected static IntentId id(Class<?> intentClass, Object... fields) {
97 // FIXME: spread the bits across the full long spectrum 98 // FIXME: spread the bits across the full long spectrum
98 - return IntentId.valueOf(Objects.hash(fields)); 99 + return IntentId.valueOf(Objects.hash(intentClass.getName(),
100 + Arrays.hashCode(fields)));
99 } 101 }
100 102
101 /** 103 /**
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.resource; 16 package org.onlab.onos.net.resource;
17 17
18 +import java.util.Objects;
19 +
18 /** 20 /**
19 * Representation of allocated lambda resource. 21 * Representation of allocated lambda resource.
20 */ 22 */
...@@ -45,4 +47,21 @@ public class LambdaResourceAllocation extends LambdaResourceRequest ...@@ -45,4 +47,21 @@ public class LambdaResourceAllocation extends LambdaResourceRequest
45 public Lambda lambda() { 47 public Lambda lambda() {
46 return lambda; 48 return lambda;
47 } 49 }
50 +
51 + @Override
52 + public int hashCode() {
53 + return Objects.hash(lambda);
54 + }
55 +
56 + @Override
57 + public boolean equals(Object obj) {
58 + if (this == obj) {
59 + return true;
60 + }
61 + if (obj == null || getClass() != obj.getClass()) {
62 + return false;
63 + }
64 + final LambdaResourceAllocation other = (LambdaResourceAllocation) obj;
65 + return Objects.equals(this.lambda, other.lambda);
66 + }
48 } 67 }
......
...@@ -407,6 +407,8 @@ public class IntentManager ...@@ -407,6 +407,8 @@ public class IntentManager
407 List<Intent> installables = store.getInstallableIntents(intent.id()); 407 List<Intent> installables = store.getInstallableIntents(intent.id());
408 if (installables != null) { 408 if (installables != null) {
409 for (Intent installable : installables) { 409 for (Intent installable : installables) {
410 + trackerService.removeTrackedResources(intent.id(),
411 + installable.resources());
410 List<FlowRuleBatchOperation> batches = getInstaller(installable).uninstall(installable); 412 List<FlowRuleBatchOperation> batches = getInstaller(installable).uninstall(installable);
411 uninstallWork.addAll(batches); 413 uninstallWork.addAll(batches);
412 } 414 }
......
...@@ -94,7 +94,26 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn ...@@ -94,7 +94,26 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
94 @Override 94 @Override
95 public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) { 95 public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
96 LinkResourceAllocations allocations = assignWavelength(intent); 96 LinkResourceAllocations allocations = assignWavelength(intent);
97 + return generateRules(intent, allocations, FlowRuleOperation.ADD);
98 + }
99 +
100 + @Override
101 + public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
102 + LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
103 + return generateRules(intent, allocations, FlowRuleOperation.REMOVE);
104 + }
97 105
106 + private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
107 + LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
108 + intent.path().links())
109 + .addLambdaRequest();
110 + LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
111 + return retLambda;
112 + }
113 +
114 + private List<FlowRuleBatchOperation> generateRules(OpticalPathIntent intent,
115 + LinkResourceAllocations allocations,
116 + FlowRuleOperation operation) {
98 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); 117 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
99 selectorBuilder.matchInport(intent.src().port()); 118 selectorBuilder.matchInport(intent.src().port());
100 119
...@@ -128,7 +147,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn ...@@ -128,7 +147,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
128 100, 147 100,
129 true); 148 true);
130 149
131 - rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); 150 + rules.add(new FlowRuleBatchEntry(operation, rule));
132 151
133 prev = link.dst(); 152 prev = link.dst();
134 selectorBuilder.matchInport(link.dst().port()); 153 selectorBuilder.matchInport(link.dst().port());
...@@ -136,28 +155,20 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn ...@@ -136,28 +155,20 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
136 } 155 }
137 156
138 // build the last T port rule 157 // build the last T port rule
139 - TrafficTreatment treatmentLast = builder() 158 + TrafficTreatment.Builder treatmentLast = builder();
140 - .setOutput(intent.dst().port()).build(); 159 + treatmentLast.setOutput(intent.dst().port());
141 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(), 160 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
142 selectorBuilder.build(), 161 selectorBuilder.build(),
143 - treatmentLast, 162 + treatmentLast.build(),
144 100, 163 100,
145 appId, 164 appId,
146 100, 165 100,
147 true); 166 true);
148 - rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); 167 + rules.add(new FlowRuleBatchEntry(operation, rule));
149 168
150 return Lists.newArrayList(new FlowRuleBatchOperation(rules)); 169 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
151 } 170 }
152 171
153 - private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
154 - LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
155 - intent.path().links())
156 - .addLambdaRequest();
157 - LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
158 - return retLambda;
159 - }
160 -
161 /*private Lambda assignWavelength(List<Link> links) { 172 /*private Lambda assignWavelength(List<Link> links) {
162 // TODO More wavelength assignment algorithm 173 // TODO More wavelength assignment algorithm
163 int wavenum = 0; 174 int wavenum = 0;
...@@ -194,64 +205,4 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn ...@@ -194,64 +205,4 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
194 } 205 }
195 return false; 206 return false;
196 }*/ 207 }*/
197 -
198 - @Override
199 - public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
200 - LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
201 -
202 - TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
203 - selectorBuilder.matchInport(intent.src().port());
204 -
205 - TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
206 -
207 - List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
208 - ConnectPoint prev = intent.src();
209 -
210 - //TODO throw exception if the lambda was not retrieved successfully
211 - for (Link link : intent.path().links()) {
212 - Lambda la = null;
213 - for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
214 - if (allocation.type() == ResourceType.LAMBDA) {
215 - la = ((LambdaResourceAllocation) allocation).lambda();
216 - break;
217 - }
218 - }
219 -
220 - if (la == null) {
221 - log.info("Lambda was not retrieved successfully");
222 - return null;
223 - }
224 -
225 - treatmentBuilder.setOutput(link.src().port());
226 - treatmentBuilder.setLambda((short) la.toInt());
227 -
228 - FlowRule rule = new DefaultFlowRule(prev.deviceId(),
229 - selectorBuilder.build(),
230 - treatmentBuilder.build(),
231 - 100,
232 - appId,
233 - 100,
234 - true);
235 - rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
236 -
237 - prev = link.dst();
238 - selectorBuilder.matchInport(link.dst().port());
239 - selectorBuilder.matchLambda((short) la.toInt());
240 - }
241 -
242 - // build the last T port rule
243 - TrafficTreatment treatmentLast = builder()
244 - .setOutput(intent.dst().port()).build();
245 - FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
246 - selectorBuilder.build(),
247 - treatmentLast,
248 - 100,
249 - appId,
250 - 100,
251 - true);
252 - rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
253 -
254 - return Lists.newArrayList(new FlowRuleBatchOperation(rules));
255 - }
256 -
257 } 208 }
......
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.resource.impl;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Service;
22 +import org.onlab.onos.net.Link;
23 +import org.onlab.onos.net.intent.IntentId;
24 +import org.onlab.onos.net.resource.Bandwidth;
25 +import org.onlab.onos.net.resource.BandwidthResourceAllocation;
26 +import org.onlab.onos.net.resource.Lambda;
27 +import org.onlab.onos.net.resource.LambdaResourceAllocation;
28 +import org.onlab.onos.net.resource.LinkResourceAllocations;
29 +import org.onlab.onos.net.resource.LinkResourceStore;
30 +import org.onlab.onos.net.resource.ResourceAllocation;
31 +import org.onlab.onos.net.resource.ResourceType;
32 +import org.slf4j.Logger;
33 +
34 +import java.util.Collections;
35 +import java.util.HashMap;
36 +import java.util.HashSet;
37 +import java.util.Map;
38 +import java.util.Set;
39 +
40 +import static com.google.common.base.Preconditions.checkNotNull;
41 +import static com.google.common.base.Preconditions.checkState;
42 +import static org.slf4j.LoggerFactory.getLogger;
43 +
44 +/**
45 + * Manages link resources using trivial in-memory structures implementation.
46 + */
47 +@Component(immediate = true)
48 +@Service
49 +public class DistributedLinkResourceStore 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 +
69 + /**
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 + */
76 + private Set<ResourceAllocation> readOriginalFreeResources(Link link) {
77 + // 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 +
86 + /**
87 + * Finds and returns {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object from a given
88 + * set.
89 + *
90 + * @param freeRes a set of ResourceAllocation object.
91 + * @return {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object if found, otherwise
92 + * {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object with 0 bandwidth
93 + *
94 + */
95 + private BandwidthResourceAllocation getBandwidth(Set<ResourceAllocation> freeRes) {
96 + 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 +
104 + /**
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 + */
110 + private void subtractFreeResources(Link link, LinkResourceAllocations allocations) {
111 + // TODO Use lock or version for updating freeResources.
112 + checkNotNull(link);
113 + Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
114 + 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 +
138 + /**
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 + */
144 + private void addFreeResources(Link link, LinkResourceAllocations allocations) {
145 + // TODO Use lock or version for updating freeResources.
146 + Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
147 + 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
170 + public Set<ResourceAllocation> getFreeResources(Link link) {
171 + 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
181 + public void allocateResources(LinkResourceAllocations allocations) {
182 + 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
196 + public void releaseResources(LinkResourceAllocations allocations) {
197 + checkNotNull(allocations);
198 + linkResourceAllocationsMap.remove(allocations);
199 + 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
212 + public LinkResourceAllocations getAllocations(IntentId intentId) {
213 + checkNotNull(intentId);
214 + return linkResourceAllocationsMap.get(intentId);
215 + }
216 +
217 + @Override
218 + public Iterable<LinkResourceAllocations> getAllocations(Link link) {
219 + 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
228 + public Iterable<LinkResourceAllocations> getAllocations() {
229 + return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
230 + }
231 +
232 +}
1 +/**
2 + * Implementation of distributed packet store.
3 + */
4 +package org.onlab.onos.store.resource.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -71,11 +71,14 @@ import org.onlab.onos.net.intent.IntentId; ...@@ -71,11 +71,14 @@ import org.onlab.onos.net.intent.IntentId;
71 import org.onlab.onos.net.intent.IntentState; 71 import org.onlab.onos.net.intent.IntentState;
72 import org.onlab.onos.net.intent.LinkCollectionIntent; 72 import org.onlab.onos.net.intent.LinkCollectionIntent;
73 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; 73 import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
74 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
75 +import org.onlab.onos.net.intent.OpticalPathIntent;
74 import org.onlab.onos.net.intent.PathIntent; 76 import org.onlab.onos.net.intent.PathIntent;
75 import org.onlab.onos.net.intent.PointToPointIntent; 77 import org.onlab.onos.net.intent.PointToPointIntent;
76 import org.onlab.onos.net.link.DefaultLinkDescription; 78 import org.onlab.onos.net.link.DefaultLinkDescription;
77 import org.onlab.onos.net.packet.DefaultOutboundPacket; 79 import org.onlab.onos.net.packet.DefaultOutboundPacket;
78 import org.onlab.onos.net.provider.ProviderId; 80 import org.onlab.onos.net.provider.ProviderId;
81 +import org.onlab.onos.net.resource.LinkResourceRequest;
79 import org.onlab.onos.store.Timestamp; 82 import org.onlab.onos.store.Timestamp;
80 import org.onlab.packet.ChassisId; 83 import org.onlab.packet.ChassisId;
81 import org.onlab.packet.IpAddress; 84 import org.onlab.packet.IpAddress;
...@@ -182,7 +185,10 @@ public final class KryoNamespaces { ...@@ -182,7 +185,10 @@ public final class KryoNamespaces {
182 HostToHostIntent.class, 185 HostToHostIntent.class,
183 PointToPointIntent.class, 186 PointToPointIntent.class,
184 MultiPointToSinglePointIntent.class, 187 MultiPointToSinglePointIntent.class,
185 - LinkCollectionIntent.class 188 + LinkCollectionIntent.class,
189 + OpticalConnectivityIntent.class,
190 + OpticalPathIntent.class,
191 + LinkResourceRequest.class
186 ) 192 )
187 .register(DefaultApplicationId.class, new DefaultApplicationIdSerializer()) 193 .register(DefaultApplicationId.class, new DefaultApplicationIdSerializer())
188 .register(URI.class, new URISerializer()) 194 .register(URI.class, new URISerializer())
......