blob: 64ac3ea7e32a74e8db4b7dfdd70f2debf02adb6c [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);
119 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
weibit9e622ac2014-10-23 13:45:44 -0700120
weibit7e583462014-10-23 10:14:05 -0700121 prev = link.dst();
weibit9e622ac2014-10-23 13:45:44 -0700122 selectorBuilder.matchInport(link.dst().port());
weibit2543d5a2014-10-23 14:13:35 -0700123 selectorBuilder.matchLambda((short) la.toInt());
weibit7e583462014-10-23 10:14:05 -0700124 }
weibit9e622ac2014-10-23 13:45:44 -0700125
126 // build the last T port rule
127 TrafficTreatment treatmentLast = builder()
Brian O'Connor086724e2014-10-23 15:47:32 -0700128 .setOutput(intent.dst().port()).build();
129 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
weibit9e622ac2014-10-23 13:45:44 -0700130 selectorBuilder.build(),
131 treatmentLast,
132 100,
133 appId,
134 100,
135 true);
136 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
137
weibit7e583462014-10-23 10:14:05 -0700138 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
139 }
weibitf32383b2014-10-22 10:17:31 -0700140
weibit9e622ac2014-10-23 13:45:44 -0700141 private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
142 LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
143 intent.path().links())
144 .addLambdaRequest();
145 LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
146 return retLambda;
147 }
148
149 /*private Lambda assignWavelength(List<Link> links) {
weibit7e583462014-10-23 10:14:05 -0700150 // TODO More wavelength assignment algorithm
151 int wavenum = 0;
152 Iterator<Link> itrlink = links.iterator();
153 for (int i = 1; i <= WAVELENGTH; i++) {
154 wavenum = i;
155 boolean found = true;
156 while (itrlink.hasNext()) {
157 Link link = itrlink.next();
158 if (isWavelengthUsed(link, i)) {
159 found = false;
160 break;
161 }
162 }
163 // First-Fit wavelength assignment algorithm
164 if (found) {
165 break;
166 }
167 }
168
169 if (wavenum == 0) {
170 return null;
171 }
172
173 Lambda wave = Lambda.valueOf(wavenum);
174 return wave;
175 }
176
177 private boolean isWavelengthUsed(Link link, int i) {
178 Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link);
179 for (LinkResourceAllocations ir : wave) {
180 //if ir.resources().contains(i) {
181 //}
182 }
183 return false;
weibit9e622ac2014-10-23 13:45:44 -0700184 }*/
weibit7e583462014-10-23 10:14:05 -0700185
186 @Override
187 public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
Toshio Koide86160f52014-10-23 14:59:07 -0700188 LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
weibit9e622ac2014-10-23 13:45:44 -0700189
190 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
Brian O'Connor086724e2014-10-23 15:47:32 -0700191 selectorBuilder.matchInport(intent.src().port());
weibit9e622ac2014-10-23 13:45:44 -0700192
193 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
194
weibit7e583462014-10-23 10:14:05 -0700195 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connor086724e2014-10-23 15:47:32 -0700196 ConnectPoint prev = intent.src();
weibit9e622ac2014-10-23 13:45:44 -0700197
198 //TODO throw exception if the lambda was not retrieved successfully
199 for (Link link : intent.path().links()) {
200 Lambda la = null;
201 for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
202 if (allocation.type() == ResourceType.LAMBDA) {
203 la = ((LambdaResourceAllocation) allocation).lambda();
204 break;
205 }
206 }
207
208 if (la == null) {
209 log.info("Lambda was not retrieved successfully");
210 return null;
211 }
212
213 treatmentBuilder.setOutput(link.src().port());
weibit2543d5a2014-10-23 14:13:35 -0700214 treatmentBuilder.setLambda((short) la.toInt());
weibit9e622ac2014-10-23 13:45:44 -0700215
216 FlowRule rule = new DefaultFlowRule(prev.deviceId(),
217 selectorBuilder.build(),
218 treatmentBuilder.build(),
weibit7e583462014-10-23 10:14:05 -0700219 100,
220 appId,
221 100,
222 true);
weibitf32383b2014-10-22 10:17:31 -0700223 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
weibit9e622ac2014-10-23 13:45:44 -0700224
weibitf32383b2014-10-22 10:17:31 -0700225 prev = link.dst();
weibit9e622ac2014-10-23 13:45:44 -0700226 selectorBuilder.matchInport(link.dst().port());
weibit2543d5a2014-10-23 14:13:35 -0700227 selectorBuilder.matchLambda((short) la.toInt());
weibitf32383b2014-10-22 10:17:31 -0700228 }
weibit9e622ac2014-10-23 13:45:44 -0700229
230 // build the last T port rule
231 TrafficTreatment treatmentLast = builder()
Brian O'Connor086724e2014-10-23 15:47:32 -0700232 .setOutput(intent.dst().port()).build();
233 FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
weibit9e622ac2014-10-23 13:45:44 -0700234 selectorBuilder.build(),
235 treatmentLast,
236 100,
237 appId,
238 100,
239 true);
240 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
241
weibit7e583462014-10-23 10:14:05 -0700242 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
weibitf32383b2014-10-22 10:17:31 -0700243 }
244
245}