Merge branch 'optical-integration' of ssh://gerrit.onlab.us:29418/onos-next into optical-integration
Showing
11 changed files
with
856 additions
and
2 deletions
apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
0 → 100644
1 | +package org.onlab.onos.optical.provisioner; | ||
2 | + | ||
3 | +import java.util.ArrayList; | ||
4 | +import java.util.HashMap; | ||
5 | +import java.util.Iterator; | ||
6 | +import java.util.Map; | ||
7 | +import java.util.Map.Entry; | ||
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.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.Path; | ||
20 | +import org.onlab.onos.net.device.DeviceService; | ||
21 | +import org.onlab.onos.net.intent.Intent; | ||
22 | +import org.onlab.onos.net.intent.IntentEvent; | ||
23 | +import org.onlab.onos.net.intent.IntentExtensionService; | ||
24 | +import org.onlab.onos.net.intent.IntentListener; | ||
25 | +import org.onlab.onos.net.intent.IntentService; | ||
26 | +import org.onlab.onos.net.intent.OpticalConnectivityIntent; | ||
27 | +import org.onlab.onos.net.intent.PointToPointIntent; | ||
28 | +import org.onlab.onos.net.link.LinkService; | ||
29 | +import org.onlab.onos.net.resource.LinkResourceService; | ||
30 | +import org.onlab.onos.net.topology.LinkWeight; | ||
31 | +import org.onlab.onos.net.topology.Topology; | ||
32 | +import org.onlab.onos.net.topology.TopologyEdge; | ||
33 | + | ||
34 | +import org.onlab.onos.net.topology.TopologyService; | ||
35 | +import org.slf4j.Logger; | ||
36 | +import org.slf4j.LoggerFactory; | ||
37 | + | ||
38 | +/** | ||
39 | + * OpticalPathProvisioner listens event notifications from the Intent F/W. | ||
40 | + * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W | ||
41 | + * for adding/releasing capacity at the packet layer. | ||
42 | + * | ||
43 | + */ | ||
44 | + | ||
45 | +@Component(immediate = true) | ||
46 | +public class OpticalPathProvisioner { | ||
47 | + | ||
48 | + protected static final Logger log = LoggerFactory | ||
49 | + .getLogger(OpticalPathProvisioner.class); | ||
50 | + | ||
51 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
52 | + private IntentService intentService; | ||
53 | + | ||
54 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
55 | + private IntentExtensionService intentExtensionService; | ||
56 | + | ||
57 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
58 | + protected LinkService linkService; | ||
59 | + | ||
60 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
61 | + protected DeviceService deviceService; | ||
62 | + | ||
63 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
64 | + protected TopologyService topologyService; | ||
65 | + | ||
66 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
67 | + protected CoreService coreService; | ||
68 | + | ||
69 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
70 | + protected LinkResourceService resourceService; | ||
71 | + | ||
72 | + private ApplicationId appId; | ||
73 | + | ||
74 | + //protected <IntentId> intentIdGenerator; | ||
75 | + | ||
76 | + private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner(); | ||
77 | + | ||
78 | + @Activate | ||
79 | + protected void activate() { | ||
80 | + intentService.addListener(pathProvisioner); | ||
81 | + appId = coreService.registerApplication("org.onlab.onos.optical"); | ||
82 | + log.info("Starting optical path provisoning..."); | ||
83 | + } | ||
84 | + | ||
85 | + @Deactivate | ||
86 | + protected void deactivate() { | ||
87 | + intentService.removeListener(pathProvisioner); | ||
88 | + } | ||
89 | + | ||
90 | + public class InternalOpticalPathProvisioner implements IntentListener { | ||
91 | + @Override | ||
92 | + public void event(IntentEvent event) { | ||
93 | + switch (event.type()) { | ||
94 | + case SUBMITTED: | ||
95 | + break; | ||
96 | + case INSTALLED: | ||
97 | + break; | ||
98 | + case FAILED: | ||
99 | + log.info("intent {} failed, calling optical path provisioning APP.", event.subject()); | ||
100 | + setuplightpath(event.subject()); | ||
101 | + break; | ||
102 | + case WITHDRAWN: | ||
103 | + log.info("intent {} withdrawn.", event.subject()); | ||
104 | + teardownLightpath(event.subject()); | ||
105 | + break; | ||
106 | + default: | ||
107 | + break; | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + private void setuplightpath(Intent intent) { | ||
112 | + // TODO: considering user policies and optical reach | ||
113 | + if (!intent.equals(PointToPointIntent.class)) { | ||
114 | + return; | ||
115 | + } | ||
116 | + | ||
117 | + PointToPointIntent pktIntent = (PointToPointIntent) intent; | ||
118 | + if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) { | ||
119 | + return; | ||
120 | + } | ||
121 | + | ||
122 | + Topology topology = topologyService.currentTopology(); | ||
123 | + | ||
124 | + LinkWeight weight = new LinkWeight() { | ||
125 | + @Override | ||
126 | + public double weight(TopologyEdge edge) { | ||
127 | + boolean isOptical = false; | ||
128 | + String t = edge.link().annotations().value("linkType"); | ||
129 | + if (t.equals("WDM")) { | ||
130 | + isOptical = true; | ||
131 | + } | ||
132 | + if (isOptical) { | ||
133 | + return 1000; // optical links | ||
134 | + } else { | ||
135 | + return 10; // packet links | ||
136 | + } | ||
137 | + } | ||
138 | + }; | ||
139 | + | ||
140 | + Set<Path> paths = topologyService.getPaths(topology, | ||
141 | + pktIntent.ingressPoint().deviceId(), | ||
142 | + pktIntent.egressPoint().deviceId(), | ||
143 | + weight); | ||
144 | + | ||
145 | + if (paths.isEmpty()) { | ||
146 | + return; | ||
147 | + } | ||
148 | + | ||
149 | + ConnectPoint srcWdmPoint = null; | ||
150 | + ConnectPoint dstWdmPoint = null; | ||
151 | + Iterator<Path> itrPath = paths.iterator(); | ||
152 | + Path firstPath = itrPath.next(); | ||
153 | + log.info(firstPath.toString()); | ||
154 | + | ||
155 | + ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList = new ArrayList<>(); | ||
156 | + | ||
157 | + Iterator<Link> itrLink = firstPath.links().iterator(); | ||
158 | + while (itrLink.hasNext()) { | ||
159 | + Link link1 = itrLink.next(); | ||
160 | + if (!isOpticalLink(link1)) { | ||
161 | + continue; | ||
162 | + } else { | ||
163 | + srcWdmPoint = link1.dst(); | ||
164 | + dstWdmPoint = srcWdmPoint; | ||
165 | + } | ||
166 | + | ||
167 | + while (true) { | ||
168 | + | ||
169 | + if (itrLink.hasNext()) { | ||
170 | + Link link2 = itrLink.next(); | ||
171 | + dstWdmPoint = link2.src(); | ||
172 | + } else { | ||
173 | + break; | ||
174 | + } | ||
175 | + | ||
176 | + if (itrLink.hasNext()) { | ||
177 | + Link link3 = itrLink.next(); | ||
178 | + if (!isOpticalLink(link3)) { | ||
179 | + break; | ||
180 | + } | ||
181 | + } else { | ||
182 | + break; | ||
183 | + } | ||
184 | + } | ||
185 | + | ||
186 | + Map<ConnectPoint, ConnectPoint> pair = | ||
187 | + new HashMap<ConnectPoint, ConnectPoint>(); | ||
188 | + pair.put(srcWdmPoint, dstWdmPoint); | ||
189 | + | ||
190 | + connectionList.add(pair); | ||
191 | + } | ||
192 | + | ||
193 | + for (Map<ConnectPoint, ConnectPoint> map : connectionList) { | ||
194 | + for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) { | ||
195 | + | ||
196 | + ConnectPoint src = entry.getKey(); | ||
197 | + ConnectPoint dst = entry.getValue(); | ||
198 | + | ||
199 | + Intent opticalIntent = new OpticalConnectivityIntent(appId, | ||
200 | + srcWdmPoint, | ||
201 | + dstWdmPoint); | ||
202 | + | ||
203 | + intentService.submit(opticalIntent); | ||
204 | + | ||
205 | + log.info(opticalIntent.toString()); | ||
206 | + } | ||
207 | + } | ||
208 | + | ||
209 | + } | ||
210 | + | ||
211 | + private boolean isOpticalLink(Link link) { | ||
212 | + boolean isOptical = false; | ||
213 | + String t = link.annotations().value("linkType"); | ||
214 | + if (t.equals("WDM") || t.equals("PktOptLink")) { | ||
215 | + isOptical = true; | ||
216 | + } | ||
217 | + return isOptical; | ||
218 | + } | ||
219 | + | ||
220 | + private void teardownLightpath(Intent intent) { | ||
221 | + // TODO: tear down the idle lightpath if the utilization is close to zero. | ||
222 | + } | ||
223 | + | ||
224 | + } | ||
225 | + | ||
226 | +} |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import org.onlab.onos.ApplicationId; | ||
4 | +import org.onlab.onos.net.ConnectPoint; | ||
5 | + | ||
6 | +/** | ||
7 | + * An optical layer Intent for a connectivity from one Transponder port to another | ||
8 | + * Transponder port. No trafficSelector as well as trafficTreament are needed. | ||
9 | + * | ||
10 | + */ | ||
11 | +public class OpticalConnectivityIntent extends Intent { | ||
12 | + protected ConnectPoint src; | ||
13 | + protected ConnectPoint dst; | ||
14 | + | ||
15 | + /** | ||
16 | + * Constructor. | ||
17 | + * | ||
18 | + * @param id ID for this new Intent object. | ||
19 | + * @param src The source transponder port. | ||
20 | + * @param dst The destination transponder port. | ||
21 | + */ | ||
22 | + public OpticalConnectivityIntent(ApplicationId appId, ConnectPoint src, ConnectPoint dst) { | ||
23 | + super(id(OpticalConnectivityIntent.class, src, dst), | ||
24 | + appId, null); | ||
25 | + this.src = src; | ||
26 | + this.dst = dst; | ||
27 | + } | ||
28 | + | ||
29 | + /** | ||
30 | + * Constructor for serializer. | ||
31 | + */ | ||
32 | + protected OpticalConnectivityIntent() { | ||
33 | + super(); | ||
34 | + this.src = null; | ||
35 | + this.dst = null; | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Gets source transponder port. | ||
40 | + * | ||
41 | + * @return The source transponder port. | ||
42 | + */ | ||
43 | + public ConnectPoint getSrcConnectPoint() { | ||
44 | + return src; | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Gets destination transponder port. | ||
49 | + * | ||
50 | + * @return The source transponder port. | ||
51 | + */ | ||
52 | + public ConnectPoint getDst() { | ||
53 | + return dst; | ||
54 | + } | ||
55 | +} |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | + | ||
5 | +import org.onlab.onos.ApplicationId; | ||
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 { | ||
15 | + private final Path path; | ||
16 | + // private final TrafficSelector opticalMatch; | ||
17 | + // private final TrafficTreatment opticalAction; | ||
18 | + | ||
19 | + public OpticalPathIntent(ApplicationId appId, | ||
20 | + ConnectPoint src, | ||
21 | + ConnectPoint dst, | ||
22 | + TrafficSelector match, | ||
23 | + TrafficTreatment action, | ||
24 | + Path path) { | ||
25 | + super(appId, src, dst); | ||
26 | + // this.opticalMatch = match; | ||
27 | + // this.opticalAction = action; | ||
28 | + this.path = path; | ||
29 | + } | ||
30 | + | ||
31 | + protected OpticalPathIntent() { | ||
32 | + // this.opticalMatch = null; | ||
33 | + // this.opticalAction = null; | ||
34 | + this.path = null; | ||
35 | + } | ||
36 | + | ||
37 | + public Path path() { | ||
38 | + return path; | ||
39 | + } | ||
40 | +/* | ||
41 | + public TrafficSelector selector() { | ||
42 | + // return opticalMatch; | ||
43 | + } | ||
44 | + | ||
45 | + public TrafficTreatment treatment() { | ||
46 | + // return opticalAction; | ||
47 | + } | ||
48 | +*/ | ||
49 | + @Override | ||
50 | + public boolean isInstallable() { | ||
51 | + return true; | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public String toString() { | ||
56 | + return MoreObjects.toStringHelper(getClass()) | ||
57 | + .add("id", id()) | ||
58 | + //.add("match", opticalMatch) | ||
59 | + //.add("action", opticalAction) | ||
60 | + .add("ingressPort", this.getSrcConnectPoint()) | ||
61 | + .add("egressPort", this.getDst()) | ||
62 | + .add("path", path) | ||
63 | + .toString(); | ||
64 | + } | ||
65 | + | ||
66 | + public Collection<Link> requiredLinks() { | ||
67 | + return path.links(); | ||
68 | + } | ||
69 | +} |
... | @@ -33,4 +33,9 @@ public class BandwidthResourceRequest implements ResourceRequest { | ... | @@ -33,4 +33,9 @@ public class BandwidthResourceRequest implements ResourceRequest { |
33 | public Bandwidth bandwidth() { | 33 | public Bandwidth bandwidth() { |
34 | return bandwidth; | 34 | return bandwidth; |
35 | } | 35 | } |
36 | + | ||
37 | + @Override | ||
38 | + public ResourceType type() { | ||
39 | + return ResourceType.BANDWIDTH; | ||
40 | + } | ||
36 | } | 41 | } | ... | ... |
... | @@ -34,6 +34,12 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest { | ... | @@ -34,6 +34,12 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest { |
34 | this.resources = ImmutableSet.copyOf(resources); | 34 | this.resources = ImmutableSet.copyOf(resources); |
35 | } | 35 | } |
36 | 36 | ||
37 | + | ||
38 | + @Override | ||
39 | + public ResourceType type() { | ||
40 | + return null; | ||
41 | + } | ||
42 | + | ||
37 | @Override | 43 | @Override |
38 | public IntentId intendId() { | 44 | public IntentId intendId() { |
39 | return intentId; | 45 | return intentId; | ... | ... |
... | @@ -5,4 +5,9 @@ package org.onlab.onos.net.resource; | ... | @@ -5,4 +5,9 @@ package org.onlab.onos.net.resource; |
5 | */ | 5 | */ |
6 | public class LambdaResourceRequest implements ResourceRequest { | 6 | public class LambdaResourceRequest implements ResourceRequest { |
7 | 7 | ||
8 | + @Override | ||
9 | + public ResourceType type() { | ||
10 | + return ResourceType.LAMBDA; | ||
11 | + } | ||
12 | + | ||
8 | } | 13 | } | ... | ... |
... | @@ -4,5 +4,11 @@ package org.onlab.onos.net.resource; | ... | @@ -4,5 +4,11 @@ package org.onlab.onos.net.resource; |
4 | * Abstraction of resource request. | 4 | * Abstraction of resource request. |
5 | */ | 5 | */ |
6 | public interface ResourceRequest { | 6 | public interface ResourceRequest { |
7 | + /** | ||
8 | + * Returns the resource type. | ||
9 | + * | ||
10 | + * @return the resource type | ||
11 | + */ | ||
12 | + ResourceType type(); | ||
7 | 13 | ||
8 | } | 14 | } | ... | ... |
core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
0 → 100644
1 | +package org.onlab.onos.net.intent.impl; | ||
2 | + | ||
3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | + | ||
5 | +import java.util.ArrayList; | ||
6 | +import java.util.Iterator; | ||
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.CoreService; | ||
16 | +import org.onlab.onos.net.ConnectPoint; | ||
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.Intent; | ||
24 | +import org.onlab.onos.net.intent.IntentCompiler; | ||
25 | +import org.onlab.onos.net.intent.IntentExtensionService; | ||
26 | + | ||
27 | +import org.onlab.onos.net.intent.OpticalConnectivityIntent; | ||
28 | +import org.onlab.onos.net.intent.OpticalPathIntent; | ||
29 | +import org.onlab.onos.net.provider.ProviderId; | ||
30 | +import org.onlab.onos.net.resource.LinkResourceService; | ||
31 | +import org.onlab.onos.net.topology.LinkWeight; | ||
32 | +import org.onlab.onos.net.topology.PathService; | ||
33 | +import org.onlab.onos.net.topology.Topology; | ||
34 | +import org.onlab.onos.net.topology.TopologyEdge; | ||
35 | + | ||
36 | +import org.onlab.onos.net.topology.TopologyService; | ||
37 | +import org.slf4j.Logger; | ||
38 | + | ||
39 | +/** | ||
40 | + * Optical compiler for OpticalConnectivityIntent. | ||
41 | + * It firstly computes K-shortest paths in the optical-layer, then choose the optimal one to assign a wavelength. | ||
42 | + * Finally, it generates one or more opticalPathintent(s) with opticalMatchs and opticalActions. | ||
43 | + */ | ||
44 | +@Component(immediate = true) | ||
45 | +public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> { | ||
46 | + | ||
47 | + private final Logger log = getLogger(getClass()); | ||
48 | + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true); | ||
49 | + | ||
50 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
51 | + protected IntentExtensionService intentManager; | ||
52 | + | ||
53 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
54 | + protected PathService pathService; | ||
55 | + | ||
56 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
57 | + protected TopologyService topologyService; | ||
58 | + | ||
59 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
60 | + protected LinkResourceService resourceService; | ||
61 | + | ||
62 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
63 | + protected CoreService coreService; | ||
64 | + | ||
65 | + @Activate | ||
66 | + public void activate() { | ||
67 | + intentManager.registerCompiler(OpticalConnectivityIntent.class, this); | ||
68 | + } | ||
69 | + | ||
70 | + @Deactivate | ||
71 | + public void deactivate() { | ||
72 | + intentManager.unregisterCompiler(OpticalConnectivityIntent.class); | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public List<Intent> compile(OpticalConnectivityIntent intent) { | ||
77 | + // TODO: compute multiple paths using the K-shortest path algorithm | ||
78 | + List<Intent> retList = new ArrayList<>(); | ||
79 | + Path path = calculatePath(intent.getSrcConnectPoint(), intent.getDst()); | ||
80 | + if (path == null) { | ||
81 | + return retList; | ||
82 | + } else { | ||
83 | + log.info("the computed lightpath is : {}.", path.toString()); | ||
84 | + } | ||
85 | + | ||
86 | + List<Link> links = new ArrayList<>(); | ||
87 | + // links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true)); | ||
88 | + links.addAll(path.links()); | ||
89 | + //links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false)); | ||
90 | + | ||
91 | + TrafficSelector opticalSelector = null; | ||
92 | + TrafficTreatment opticalTreatment = null; | ||
93 | + | ||
94 | + // create a new opticalPathIntent | ||
95 | + Intent newIntent = new OpticalPathIntent(intent.appId(), | ||
96 | + path.src(), | ||
97 | + path.dst(), | ||
98 | + opticalSelector, | ||
99 | + opticalTreatment, | ||
100 | + path); | ||
101 | + | ||
102 | + retList.add(newIntent); | ||
103 | + | ||
104 | + return retList; | ||
105 | + } | ||
106 | + | ||
107 | + private Path calculatePath(ConnectPoint start, ConnectPoint end) { | ||
108 | + // TODO: support user policies | ||
109 | + Topology topology = topologyService.currentTopology(); | ||
110 | + LinkWeight weight = new LinkWeight() { | ||
111 | + @Override | ||
112 | + public double weight(TopologyEdge edge) { | ||
113 | + boolean isOptical = false; | ||
114 | + String t = edge.link().annotations().value("linkType"); | ||
115 | + if (t.equals("WDM")) { | ||
116 | + isOptical = true; | ||
117 | + } | ||
118 | + if (isOptical) { | ||
119 | + return 1; // optical links | ||
120 | + } else { | ||
121 | + return 10000; // packet links | ||
122 | + } | ||
123 | + } | ||
124 | + }; | ||
125 | + | ||
126 | + Set<Path> paths = topologyService.getPaths(topology, | ||
127 | + start.deviceId(), | ||
128 | + end.deviceId(), | ||
129 | + weight); | ||
130 | + | ||
131 | + Iterator<Path> itr = paths.iterator(); | ||
132 | + while (itr.hasNext()) { | ||
133 | + Path path = itr.next(); | ||
134 | + if (path.cost() >= 10000) { | ||
135 | + itr.remove(); | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + if (paths.isEmpty()) { | ||
140 | + log.info("No optical path found from " + start + " to " + end); | ||
141 | + return null; | ||
142 | + } else { | ||
143 | + return paths.iterator().next(); | ||
144 | + } | ||
145 | + | ||
146 | + } | ||
147 | + | ||
148 | +} |
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 | + | ||
7 | +import java.util.List; | ||
8 | + | ||
9 | +import org.apache.felix.scr.annotations.Activate; | ||
10 | +import org.apache.felix.scr.annotations.Component; | ||
11 | +import org.apache.felix.scr.annotations.Deactivate; | ||
12 | +import org.apache.felix.scr.annotations.Reference; | ||
13 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
14 | +import org.onlab.onos.ApplicationId; | ||
15 | +import org.onlab.onos.CoreService; | ||
16 | +import org.onlab.onos.net.ConnectPoint; | ||
17 | +import org.onlab.onos.net.Link; | ||
18 | +import org.onlab.onos.net.flow.DefaultFlowRule; | ||
19 | +import org.onlab.onos.net.flow.DefaultTrafficSelector; | ||
20 | +import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
21 | +import org.onlab.onos.net.flow.FlowRule; | ||
22 | +import org.onlab.onos.net.flow.FlowRuleBatchEntry; | ||
23 | +import org.onlab.onos.net.flow.FlowRuleBatchOperation; | ||
24 | +import org.onlab.onos.net.flow.FlowRuleService; | ||
25 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
26 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
27 | +import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation; | ||
28 | +import org.onlab.onos.net.intent.IntentExtensionService; | ||
29 | +import org.onlab.onos.net.intent.IntentInstaller; | ||
30 | +import org.onlab.onos.net.intent.OpticalPathIntent; | ||
31 | +import org.onlab.onos.net.resource.DefaultLinkResourceRequest; | ||
32 | +import org.onlab.onos.net.resource.Lambda; | ||
33 | +import org.onlab.onos.net.resource.LambdaResourceAllocation; | ||
34 | +import org.onlab.onos.net.resource.LinkResourceAllocations; | ||
35 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
36 | +import org.onlab.onos.net.resource.LinkResourceService; | ||
37 | +import org.onlab.onos.net.resource.ResourceAllocation; | ||
38 | +import org.onlab.onos.net.resource.ResourceType; | ||
39 | +import org.onlab.onos.net.topology.TopologyService; | ||
40 | +import org.slf4j.Logger; | ||
41 | + | ||
42 | +import com.google.common.collect.Lists; | ||
43 | + | ||
44 | +/** | ||
45 | + * OpticaliIntentInstaller for optical path intents. | ||
46 | + * It essentially generates optical FlowRules and | ||
47 | + * call the flowRule service to execute them. | ||
48 | + */ | ||
49 | + | ||
50 | +@Component(immediate = true) | ||
51 | +public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> { | ||
52 | + private final Logger log = getLogger(getClass()); | ||
53 | + | ||
54 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
55 | + protected IntentExtensionService intentManager; | ||
56 | + | ||
57 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
58 | + protected FlowRuleService flowRuleService; | ||
59 | + | ||
60 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
61 | + protected CoreService coreService; | ||
62 | + | ||
63 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
64 | + protected TopologyService topologyService; | ||
65 | + | ||
66 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
67 | + protected LinkResourceService resourceService; | ||
68 | + | ||
69 | + private ApplicationId appId; | ||
70 | + | ||
71 | + //final short WAVELENGTH = 80; | ||
72 | + | ||
73 | + @Activate | ||
74 | + public void activate() { | ||
75 | + appId = coreService.registerApplication("org.onlab.onos.net.intent"); | ||
76 | + intentManager.registerInstaller(OpticalPathIntent.class, this); | ||
77 | + } | ||
78 | + | ||
79 | + @Deactivate | ||
80 | + public void deactivate() { | ||
81 | + intentManager.unregisterInstaller(OpticalPathIntent.class); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) { | ||
86 | + LinkResourceAllocations allocations = assignWavelength(intent); | ||
87 | + | ||
88 | + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); | ||
89 | + selectorBuilder.matchInport(intent.getSrcConnectPoint().port()); | ||
90 | + | ||
91 | + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | ||
92 | + | ||
93 | + List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | ||
94 | + ConnectPoint prev = intent.getSrcConnectPoint(); | ||
95 | + | ||
96 | + //TODO throw exception if the lambda was not assigned successfully | ||
97 | + for (Link link : intent.path().links()) { | ||
98 | + Lambda la = null; | ||
99 | + for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) { | ||
100 | + if (allocation.type() == ResourceType.LAMBDA) { | ||
101 | + la = ((LambdaResourceAllocation) allocation).lambda(); | ||
102 | + break; | ||
103 | + } | ||
104 | + } | ||
105 | + | ||
106 | + if (la == null) { | ||
107 | + log.info("Lambda was not assigned successfully"); | ||
108 | + return null; | ||
109 | + } | ||
110 | + | ||
111 | + treatmentBuilder.setOutput(link.src().port()); | ||
112 | + //treatmentBuilder.setLambda(la.toInt()); | ||
113 | + | ||
114 | + FlowRule rule = new DefaultFlowRule(prev.deviceId(), | ||
115 | + selectorBuilder.build(), | ||
116 | + treatmentBuilder.build(), | ||
117 | + 100, | ||
118 | + appId, | ||
119 | + 100, | ||
120 | + true); | ||
121 | + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); | ||
122 | + | ||
123 | + prev = link.dst(); | ||
124 | + selectorBuilder.matchInport(link.dst().port()); | ||
125 | + //selectorBuilder.setLambda(la.toInt()); | ||
126 | + } | ||
127 | + | ||
128 | + // build the last T port rule | ||
129 | + TrafficTreatment treatmentLast = builder() | ||
130 | + .setOutput(intent.getDst().port()).build(); | ||
131 | + FlowRule rule = new DefaultFlowRule(intent.getDst().deviceId(), | ||
132 | + selectorBuilder.build(), | ||
133 | + treatmentLast, | ||
134 | + 100, | ||
135 | + appId, | ||
136 | + 100, | ||
137 | + true); | ||
138 | + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); | ||
139 | + | ||
140 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | ||
141 | + } | ||
142 | + | ||
143 | + private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) { | ||
144 | + LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(), | ||
145 | + intent.path().links()) | ||
146 | + .addLambdaRequest(); | ||
147 | + LinkResourceAllocations retLambda = resourceService.requestResources(request.build()); | ||
148 | + return retLambda; | ||
149 | + } | ||
150 | + | ||
151 | + /*private Lambda assignWavelength(List<Link> links) { | ||
152 | + // TODO More wavelength assignment algorithm | ||
153 | + int wavenum = 0; | ||
154 | + Iterator<Link> itrlink = links.iterator(); | ||
155 | + for (int i = 1; i <= WAVELENGTH; i++) { | ||
156 | + wavenum = i; | ||
157 | + boolean found = true; | ||
158 | + while (itrlink.hasNext()) { | ||
159 | + Link link = itrlink.next(); | ||
160 | + if (isWavelengthUsed(link, i)) { | ||
161 | + found = false; | ||
162 | + break; | ||
163 | + } | ||
164 | + } | ||
165 | + // First-Fit wavelength assignment algorithm | ||
166 | + if (found) { | ||
167 | + break; | ||
168 | + } | ||
169 | + } | ||
170 | + | ||
171 | + if (wavenum == 0) { | ||
172 | + return null; | ||
173 | + } | ||
174 | + | ||
175 | + Lambda wave = Lambda.valueOf(wavenum); | ||
176 | + return wave; | ||
177 | + } | ||
178 | + | ||
179 | + private boolean isWavelengthUsed(Link link, int i) { | ||
180 | + Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link); | ||
181 | + for (LinkResourceAllocations ir : wave) { | ||
182 | + //if ir.resources().contains(i) { | ||
183 | + //} | ||
184 | + } | ||
185 | + return false; | ||
186 | + }*/ | ||
187 | + | ||
188 | + @Override | ||
189 | + public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) { | ||
190 | + LinkResourceAllocations allocations = resourceService.getAllocation(intent.id()); | ||
191 | + | ||
192 | + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); | ||
193 | + selectorBuilder.matchInport(intent.getSrcConnectPoint().port()); | ||
194 | + | ||
195 | + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | ||
196 | + | ||
197 | + List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | ||
198 | + ConnectPoint prev = intent.getSrcConnectPoint(); | ||
199 | + | ||
200 | + //TODO throw exception if the lambda was not retrieved successfully | ||
201 | + for (Link link : intent.path().links()) { | ||
202 | + Lambda la = null; | ||
203 | + for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) { | ||
204 | + if (allocation.type() == ResourceType.LAMBDA) { | ||
205 | + la = ((LambdaResourceAllocation) allocation).lambda(); | ||
206 | + break; | ||
207 | + } | ||
208 | + } | ||
209 | + | ||
210 | + if (la == null) { | ||
211 | + log.info("Lambda was not retrieved successfully"); | ||
212 | + return null; | ||
213 | + } | ||
214 | + | ||
215 | + treatmentBuilder.setOutput(link.src().port()); | ||
216 | + //treatmentBuilder.setLambda(la.toInt()); | ||
217 | + | ||
218 | + FlowRule rule = new DefaultFlowRule(prev.deviceId(), | ||
219 | + selectorBuilder.build(), | ||
220 | + treatmentBuilder.build(), | ||
221 | + 100, | ||
222 | + appId, | ||
223 | + 100, | ||
224 | + true); | ||
225 | + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); | ||
226 | + | ||
227 | + prev = link.dst(); | ||
228 | + selectorBuilder.matchInport(link.dst().port()); | ||
229 | + //selectorBuilder.setLambda(la.toInt()); | ||
230 | + } | ||
231 | + | ||
232 | + // build the last T port rule | ||
233 | + TrafficTreatment treatmentLast = builder() | ||
234 | + .setOutput(intent.getDst().port()).build(); | ||
235 | + FlowRule rule = new DefaultFlowRule(intent.getDst().deviceId(), | ||
236 | + selectorBuilder.build(), | ||
237 | + treatmentLast, | ||
238 | + 100, | ||
239 | + appId, | ||
240 | + 100, | ||
241 | + true); | ||
242 | + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); | ||
243 | + | ||
244 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | ||
245 | + } | ||
246 | + | ||
247 | +} |
1 | +package org.onlab.onos.net.resource; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | +import java.util.Collections; | ||
5 | +import java.util.Map; | ||
6 | +import java.util.Set; | ||
7 | + | ||
8 | +import org.onlab.onos.net.Link; | ||
9 | +import org.onlab.onos.net.intent.IntentId; | ||
10 | + | ||
11 | +/** | ||
12 | + * Implementation of {@link LinkResourceAllocations}. | ||
13 | + */ | ||
14 | +public class DefaultLinkResourceAllocations implements LinkResourceAllocations { | ||
15 | + private final LinkResourceRequest request; | ||
16 | + private final Map<Link, Set<ResourceAllocation>> allocations; | ||
17 | + | ||
18 | + /** | ||
19 | + * Creates a new link resource allocations. | ||
20 | + * | ||
21 | + * @param request requested resources | ||
22 | + * @param allocations allocated resources | ||
23 | + */ | ||
24 | + protected DefaultLinkResourceAllocations(LinkResourceRequest request, | ||
25 | + Map<Link, Set<ResourceAllocation>> allocations) { | ||
26 | + this.request = request; | ||
27 | + this.allocations = allocations; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + public IntentId intendId() { | ||
32 | + return request.intendId(); | ||
33 | + } | ||
34 | + | ||
35 | + @Override | ||
36 | + public Collection<Link> links() { | ||
37 | + return request.links(); | ||
38 | + } | ||
39 | + | ||
40 | + @Override | ||
41 | + public Set<ResourceRequest> resources() { | ||
42 | + return request.resources(); | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + public ResourceType type() { | ||
47 | + return null; | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public Set<ResourceAllocation> getResourceAllocation(Link link) { | ||
52 | + Set<ResourceAllocation> result = allocations.get(link); | ||
53 | + if (result == null) { | ||
54 | + result = Collections.emptySet(); | ||
55 | + } | ||
56 | + return result; | ||
57 | + } | ||
58 | + | ||
59 | +} |
... | @@ -2,6 +2,10 @@ package org.onlab.onos.net.resource; | ... | @@ -2,6 +2,10 @@ package org.onlab.onos.net.resource; |
2 | 2 | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | +import java.util.HashMap; | ||
6 | +import java.util.Map; | ||
7 | +import java.util.Set; | ||
8 | + | ||
5 | import org.apache.felix.scr.annotations.Activate; | 9 | import org.apache.felix.scr.annotations.Activate; |
6 | import org.apache.felix.scr.annotations.Component; | 10 | import org.apache.felix.scr.annotations.Component; |
7 | import org.apache.felix.scr.annotations.Deactivate; | 11 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -10,6 +14,8 @@ import org.onlab.onos.net.Link; | ... | @@ -10,6 +14,8 @@ import org.onlab.onos.net.Link; |
10 | import org.onlab.onos.net.intent.IntentId; | 14 | import org.onlab.onos.net.intent.IntentId; |
11 | import org.slf4j.Logger; | 15 | import org.slf4j.Logger; |
12 | 16 | ||
17 | +import com.google.common.collect.Sets; | ||
18 | + | ||
13 | /** | 19 | /** |
14 | * Provides basic implementation of link resources allocation. | 20 | * Provides basic implementation of link resources allocation. |
15 | */ | 21 | */ |
... | @@ -31,8 +37,30 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -31,8 +37,30 @@ public class LinkResourceManager implements LinkResourceService { |
31 | 37 | ||
32 | @Override | 38 | @Override |
33 | public LinkResourceAllocations requestResources(LinkResourceRequest req) { | 39 | public LinkResourceAllocations requestResources(LinkResourceRequest req) { |
34 | - // TODO Auto-generated method stub | 40 | + // TODO implement it using a resource data store. |
35 | - return null; | 41 | + |
42 | + ResourceAllocation alloc = null; | ||
43 | + for (ResourceRequest r: req.resources()) { | ||
44 | + switch (r.type()) { | ||
45 | + case BANDWIDTH: | ||
46 | + log.info("requestResources() always returns requested bandwidth"); | ||
47 | + BandwidthResourceRequest br = (BandwidthResourceRequest) r; | ||
48 | + alloc = new BandwidthResourceAllocation(br.bandwidth()); | ||
49 | + break; | ||
50 | + case LAMBDA: | ||
51 | + log.info("requestResources() always returns lambda 7"); | ||
52 | + alloc = new LambdaResourceAllocation(Lambda.valueOf(7)); | ||
53 | + break; | ||
54 | + default: | ||
55 | + break; | ||
56 | + } | ||
57 | + } | ||
58 | + | ||
59 | + Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>(); | ||
60 | + for (Link link: req.links()) { | ||
61 | + allocations.put(link, Sets.newHashSet(alloc)); | ||
62 | + } | ||
63 | + return new DefaultLinkResourceAllocations(req, allocations); | ||
36 | } | 64 | } |
37 | 65 | ||
38 | @Override | 66 | @Override | ... | ... |
-
Please register or login to post a comment