blob: dd6a8e2571c352dd04ea4e143a9c1bf55cfe0e2e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.onlab.onos.optical.provisioner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.core.CoreService;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentEvent;
import org.onlab.onos.net.intent.IntentExtensionService;
import org.onlab.onos.net.intent.IntentListener;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.OpticalConnectivityIntent;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.resource.LinkResourceService;
import org.onlab.onos.net.topology.LinkWeight;
import org.onlab.onos.net.topology.Topology;
import org.onlab.onos.net.topology.TopologyEdge;
import org.onlab.onos.net.topology.TopologyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* OpticalPathProvisioner listens event notifications from the Intent F/W.
* It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
* for adding/releasing capacity at the packet layer.
*
*/
@Component(immediate = true)
public class OpticalPathProvisioner {
protected static final Logger log = LoggerFactory
.getLogger(OpticalPathProvisioner.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private IntentService intentService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private IntentExtensionService intentExtensionService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LinkService linkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LinkResourceService resourceService;
private ApplicationId appId;
//protected <IntentId> intentIdGenerator;
private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
@Activate
protected void activate() {
intentService.addListener(pathProvisioner);
appId = coreService.registerApplication("org.onlab.onos.optical");
log.info("Starting optical path provisoning...");
}
@Deactivate
protected void deactivate() {
intentService.removeListener(pathProvisioner);
}
public class InternalOpticalPathProvisioner implements IntentListener {
@Override
public void event(IntentEvent event) {
switch (event.type()) {
case SUBMITTED:
break;
case INSTALLED:
break;
case FAILED:
log.info("packet intent {} failed, calling optical path provisioning APP.", event.subject());
setuplightpath(event.subject());
break;
case WITHDRAWN:
log.info("intent {} withdrawn.", event.subject());
teardownLightpath(event.subject());
break;
default:
break;
}
}
private void setuplightpath(Intent intent) {
// TODO support more packet intent types
if (!intent.getClass().equals(PointToPointIntent.class)) {
return;
}
PointToPointIntent pktIntent = (PointToPointIntent) intent;
if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) {
return;
}
Topology topology = topologyService.currentTopology();
LinkWeight weight = new LinkWeight() {
@Override
public double weight(TopologyEdge edge) {
if (isOpticalLink(edge.link())) {
return 1000.0; // optical links
} else {
return 1.0; // packet links
}
}
};
Set<Path> paths = topologyService.getPaths(topology,
pktIntent.ingressPoint().deviceId(),
pktIntent.egressPoint().deviceId(),
weight);
if (paths.isEmpty()) {
return;
}
ConnectPoint srcWdmPoint = null;
ConnectPoint dstWdmPoint = null;
Iterator<Path> itrPath = paths.iterator();
Path firstPath = itrPath.next();
log.info(firstPath.toString());
ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList = new ArrayList<>();
Iterator<Link> itrLink = firstPath.links().iterator();
while (itrLink.hasNext()) {
Link link1 = itrLink.next();
if (!isOpticalLink(link1)) {
continue;
} else {
srcWdmPoint = link1.dst();
dstWdmPoint = srcWdmPoint;
}
while (true) {
if (itrLink.hasNext()) {
Link link2 = itrLink.next();
dstWdmPoint = link2.src();
} else {
break;
}
if (itrLink.hasNext()) {
Link link3 = itrLink.next();
if (!isOpticalLink(link3)) {
break;
}
} else {
break;
}
}
Map<ConnectPoint, ConnectPoint> pair =
new HashMap<ConnectPoint, ConnectPoint>();
pair.put(srcWdmPoint, dstWdmPoint);
connectionList.add(pair);
}
for (Map<ConnectPoint, ConnectPoint> map : connectionList) {
for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) {
ConnectPoint src = entry.getKey();
ConnectPoint dst = entry.getValue();
Intent opticalIntent = new OpticalConnectivityIntent(appId,
srcWdmPoint,
dstWdmPoint);
intentService.submit(opticalIntent);
log.info(opticalIntent.toString());
}
}
}
private boolean isOpticalLink(Link link) {
boolean isOptical = false;
Link.Type lt = link.type();
if (lt == Link.Type.OPTICAL) {
isOptical = true;
}
return isOptical;
}
private void teardownLightpath(Intent intent) {
// TODO: tear down the idle lightpath if the utilization is close to zero.
}
}
}