blob: f4ad841fb7c71cef8908ff9d2ababa03fb76a922 [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 */
Thomas Vachuska112c7032014-11-16 11:05:14 -080016package org.onlab.onos.optical;
weibitf32383b2014-10-22 10:17:31 -070017
Brian O'Connor772852a2014-11-17 15:51:19 -080018import com.google.common.collect.Lists;
weibitf32383b2014-10-22 10:17:31 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070024import org.onlab.onos.core.ApplicationId;
25import org.onlab.onos.core.CoreService;
weibitf32383b2014-10-22 10:17:31 -070026import org.onlab.onos.net.ConnectPoint;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080027import org.onlab.onos.net.Host;
weibitf32383b2014-10-22 10:17:31 -070028import org.onlab.onos.net.Link;
weibit7e583462014-10-23 10:14:05 -070029import org.onlab.onos.net.Path;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080030import org.onlab.onos.net.host.HostService;
31import org.onlab.onos.net.intent.HostToHostIntent;
weibitf32383b2014-10-22 10:17:31 -070032import org.onlab.onos.net.intent.Intent;
weibitf32383b2014-10-22 10:17:31 -070033import org.onlab.onos.net.intent.IntentEvent;
weibitf32383b2014-10-22 10:17:31 -070034import org.onlab.onos.net.intent.IntentListener;
Brian O'Connor772852a2014-11-17 15:51:19 -080035import org.onlab.onos.net.intent.IntentOperations;
weibitf32383b2014-10-22 10:17:31 -070036import org.onlab.onos.net.intent.IntentService;
Brian O'Connor772852a2014-11-17 15:51:19 -080037import org.onlab.onos.net.intent.IntentState;
weibitf32383b2014-10-22 10:17:31 -070038import org.onlab.onos.net.intent.OpticalConnectivityIntent;
39import org.onlab.onos.net.intent.PointToPointIntent;
weibit7e583462014-10-23 10:14:05 -070040import org.onlab.onos.net.topology.LinkWeight;
Brian O'Connor772852a2014-11-17 15:51:19 -080041import org.onlab.onos.net.topology.PathService;
weibit7e583462014-10-23 10:14:05 -070042import org.onlab.onos.net.topology.TopologyEdge;
weibitf32383b2014-10-22 10:17:31 -070043import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45
Brian O'Connor772852a2014-11-17 15:51:19 -080046import java.util.Iterator;
47import java.util.List;
48import java.util.Set;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080049
weibitf32383b2014-10-22 10:17:31 -070050/**
51 * OpticalPathProvisioner listens event notifications from the Intent F/W.
52 * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
53 * for adding/releasing capacity at the packet layer.
54 *
55 */
56
57@Component(immediate = true)
58public class OpticalPathProvisioner {
59
60 protected static final Logger log = LoggerFactory
61 .getLogger(OpticalPathProvisioner.class);
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 private IntentService intentService;
65
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Brian O'Connor772852a2014-11-17 15:51:19 -080067 protected PathService pathService;
weibitf32383b2014-10-22 10:17:31 -070068
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected CoreService coreService;
71
weibit7e583462014-10-23 10:14:05 -070072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080073 protected HostService hostService;
74
weibitf32383b2014-10-22 10:17:31 -070075 private ApplicationId appId;
weibitf32383b2014-10-22 10:17:31 -070076
weibit7e583462014-10-23 10:14:05 -070077 //protected <IntentId> intentIdGenerator;
weibitf32383b2014-10-22 10:17:31 -070078
79 private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
80
81 @Activate
82 protected void activate() {
83 intentService.addListener(pathProvisioner);
84 appId = coreService.registerApplication("org.onlab.onos.optical");
85 log.info("Starting optical path provisoning...");
86 }
87
88 @Deactivate
89 protected void deactivate() {
90 intentService.removeListener(pathProvisioner);
91 }
92
93 public class InternalOpticalPathProvisioner implements IntentListener {
94 @Override
95 public void event(IntentEvent event) {
96 switch (event.type()) {
Brian O'Connor7a71d5d2014-12-02 00:12:27 -080097 case INSTALL_REQ:
weibitf32383b2014-10-22 10:17:31 -070098 break;
99 case INSTALLED:
100 break;
101 case FAILED:
weibit50eb95b2014-10-25 21:47:54 -0700102 log.info("packet intent {} failed, calling optical path provisioning APP.", event.subject());
Brian O'Connor772852a2014-11-17 15:51:19 -0800103 setupLightpath(event.subject());
weibitf32383b2014-10-22 10:17:31 -0700104 break;
105 case WITHDRAWN:
106 log.info("intent {} withdrawn.", event.subject());
107 teardownLightpath(event.subject());
108 break;
109 default:
110 break;
111 }
112 }
113
Brian O'Connor772852a2014-11-17 15:51:19 -0800114 private void setupLightpath(Intent intent) {
115 // TODO support more packet intent types
116 List<Intent> intents = Lists.newArrayList();
117 if (intent instanceof HostToHostIntent) {
118 HostToHostIntent hostToHostIntent = (HostToHostIntent) intent;
119 Host one = hostService.getHost(hostToHostIntent.one());
120 Host two = hostService.getHost(hostToHostIntent.two());
121 // provision both directions
122 intents.addAll(getOpticalPaths(one.location(), two.location()));
123 intents.addAll(getOpticalPaths(two.location(), one.location()));
124 } else if (intent instanceof PointToPointIntent) {
125 PointToPointIntent p2pIntent = (PointToPointIntent) intent;
126 intents.addAll(getOpticalPaths(p2pIntent.ingressPoint(), p2pIntent.egressPoint()));
127 } else {
128 log.info("Unsupported intent type: {}", intent.getClass());
129 }
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800130
Brian O'Connor772852a2014-11-17 15:51:19 -0800131 // Build the intent batch
Brian O'Connor72a034c2014-11-26 18:24:23 -0800132 IntentOperations.Builder ops = IntentOperations.builder(appId);
Brian O'Connor772852a2014-11-17 15:51:19 -0800133 for (Intent i : intents) {
134 // TODO: don't allow duplicate intents between the same points for now
135 // we may want to allow this carefully in future to increase capacity
136 Intent existing = intentService.getIntent(i.id());
137 if (existing == null ||
138 !IntentState.WITHDRAWN.equals(intentService.getIntentState(i.id()))) {
139 ops.addSubmitOperation(i);
140 }
141 }
142 intentService.execute(ops.build());
weibit7e583462014-10-23 10:14:05 -0700143 }
144
Brian O'Connor772852a2014-11-17 15:51:19 -0800145 private List<Intent> getOpticalPaths(ConnectPoint ingress, ConnectPoint egress) {
146 Set<Path> paths = pathService.getPaths(ingress.deviceId(),
147 egress.deviceId(),
148 new OpticalLinkWeight());
149
150 if (paths.isEmpty()) {
151 return Lists.newArrayList();
weibit7e583462014-10-23 10:14:05 -0700152 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800153
154 ConnectPoint srcWdmPoint = null;
155 ConnectPoint dstWdmPoint = null;
156 Iterator<Path> itrPath = paths.iterator();
157 Path firstPath = itrPath.next();
158 log.info(firstPath.links().toString());
159
160 List<Intent> connectionList = Lists.newArrayList();
161
162 Iterator<Link> itrLink = firstPath.links().iterator();
163 while (itrLink.hasNext()) {
164 Link link1 = itrLink.next();
165 if (!isOpticalLink(link1)) {
166 continue;
167 } else {
168 srcWdmPoint = link1.dst();
169 dstWdmPoint = srcWdmPoint;
170 }
171
172 while (true) {
173 if (itrLink.hasNext()) {
174 Link link2 = itrLink.next();
175 dstWdmPoint = link2.src();
176 } else {
177 break;
178 }
179 }
180
181 Intent opticalIntent = new OpticalConnectivityIntent(appId,
182 srcWdmPoint,
183 dstWdmPoint);
184 log.info("Creating optical intent from {} to {}", srcWdmPoint, dstWdmPoint);
185 connectionList.add(opticalIntent);
186 }
187 return connectionList;
188 }
189
190
weibitf32383b2014-10-22 10:17:31 -0700191
192 private void teardownLightpath(Intent intent) {
193 // TODO: tear down the idle lightpath if the utilization is close to zero.
194 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800195 }
weibitf32383b2014-10-22 10:17:31 -0700196
Brian O'Connor772852a2014-11-17 15:51:19 -0800197 private static boolean isOpticalLink(Link link) {
198 boolean isOptical = false;
199 Link.Type lt = link.type();
200 if (lt == Link.Type.OPTICAL) {
201 isOptical = true;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800202 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800203 return isOptical;
204 }
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800205
Brian O'Connor772852a2014-11-17 15:51:19 -0800206 private static class OpticalLinkWeight implements LinkWeight {
207 @Override
208 public double weight(TopologyEdge edge) {
Praseed Balakrishnan00dd1f92014-11-19 17:12:36 -0800209 if (edge.link().state() == Link.State.INACTIVE) {
210 return -1; // ignore inactive links
211 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800212 if (isOpticalLink(edge.link())) {
213 return 1000.0; // optical links
214 } else {
215 return 1.0; // packet links
216 }
217 }
weibitf32383b2014-10-22 10:17:31 -0700218 }
219
220}