blob: 5557b055294885697ea69eb995bf5eb2fcb5d3c7 [file] [log] [blame]
weibitf32383b2014-10-22 10:17:31 -07001package org.onlab.onos.net.intent.impl;
2
3import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
4import static org.slf4j.LoggerFactory.getLogger;
5
weibitf32383b2014-10-22 10:17:31 -07006import java.util.List;
weibitf32383b2014-10-22 10:17:31 -07007
8import org.apache.felix.scr.annotations.Activate;
9import org.apache.felix.scr.annotations.Component;
10import org.apache.felix.scr.annotations.Deactivate;
11import org.apache.felix.scr.annotations.Reference;
12import org.apache.felix.scr.annotations.ReferenceCardinality;
13import org.onlab.onos.ApplicationId;
14import org.onlab.onos.CoreService;
15import org.onlab.onos.net.ConnectPoint;
16import org.onlab.onos.net.Link;
weibitf32383b2014-10-22 10:17:31 -070017import org.onlab.onos.net.flow.DefaultFlowRule;
18import org.onlab.onos.net.flow.DefaultTrafficSelector;
weibit7e583462014-10-23 10:14:05 -070019import org.onlab.onos.net.flow.DefaultTrafficTreatment;
weibitf32383b2014-10-22 10:17:31 -070020import org.onlab.onos.net.flow.FlowRule;
21import org.onlab.onos.net.flow.FlowRuleBatchEntry;
Brian O'Connor086724e2014-10-23 15:47:32 -070022import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
weibitf32383b2014-10-22 10:17:31 -070023import org.onlab.onos.net.flow.FlowRuleBatchOperation;
24import org.onlab.onos.net.flow.FlowRuleService;
25import org.onlab.onos.net.flow.TrafficSelector;
26import org.onlab.onos.net.flow.TrafficTreatment;
weibitf32383b2014-10-22 10:17:31 -070027import org.onlab.onos.net.intent.IntentExtensionService;
28import org.onlab.onos.net.intent.IntentInstaller;
29import org.onlab.onos.net.intent.OpticalPathIntent;
weibit9e622ac2014-10-23 13:45:44 -070030import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
weibit7e583462014-10-23 10:14:05 -070031import org.onlab.onos.net.resource.Lambda;
weibit9e622ac2014-10-23 13:45:44 -070032import org.onlab.onos.net.resource.LambdaResourceAllocation;
weibit7e583462014-10-23 10:14:05 -070033import org.onlab.onos.net.resource.LinkResourceAllocations;
34import org.onlab.onos.net.resource.LinkResourceRequest;
35import org.onlab.onos.net.resource.LinkResourceService;
weibit9e622ac2014-10-23 13:45:44 -070036import org.onlab.onos.net.resource.ResourceAllocation;
37import org.onlab.onos.net.resource.ResourceType;
weibit7e583462014-10-23 10:14:05 -070038import org.onlab.onos.net.topology.TopologyService;
weibitf32383b2014-10-22 10:17:31 -070039import org.slf4j.Logger;
40
41import com.google.common.collect.Lists;
42
43/**
44 * OpticaliIntentInstaller for optical path intents.
45 * It essentially generates optical FlowRules and
46 * call the flowRule service to execute them.
47 */
48
49@Component(immediate = true)
50public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
weibitf32383b2014-10-22 10:17:31 -070051 private final Logger log = getLogger(getClass());
52
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected IntentExtensionService intentManager;
55
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected FlowRuleService flowRuleService;
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected CoreService coreService;
61
weibit7e583462014-10-23 10:14:05 -070062 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected TopologyService topologyService;
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected LinkResourceService resourceService;
67
weibitf32383b2014-10-22 10:17:31 -070068 private ApplicationId appId;
69
weibit9e622ac2014-10-23 13:45:44 -070070 //final short WAVELENGTH = 80;
weibit7e583462014-10-23 10:14:05 -070071
weibitf32383b2014-10-22 10:17:31 -070072 @Activate
73 public void activate() {
74 appId = coreService.registerApplication("org.onlab.onos.net.intent");
75 intentManager.registerInstaller(OpticalPathIntent.class, this);
76 }
77
78 @Deactivate
79 public void deactivate() {
80 intentManager.unregisterInstaller(OpticalPathIntent.class);
81 }
82
83 @Override
weibit7e583462014-10-23 10:14:05 -070084 public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
weibit9e622ac2014-10-23 13:45:44 -070085 LinkResourceAllocations allocations = assignWavelength(intent);
weibitf32383b2014-10-22 10:17:31 -070086
weibit9e622ac2014-10-23 13:45:44 -070087 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
Brian O'Connor086724e2014-10-23 15:47:32 -070088 selectorBuilder.matchInport(intent.src().port());
weibitf32383b2014-10-22 10:17:31 -070089
weibitf32383b2014-10-22 10:17:31 -070090 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connor086724e2014-10-23 15:47:32 -070091 ConnectPoint prev = intent.src();
weibitf32383b2014-10-22 10:17:31 -070092
weibit9e622ac2014-10-23 13:45:44 -070093 //TODO throw exception if the lambda was not assigned successfully
94 for (Link link : intent.path().links()) {
95 Lambda la = null;
96 for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
97 if (allocation.type() == ResourceType.LAMBDA) {
98 la = ((LambdaResourceAllocation) allocation).lambda();
99 break;
100 }
101 }
102
103 if (la == null) {
104 log.info("Lambda was not assigned successfully");
105 return null;
106 }
107
weibit253c8652014-10-23 16:30:03 -0700108 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
weibit9e622ac2014-10-23 13:45:44 -0700109 treatmentBuilder.setOutput(link.src().port());
weibit2543d5a2014-10-23 14:13:35 -0700110 treatmentBuilder.setLambda((short) la.toInt());
weibit9e622ac2014-10-23 13:45:44 -0700111
112 FlowRule rule = new DefaultFlowRule(prev.deviceId(),
113 selectorBuilder.build(),
114 treatmentBuilder.build(),
weibitf32383b2014-10-22 10:17:31 -0700115 100,
116 appId,
weibit7e583462014-10-23 10:14:05 -0700117 100,
118 true);
weibitaca14602014-10-24 10:26:26 -0700119
weibit7e583462014-10-23 10:14:05 -0700120 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
weibit9e622ac2014-10-23 13:45:44 -0700121
weibit7e583462014-10-23 10:14:05 -0700122 prev = link.dst();
weibit9e622ac2014-10-23 13:45:44 -0700123 selectorBuilder.matchInport(link.dst().port());
weibit2543d5a2014-10-23 14:13:35 -0700124 selectorBuilder.matchLambda((short) la.toInt());
weibit7e583462014-10-23 10:14:05 -0700125 }
weibit9e622ac2014-10-23 13:45:44 -0700126
127 // build the last T port rule
128 TrafficTreatment treatmentLast = builder()
Brian O'Connor086724e2014-10-23 15:47:32 -0700129 .setOutput(intent.dst().port()).build();
130 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
weibit9e622ac2014-10-23 13:45:44 -0700131 selectorBuilder.build(),
132 treatmentLast,
133 100,
134 appId,
135 100,
136 true);
137 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
138
weibit7e583462014-10-23 10:14:05 -0700139 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
140 }
weibitf32383b2014-10-22 10:17:31 -0700141
weibit9e622ac2014-10-23 13:45:44 -0700142 private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
143 LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
144 intent.path().links())
145 .addLambdaRequest();
146 LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
147 return retLambda;
148 }
149
150 /*private Lambda assignWavelength(List<Link> links) {
weibit7e583462014-10-23 10:14:05 -0700151 // TODO More wavelength assignment algorithm
152 int wavenum = 0;
153 Iterator<Link> itrlink = links.iterator();
154 for (int i = 1; i <= WAVELENGTH; i++) {
155 wavenum = i;
156 boolean found = true;
157 while (itrlink.hasNext()) {
158 Link link = itrlink.next();
159 if (isWavelengthUsed(link, i)) {
160 found = false;
161 break;
162 }
163 }
164 // First-Fit wavelength assignment algorithm
165 if (found) {
166 break;
167 }
168 }
169
170 if (wavenum == 0) {
171 return null;
172 }
173
174 Lambda wave = Lambda.valueOf(wavenum);
175 return wave;
176 }
177
178 private boolean isWavelengthUsed(Link link, int i) {
179 Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link);
180 for (LinkResourceAllocations ir : wave) {
181 //if ir.resources().contains(i) {
182 //}
183 }
184 return false;
weibit9e622ac2014-10-23 13:45:44 -0700185 }*/
weibit7e583462014-10-23 10:14:05 -0700186
187 @Override
188 public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
Toshio Koide86160f52014-10-23 14:59:07 -0700189 LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
weibit9e622ac2014-10-23 13:45:44 -0700190
191 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
Brian O'Connor086724e2014-10-23 15:47:32 -0700192 selectorBuilder.matchInport(intent.src().port());
weibit9e622ac2014-10-23 13:45:44 -0700193
194 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
195
weibit7e583462014-10-23 10:14:05 -0700196 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connor086724e2014-10-23 15:47:32 -0700197 ConnectPoint prev = intent.src();
weibit9e622ac2014-10-23 13:45:44 -0700198
199 //TODO throw exception if the lambda was not retrieved successfully
200 for (Link link : intent.path().links()) {
201 Lambda la = null;
202 for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
203 if (allocation.type() == ResourceType.LAMBDA) {
204 la = ((LambdaResourceAllocation) allocation).lambda();
205 break;
206 }
207 }
208
209 if (la == null) {
210 log.info("Lambda was not retrieved successfully");
211 return null;
212 }
213
214 treatmentBuilder.setOutput(link.src().port());
weibit2543d5a2014-10-23 14:13:35 -0700215 treatmentBuilder.setLambda((short) la.toInt());
weibit9e622ac2014-10-23 13:45:44 -0700216
217 FlowRule rule = new DefaultFlowRule(prev.deviceId(),
218 selectorBuilder.build(),
219 treatmentBuilder.build(),
weibit7e583462014-10-23 10:14:05 -0700220 100,
221 appId,
222 100,
223 true);
weibitf32383b2014-10-22 10:17:31 -0700224 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
weibit9e622ac2014-10-23 13:45:44 -0700225
weibitf32383b2014-10-22 10:17:31 -0700226 prev = link.dst();
weibit9e622ac2014-10-23 13:45:44 -0700227 selectorBuilder.matchInport(link.dst().port());
weibit2543d5a2014-10-23 14:13:35 -0700228 selectorBuilder.matchLambda((short) la.toInt());
weibitf32383b2014-10-22 10:17:31 -0700229 }
weibit9e622ac2014-10-23 13:45:44 -0700230
231 // build the last T port rule
232 TrafficTreatment treatmentLast = builder()
Brian O'Connor086724e2014-10-23 15:47:32 -0700233 .setOutput(intent.dst().port()).build();
234 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
weibit9e622ac2014-10-23 13:45:44 -0700235 selectorBuilder.build(),
236 treatmentLast,
237 100,
238 appId,
239 100,
240 true);
241 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
242
weibit7e583462014-10-23 10:14:05 -0700243 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
weibitf32383b2014-10-22 10:17:31 -0700244 }
245
246}