blob: 8b7880084a385f8f7b4e619881e184ff174f738b [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
weibitf32383b2014-10-22 10:17:31 -070016package org.onlab.onos.optical.provisioner;
17
weibit7e583462014-10-23 10:14:05 -070018import java.util.ArrayList;
19import java.util.HashMap;
weibitf32383b2014-10-22 10:17:31 -070020import java.util.Iterator;
weibit7e583462014-10-23 10:14:05 -070021import java.util.Map;
22import java.util.Map.Entry;
weibitf32383b2014-10-22 10:17:31 -070023import java.util.Set;
24
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070030import org.onlab.onos.core.ApplicationId;
31import org.onlab.onos.core.CoreService;
weibitf32383b2014-10-22 10:17:31 -070032import org.onlab.onos.net.ConnectPoint;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080033import org.onlab.onos.net.Host;
weibitf32383b2014-10-22 10:17:31 -070034import org.onlab.onos.net.Link;
weibit7e583462014-10-23 10:14:05 -070035import org.onlab.onos.net.Path;
weibitf32383b2014-10-22 10:17:31 -070036import org.onlab.onos.net.device.DeviceService;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080037import org.onlab.onos.net.flow.DefaultTrafficSelector;
38import org.onlab.onos.net.flow.TrafficSelector;
39import org.onlab.onos.net.flow.TrafficTreatment;
40import org.onlab.onos.net.host.HostService;
41import org.onlab.onos.net.intent.HostToHostIntent;
weibitf32383b2014-10-22 10:17:31 -070042import org.onlab.onos.net.intent.Intent;
weibitf32383b2014-10-22 10:17:31 -070043import org.onlab.onos.net.intent.IntentEvent;
44import org.onlab.onos.net.intent.IntentExtensionService;
weibitf32383b2014-10-22 10:17:31 -070045import org.onlab.onos.net.intent.IntentListener;
46import org.onlab.onos.net.intent.IntentService;
47import org.onlab.onos.net.intent.OpticalConnectivityIntent;
48import org.onlab.onos.net.intent.PointToPointIntent;
49import org.onlab.onos.net.link.LinkService;
weibit7e583462014-10-23 10:14:05 -070050import org.onlab.onos.net.resource.LinkResourceService;
51import org.onlab.onos.net.topology.LinkWeight;
52import org.onlab.onos.net.topology.Topology;
53import org.onlab.onos.net.topology.TopologyEdge;
weibit9e622ac2014-10-23 13:45:44 -070054
weibitf32383b2014-10-22 10:17:31 -070055import org.onlab.onos.net.topology.TopologyService;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080056import org.onlab.packet.Ethernet;
weibitf32383b2014-10-22 10:17:31 -070057import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080060import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
61
weibitf32383b2014-10-22 10:17:31 -070062/**
63 * OpticalPathProvisioner listens event notifications from the Intent F/W.
64 * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
65 * for adding/releasing capacity at the packet layer.
66 *
67 */
68
69@Component(immediate = true)
70public class OpticalPathProvisioner {
71
72 protected static final Logger log = LoggerFactory
73 .getLogger(OpticalPathProvisioner.class);
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 private IntentService intentService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 private IntentExtensionService intentExtensionService;
80
81 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 protected LinkService linkService;
83
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected DeviceService deviceService;
86
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected TopologyService topologyService;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected CoreService coreService;
92
weibit7e583462014-10-23 10:14:05 -070093 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected LinkResourceService resourceService;
weibitf32383b2014-10-22 10:17:31 -070095
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080096 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected HostService hostService;
98
weibitf32383b2014-10-22 10:17:31 -070099 private ApplicationId appId;
weibitf32383b2014-10-22 10:17:31 -0700100
weibit7e583462014-10-23 10:14:05 -0700101 //protected <IntentId> intentIdGenerator;
weibitf32383b2014-10-22 10:17:31 -0700102
103 private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
104
105 @Activate
106 protected void activate() {
107 intentService.addListener(pathProvisioner);
108 appId = coreService.registerApplication("org.onlab.onos.optical");
109 log.info("Starting optical path provisoning...");
110 }
111
112 @Deactivate
113 protected void deactivate() {
114 intentService.removeListener(pathProvisioner);
115 }
116
117 public class InternalOpticalPathProvisioner implements IntentListener {
118 @Override
119 public void event(IntentEvent event) {
120 switch (event.type()) {
121 case SUBMITTED:
122 break;
123 case INSTALLED:
124 break;
125 case FAILED:
weibit50eb95b2014-10-25 21:47:54 -0700126 log.info("packet intent {} failed, calling optical path provisioning APP.", event.subject());
weibitf32383b2014-10-22 10:17:31 -0700127 setuplightpath(event.subject());
128 break;
129 case WITHDRAWN:
130 log.info("intent {} withdrawn.", event.subject());
131 teardownLightpath(event.subject());
132 break;
133 default:
134 break;
135 }
136 }
137
138 private void setuplightpath(Intent intent) {
weibit50eb95b2014-10-25 21:47:54 -0700139 // TODO support more packet intent types
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800140
141 if (intent instanceof HostToHostIntent) {
142 HostToHostIntent hostToHostIntent = (HostToHostIntent) intent;
143 Host one = hostService.getHost(hostToHostIntent.one());
144 Host two = hostService.getHost(hostToHostIntent.two());
145
146 TrafficSelector selector = buildTrafficSelector();
147 TrafficTreatment treatment = builder().build();
148
149 PointToPointIntent intentOneToTwo =
150 new PointToPointIntent(appId, selector, treatment,
151 one.location(), two.location());
152 intentService.submit(intentOneToTwo);
153 log.info("Submitting P2P intent {} ", intentOneToTwo);
154
155 PointToPointIntent intentTwoToOne =
156 new PointToPointIntent(appId, selector, treatment,
157 two.location(), one.location());
158 intentService.submit(intentTwoToOne);
159 log.info("Submitting P2P intent for {} ", intentTwoToOne);
160 return;
161 } else if (!intent.getClass().equals(PointToPointIntent.class)) {
weibitf32383b2014-10-22 10:17:31 -0700162 return;
163 }
164
165 PointToPointIntent pktIntent = (PointToPointIntent) intent;
166 if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) {
167 return;
168 }
169
weibit7e583462014-10-23 10:14:05 -0700170 Topology topology = topologyService.currentTopology();
weibitf32383b2014-10-22 10:17:31 -0700171
weibit7e583462014-10-23 10:14:05 -0700172 LinkWeight weight = new LinkWeight() {
173 @Override
174 public double weight(TopologyEdge edge) {
weibit50eb95b2014-10-25 21:47:54 -0700175 if (isOpticalLink(edge.link())) {
176 return 1000.0; // optical links
weibit7e583462014-10-23 10:14:05 -0700177 } else {
weibit50eb95b2014-10-25 21:47:54 -0700178 return 1.0; // packet links
weibit7e583462014-10-23 10:14:05 -0700179 }
180 }
181 };
weibitf32383b2014-10-22 10:17:31 -0700182
weibit7e583462014-10-23 10:14:05 -0700183 Set<Path> paths = topologyService.getPaths(topology,
184 pktIntent.ingressPoint().deviceId(),
185 pktIntent.egressPoint().deviceId(),
186 weight);
187
188 if (paths.isEmpty()) {
weibitf32383b2014-10-22 10:17:31 -0700189 return;
190 }
191
weibit7e583462014-10-23 10:14:05 -0700192 ConnectPoint srcWdmPoint = null;
193 ConnectPoint dstWdmPoint = null;
194 Iterator<Path> itrPath = paths.iterator();
195 Path firstPath = itrPath.next();
weibit51234a82014-11-13 17:34:50 -0800196 log.info(firstPath.links().toString());
weibitf32383b2014-10-22 10:17:31 -0700197
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800198 ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList =
199 new ArrayList<>();
200
weibit7e583462014-10-23 10:14:05 -0700201
202 Iterator<Link> itrLink = firstPath.links().iterator();
203 while (itrLink.hasNext()) {
204 Link link1 = itrLink.next();
205 if (!isOpticalLink(link1)) {
206 continue;
207 } else {
208 srcWdmPoint = link1.dst();
209 dstWdmPoint = srcWdmPoint;
210 }
211
212 while (true) {
weibit7e583462014-10-23 10:14:05 -0700213 if (itrLink.hasNext()) {
214 Link link2 = itrLink.next();
215 dstWdmPoint = link2.src();
216 } else {
217 break;
218 }
weibit51234a82014-11-13 17:34:50 -0800219
220 /*
weibit7e583462014-10-23 10:14:05 -0700221 if (itrLink.hasNext()) {
222 Link link3 = itrLink.next();
weibit51234a82014-11-13 17:34:50 -0800223 if (isOpticalLink(link3)) {
weibit7e583462014-10-23 10:14:05 -0700224 break;
225 }
226 } else {
227 break;
weibit51234a82014-11-13 17:34:50 -0800228 }*/
229
weibit7e583462014-10-23 10:14:05 -0700230 }
231
232 Map<ConnectPoint, ConnectPoint> pair =
233 new HashMap<ConnectPoint, ConnectPoint>();
234 pair.put(srcWdmPoint, dstWdmPoint);
235
236 connectionList.add(pair);
weibitf32383b2014-10-22 10:17:31 -0700237 }
238
weibit7e583462014-10-23 10:14:05 -0700239 for (Map<ConnectPoint, ConnectPoint> map : connectionList) {
240 for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) {
weibitf32383b2014-10-22 10:17:31 -0700241
weibit7e583462014-10-23 10:14:05 -0700242 ConnectPoint src = entry.getKey();
243 ConnectPoint dst = entry.getValue();
weibitf32383b2014-10-22 10:17:31 -0700244
weibit7e583462014-10-23 10:14:05 -0700245 Intent opticalIntent = new OpticalConnectivityIntent(appId,
246 srcWdmPoint,
247 dstWdmPoint);
248
249 intentService.submit(opticalIntent);
250
weibit51234a82014-11-13 17:34:50 -0800251 log.info(srcWdmPoint.toString());
252 log.info(dstWdmPoint.toString());
weibit7e583462014-10-23 10:14:05 -0700253 }
254 }
255
256 }
257
258 private boolean isOpticalLink(Link link) {
259 boolean isOptical = false;
weibit50eb95b2014-10-25 21:47:54 -0700260 Link.Type lt = link.type();
261 if (lt == Link.Type.OPTICAL) {
262 isOptical = true;
weibit7e583462014-10-23 10:14:05 -0700263 }
264 return isOptical;
weibitf32383b2014-10-22 10:17:31 -0700265 }
266
267 private void teardownLightpath(Intent intent) {
268 // TODO: tear down the idle lightpath if the utilization is close to zero.
269 }
270
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800271 private TrafficSelector buildTrafficSelector() {
272 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
273 Short ethType = Ethernet.TYPE_IPV4;
274
275 selectorBuilder.matchEthType(ethType);
276
277 return selectorBuilder.build();
278 }
279
weibitf32383b2014-10-22 10:17:31 -0700280 }
281
282}