weibit

Optical Path Porvisioning

Change-Id: I9788fd9172edc8ab571aa1d41962c2bd10697c50
1 +package org.onlab.onos.optical.provisioner;
2 +
3 +import java.util.Iterator;
4 +
5 +import java.util.Set;
6 +
7 +import org.apache.felix.scr.annotations.Activate;
8 +import org.apache.felix.scr.annotations.Component;
9 +import org.apache.felix.scr.annotations.Deactivate;
10 +import org.apache.felix.scr.annotations.Reference;
11 +import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +
13 +import org.onlab.onos.ApplicationId;
14 +import org.onlab.onos.CoreService;
15 +import org.onlab.onos.net.ConnectPoint;
16 +
17 +import org.onlab.onos.net.Link;
18 +import org.onlab.onos.net.device.DeviceService;
19 +
20 +import org.onlab.onos.net.intent.IdGenerator;
21 +import org.onlab.onos.net.intent.Intent;
22 +
23 +import org.onlab.onos.net.intent.IntentEvent;
24 +import org.onlab.onos.net.intent.IntentExtensionService;
25 +import org.onlab.onos.net.intent.IntentId;
26 +import org.onlab.onos.net.intent.IntentListener;
27 +import org.onlab.onos.net.intent.IntentService;
28 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
29 +import org.onlab.onos.net.intent.PointToPointIntent;
30 +import org.onlab.onos.net.link.LinkService;
31 +import org.onlab.onos.net.topology.TopologyService;
32 +import org.slf4j.Logger;
33 +import org.slf4j.LoggerFactory;
34 +
35 +/**
36 + * OpticalPathProvisioner listens event notifications from the Intent F/W.
37 + * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
38 + * for adding/releasing capacity at the packet layer.
39 + *
40 + */
41 +
42 +@Component(immediate = true)
43 +public class OpticalPathProvisioner {
44 +
45 + protected static final Logger log = LoggerFactory
46 + .getLogger(OpticalPathProvisioner.class);
47 +
48 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 + private IntentService intentService;
50 +
51 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 + private IntentExtensionService intentExtensionService;
53 +
54 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 + protected LinkService linkService;
56 +
57 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 + protected DeviceService deviceService;
59 +
60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + protected TopologyService topologyService;
62 +
63 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 + protected CoreService coreService;
65 +
66 + // protected LinkResourceService resourceService;
67 +
68 + private ApplicationId appId;
69 + private static long intentId = 0x9000000;
70 +
71 + protected IdGenerator<IntentId> intentIdGenerator;
72 +
73 + private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
74 +
75 + @Activate
76 + protected void activate() {
77 + intentService.addListener(pathProvisioner);
78 + appId = coreService.registerApplication("org.onlab.onos.optical");
79 + log.info("Starting optical path provisoning...");
80 + }
81 +
82 + @Deactivate
83 + protected void deactivate() {
84 + intentService.removeListener(pathProvisioner);
85 + }
86 +
87 + public class InternalOpticalPathProvisioner implements IntentListener {
88 + @Override
89 + public void event(IntentEvent event) {
90 + switch (event.type()) {
91 + case SUBMITTED:
92 + break;
93 + case INSTALLED:
94 + break;
95 + case FAILED:
96 + log.info("intent {} failed, calling optical path provisioning APP.", event.subject());
97 + setuplightpath(event.subject());
98 + break;
99 + case WITHDRAWN:
100 + log.info("intent {} withdrawn.", event.subject());
101 + teardownLightpath(event.subject());
102 + break;
103 + default:
104 + break;
105 + }
106 + }
107 +
108 + private void setuplightpath(Intent intent) {
109 + // TODO: considering user policies and optical reach, may generate more OpticalConnectivityIntents
110 + if (!intent.equals(PointToPointIntent.class)) {
111 + return;
112 + }
113 +
114 + PointToPointIntent pktIntent = (PointToPointIntent) intent;
115 + if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) {
116 + return;
117 + }
118 +
119 + // Set<Port> port1 = deviceService.getPorts(pktIntent.ingressPoint().deviceId());
120 +
121 + Set<Link> srcLink = linkService.getLinks(pktIntent.ingressPoint());
122 + Set<Link> dstLink = linkService.getLinks(pktIntent.egressPoint());
123 +
124 + if (srcLink.isEmpty() || dstLink.isEmpty()) {
125 + return;
126 + }
127 +
128 + Iterator<Link> itrSrc = srcLink.iterator();
129 + Iterator<Link> itrDst = dstLink.iterator();
130 +
131 + if (!itrSrc.next().annotations().value("linkType").equals("PktOptLink")) {
132 + return;
133 + }
134 + if (!itrDst.next().annotations().value("linkType").equals("PktOptLink")) {
135 + return;
136 + }
137 +
138 + ConnectPoint srcWdmPoint = itrSrc.next().dst();
139 + ConnectPoint dstWdmPoint = itrDst.next().dst();
140 +
141 + OpticalConnectivityIntent opticalIntent =
142 + new OpticalConnectivityIntent(new IntentId(intentId++),
143 + srcWdmPoint,
144 + dstWdmPoint);
145 +
146 + log.info(opticalIntent.toString());
147 + intentService.submit(opticalIntent);
148 + }
149 +
150 + private void teardownLightpath(Intent intent) {
151 + // TODO: tear down the idle lightpath if the utilization is close to zero.
152 + }
153 +
154 + }
155 +
156 +}
1 +package org.onlab.onos.net.intent;
2 +
3 +import org.onlab.onos.net.ConnectPoint;
4 +
5 +/**
6 + * An optical layer Intent for a connectivity from a Transponder port to another
7 + * Transponder port. No trafficSelector as well as trafficTreament are needed.
8 + *
9 + */
10 +public class OpticalConnectivityIntent extends AbstractIntent {
11 + protected ConnectPoint src;
12 + protected ConnectPoint dst;
13 +
14 + /**
15 + * Constructor.
16 + *
17 + * @param id ID for this new Intent object.
18 + * @param src The source transponder port.
19 + * @param dst The destination transponder port.
20 + */
21 + public OpticalConnectivityIntent(IntentId id, ConnectPoint src, ConnectPoint dst) {
22 + super(id);
23 + this.src = src;
24 + this.dst = dst;
25 + }
26 +
27 + /**
28 + * Constructor for serializer.
29 + */
30 + protected OpticalConnectivityIntent() {
31 + super();
32 + this.src = null;
33 + this.dst = null;
34 + }
35 +
36 + /**
37 + * Gets source transponder port.
38 + *
39 + * @return The source transponder port.
40 + */
41 + public ConnectPoint getSrcConnectPoint() {
42 + return src;
43 + }
44 +
45 + /**
46 + * Gets destination transponder port.
47 + *
48 + * @return The source transponder port.
49 + */
50 + public ConnectPoint getDst() {
51 + return dst;
52 + }
53 +}
1 +package org.onlab.onos.net.intent;
2 +
3 +import java.util.Collection;
4 +import java.util.Objects;
5 +
6 +import org.onlab.onos.net.ConnectPoint;
7 +import org.onlab.onos.net.Link;
8 +import org.onlab.onos.net.Path;
9 +import org.onlab.onos.net.flow.TrafficSelector;
10 +import org.onlab.onos.net.flow.TrafficTreatment;
11 +
12 +import com.google.common.base.MoreObjects;
13 +
14 +public class OpticalPathIntent extends OpticalConnectivityIntent implements InstallableIntent {
15 +
16 + private final Path path;
17 + private final TrafficSelector opticalMatch;
18 + private final TrafficTreatment opticalAction;
19 +
20 + public OpticalPathIntent(IntentId id, TrafficSelector match, TrafficTreatment action,
21 + ConnectPoint ingressPort, ConnectPoint egressPort,
22 + Path path) {
23 + this.opticalMatch = match;
24 + this.opticalAction = action;
25 + this.path = path;
26 + }
27 +
28 + public OpticalPathIntent() {
29 + this.opticalMatch = null;
30 + this.opticalAction = null;
31 + this.path = null;
32 + }
33 +
34 + public Path path() {
35 + return path;
36 + }
37 +
38 + public TrafficSelector selector() {
39 + return opticalMatch;
40 + }
41 +
42 + public TrafficTreatment treatment() {
43 + return opticalAction;
44 + }
45 +
46 + @Override
47 + public boolean equals(Object o) {
48 + if (this == o) {
49 + return true;
50 + }
51 + if (o == null || getClass() != o.getClass()) {
52 + return false;
53 + }
54 + if (!super.equals(o)) {
55 + return false;
56 + }
57 +
58 + OpticalPathIntent that = (OpticalPathIntent) o;
59 +
60 + if (!path.equals(that.path)) {
61 + return false;
62 + }
63 +
64 + return true;
65 + }
66 +
67 + @Override
68 + public int hashCode() {
69 + return Objects.hash(super.hashCode(), path);
70 + }
71 +
72 + @Override
73 + public String toString() {
74 + return MoreObjects.toStringHelper(getClass())
75 + .add("id", id())
76 + .add("match", opticalMatch)
77 + .add("action", opticalAction)
78 + .add("ingressPort", this.getSrcConnectPoint())
79 + .add("egressPort", this.getDst())
80 + .add("path", path)
81 + .toString();
82 + }
83 +
84 + @Override
85 + public Collection<Link> requiredLinks() {
86 + return path.links();
87 + }
88 +}
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.ArrayList;
6 +
7 +import java.util.List;
8 +import java.util.Set;
9 +
10 +import org.apache.felix.scr.annotations.Activate;
11 +import org.apache.felix.scr.annotations.Component;
12 +import org.apache.felix.scr.annotations.Deactivate;
13 +import org.apache.felix.scr.annotations.Reference;
14 +import org.apache.felix.scr.annotations.ReferenceCardinality;
15 +import org.onlab.onos.net.ConnectPoint;
16 +import org.onlab.onos.net.DefaultEdgeLink;
17 +
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.Path;
20 +import org.onlab.onos.net.flow.TrafficSelector;
21 +import org.onlab.onos.net.flow.TrafficTreatment;
22 +
23 +import org.onlab.onos.net.intent.IdGenerator;
24 +import org.onlab.onos.net.intent.Intent;
25 +import org.onlab.onos.net.intent.IntentCompiler;
26 +import org.onlab.onos.net.intent.IntentExtensionService;
27 +import org.onlab.onos.net.intent.IntentId;
28 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
29 +import org.onlab.onos.net.intent.OpticalPathIntent;
30 +
31 +import org.onlab.onos.net.provider.ProviderId;
32 +import org.onlab.onos.net.topology.PathService;
33 +import org.slf4j.Logger;
34 +
35 +/**
36 + * Optical compiler for OpticalConnectivityIntent.
37 + * It firstly computes K-shortest paths in the optical-layer, then choose the optimal one to assign a wavelength.
38 + * Finally, it generates one or more opticalPathintent(s) with opticalMatchs and opticalActions.
39 + */
40 +@Component(immediate = true)
41 +public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
42 +
43 + private final Logger log = getLogger(getClass());
44 + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
45 +
46 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
47 + protected IntentExtensionService intentManager;
48 +
49 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 + protected PathService pathService;
51 +
52 + // protected LinkResourceService resourceService;
53 +
54 + protected IdGenerator<IntentId> intentIdGenerator;
55 +
56 + @Activate
57 + public void activate() {
58 + IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
59 + intentIdGenerator = new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
60 + intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
61 + }
62 +
63 + @Deactivate
64 + public void deactivate() {
65 + intentManager.unregisterCompiler(OpticalConnectivityIntent.class);
66 + }
67 +
68 + @Override
69 + public List<Intent> compile(OpticalConnectivityIntent intent) {
70 + // TO DO: compute multiple paths using the K-shortest path algorithm
71 + Path path = calculatePath(intent.getSrcConnectPoint(), intent.getDst());
72 + log.info("calculate the lightpath: {}.", path.toString());
73 +
74 + List<Link> links = new ArrayList<>();
75 + links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
76 + links.addAll(path.links());
77 + links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
78 +
79 + // TO DO: choose a wavelength using the first-fit algorithm
80 + TrafficSelector opticalSelector = null;
81 + TrafficTreatment opticalTreatment = null;
82 +
83 + List<Intent> retList = new ArrayList<>();
84 + int wavelength = assignWavelength(path);
85 + log.info("assign the wavelength: {}.", wavelength);
86 +
87 + // create a new opticalPathIntent
88 + Intent newIntent = new OpticalPathIntent(intentIdGenerator.getNewId(),
89 + opticalSelector,
90 + opticalTreatment,
91 + path.src(),
92 + path.dst(),
93 + path);
94 +
95 + retList.add(newIntent);
96 +
97 + return retList;
98 + }
99 +
100 + private Path calculatePath(ConnectPoint one, ConnectPoint two) {
101 + // TODO: K-shortest path computation algorithm
102 + Set<Path> paths = pathService.getPaths(one.deviceId(), two.deviceId());
103 + if (paths.isEmpty()) {
104 + throw new PathNotFoundException("No optical path from " + one + " to " + two);
105 + }
106 + return paths.iterator().next();
107 + }
108 +
109 + private int assignWavelength(Path path) {
110 + // TODO: wavelength assignment
111 + return 1;
112 + }
113 +
114 +}
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
4 +import static org.slf4j.LoggerFactory.getLogger;
5 +
6 +import java.util.Iterator;
7 +import java.util.List;
8 +import java.util.concurrent.Future;
9 +
10 +import org.apache.felix.scr.annotations.Activate;
11 +import org.apache.felix.scr.annotations.Component;
12 +import org.apache.felix.scr.annotations.Deactivate;
13 +import org.apache.felix.scr.annotations.Reference;
14 +import org.apache.felix.scr.annotations.ReferenceCardinality;
15 +import org.onlab.onos.ApplicationId;
16 +import org.onlab.onos.CoreService;
17 +import org.onlab.onos.net.ConnectPoint;
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.flow.CompletedBatchOperation;
20 +import org.onlab.onos.net.flow.DefaultFlowRule;
21 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
22 +import org.onlab.onos.net.flow.FlowRule;
23 +import org.onlab.onos.net.flow.FlowRuleBatchEntry;
24 +import org.onlab.onos.net.flow.FlowRuleBatchOperation;
25 +import org.onlab.onos.net.flow.FlowRuleService;
26 +import org.onlab.onos.net.flow.TrafficSelector;
27 +import org.onlab.onos.net.flow.TrafficTreatment;
28 +import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
29 +import org.onlab.onos.net.intent.IntentExtensionService;
30 +import org.onlab.onos.net.intent.IntentInstaller;
31 +import org.onlab.onos.net.intent.OpticalPathIntent;
32 +import org.slf4j.Logger;
33 +
34 +import com.google.common.collect.Lists;
35 +
36 +/**
37 + * OpticaliIntentInstaller for optical path intents.
38 + * It essentially generates optical FlowRules and
39 + * call the flowRule service to execute them.
40 + */
41 +
42 +@Component(immediate = true)
43 +public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
44 +
45 + private final Logger log = getLogger(getClass());
46 +
47 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 + protected IntentExtensionService intentManager;
49 +
50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected FlowRuleService flowRuleService;
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected CoreService coreService;
55 +
56 + private ApplicationId appId;
57 +
58 + @Activate
59 + public void activate() {
60 + appId = coreService.registerApplication("org.onlab.onos.net.intent");
61 + intentManager.registerInstaller(OpticalPathIntent.class, this);
62 + }
63 +
64 + @Deactivate
65 + public void deactivate() {
66 + intentManager.unregisterInstaller(OpticalPathIntent.class);
67 + }
68 +
69 + @Override
70 + public Future<CompletedBatchOperation> install(OpticalPathIntent intent) {
71 + TrafficSelector.Builder builder =
72 + DefaultTrafficSelector.builder(intent.selector());
73 + Iterator<Link> links = intent.path().links().iterator();
74 + ConnectPoint prev = links.next().dst();
75 + List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
76 + while (links.hasNext()) {
77 + builder.matchInport(prev.port());
78 + Link link = links.next();
79 + TrafficTreatment treatment = builder()
80 + .setOutput(link.src().port()).build();
81 +
82 + FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
83 + builder.build(),
84 + treatment,
85 + 100, // priority is set to 100
86 + appId,
87 + 100); // ROADM may need longer cross-connect time, here it is assumed 100ms.
88 +
89 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
90 + prev = link.dst();
91 + }
92 +
93 + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
94 + Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
95 + return future;
96 + }
97 +
98 + @Override
99 + public Future<CompletedBatchOperation> uninstall(OpticalPathIntent intent) {
100 + TrafficSelector.Builder builder =
101 + DefaultTrafficSelector.builder(intent.selector());
102 + Iterator<Link> links = intent.path().links().iterator();
103 + ConnectPoint prev = links.next().dst();
104 + List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
105 +
106 + while (links.hasNext()) {
107 + builder.matchInport(prev.port());
108 + Link link = links.next();
109 + TrafficTreatment treatment = builder()
110 + .setOutput(link.src().port()).build();
111 +
112 + FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
113 + builder.build(),
114 + treatment,
115 + 100,
116 + appId,
117 + 100);
118 +
119 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
120 + prev = link.dst();
121 + }
122 +
123 + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
124 + Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
125 + return future;
126 + }
127 +
128 +}