Aaron Kruglikov
Committed by Gerrit Code Review

Not ready, commiting to transfer between systems for work.

Change-Id: Ifb3d2ce184761574aa0fd35211deacfac1236d63
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onosproject.cli.net;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onosproject.cli.AbstractShellCommand;
21 +import org.onosproject.net.edge.EdgePortService;
22 +
23 +import static org.onosproject.net.DeviceId.deviceId;
24 +
25 +/**
26 + * Lists all edge ports.
27 + */
28 +@Command(scope = "onos", name = "edge-ports",
29 + description = "Lists all edge ports.")
30 +public class EdgePortsListCommand extends AbstractShellCommand {
31 +
32 + private static final String FMT = "%s/%s";
33 +
34 + @Argument(index = 0, name = "uri", description = "Device ID",
35 + required = false, multiValued = false)
36 + String uri = null;
37 +
38 +
39 +
40 + @Override
41 + protected void execute() {
42 + EdgePortService service = get(EdgePortService.class);
43 + if (uri == null) {
44 + service.getEdgePoints().forEach(e -> print(FMT, e.deviceId(), e.port()));
45 + } else {
46 + service.getEdgePoints(deviceId(uri)).forEach(e -> print(FMT, e.deviceId(), e.port()));
47 + }
48 + }
49 +
50 +}
...@@ -120,6 +120,13 @@ ...@@ -120,6 +120,13 @@
120 </command> 120 </command>
121 121
122 <command> 122 <command>
123 + <action class="org.onosproject.cli.net.EdgePortsListCommand"/>
124 + <completers>
125 + <ref component-id="deviceIdCompleter"/>
126 + </completers>
127 + </command>
128 +
129 + <command>
123 <action class="org.onosproject.cli.net.TopologyCommand"/> 130 <action class="org.onosproject.cli.net.TopologyCommand"/>
124 </command> 131 </command>
125 <command> 132 <command>
......
...@@ -41,7 +41,7 @@ public class EdgePortEvent extends AbstractEvent<EdgePortEvent.Type, ConnectPoin ...@@ -41,7 +41,7 @@ public class EdgePortEvent extends AbstractEvent<EdgePortEvent.Type, ConnectPoin
41 * @param type event type 41 * @param type event type
42 * @param subject connection point subject 42 * @param subject connection point subject
43 */ 43 */
44 - protected EdgePortEvent(Type type, ConnectPoint subject) { 44 + public EdgePortEvent(Type type, ConnectPoint subject) {
45 super(type, subject); 45 super(type, subject);
46 } 46 }
47 47
...@@ -52,7 +52,7 @@ public class EdgePortEvent extends AbstractEvent<EdgePortEvent.Type, ConnectPoin ...@@ -52,7 +52,7 @@ public class EdgePortEvent extends AbstractEvent<EdgePortEvent.Type, ConnectPoin
52 * @param subject connection point subject 52 * @param subject connection point subject
53 * @param time occurrence time 53 * @param time occurrence time
54 */ 54 */
55 - protected EdgePortEvent(Type type, ConnectPoint subject, long time) { 55 + public EdgePortEvent(Type type, ConnectPoint subject, long time) {
56 super(type, subject, time); 56 super(type, subject, time);
57 } 57 }
58 58
......
...@@ -40,7 +40,7 @@ public interface EdgePortService { ...@@ -40,7 +40,7 @@ public interface EdgePortService {
40 * 40 *
41 * @return iterable collection of all edge points 41 * @return iterable collection of all edge points
42 */ 42 */
43 - Iterable<ConnectPoint> getEdgePoint(); 43 + Iterable<ConnectPoint> getEdgePoints();
44 44
45 /** 45 /**
46 * Returns a collection of all edge point for the specified device. 46 * Returns a collection of all edge point for the specified device.
...@@ -48,7 +48,7 @@ public interface EdgePortService { ...@@ -48,7 +48,7 @@ public interface EdgePortService {
48 * @param deviceId device identifier 48 * @param deviceId device identifier
49 * @return iterable collection of all edge points for the device 49 * @return iterable collection of all edge points for the device
50 */ 50 */
51 - Iterable<ConnectPoint> getEdgePoint(DeviceId deviceId); 51 + Iterable<ConnectPoint> getEdgePoints(DeviceId deviceId);
52 52
53 /** 53 /**
54 * Emits the specified packet, with optional treatment to all edge ports. 54 * Emits the specified packet, with optional treatment to all edge ports.
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +package org.onosproject.net.edgeservice.impl;
19 +
20 +import com.google.common.collect.ImmutableSet;
21 +import com.google.common.collect.Maps;
22 +import com.google.common.collect.Sets;
23 +import org.apache.felix.scr.annotations.Activate;
24 +import org.apache.felix.scr.annotations.Component;
25 +import org.apache.felix.scr.annotations.Deactivate;
26 +import org.apache.felix.scr.annotations.Reference;
27 +import org.apache.felix.scr.annotations.ReferenceCardinality;
28 +import org.apache.felix.scr.annotations.Service;
29 +import org.onosproject.event.Event;
30 +import org.onosproject.event.EventDeliveryService;
31 +import org.onosproject.event.ListenerRegistry;
32 +import org.onosproject.net.ConnectPoint;
33 +import org.onosproject.net.DeviceId;
34 +import org.onosproject.net.device.DeviceEvent;
35 +import org.onosproject.net.device.DeviceService;
36 +import org.onosproject.net.edge.EdgePortEvent;
37 +import org.onosproject.net.edge.EdgePortListener;
38 +import org.onosproject.net.edge.EdgePortService;
39 +import org.onosproject.net.flow.DefaultTrafficTreatment;
40 +import org.onosproject.net.flow.TrafficTreatment;
41 +import org.onosproject.net.link.LinkEvent;
42 +import org.onosproject.net.packet.DefaultOutboundPacket;
43 +import org.onosproject.net.packet.OutboundPacket;
44 +import org.onosproject.net.packet.PacketService;
45 +import org.onosproject.net.topology.Topology;
46 +import org.onosproject.net.topology.TopologyEvent;
47 +import org.onosproject.net.topology.TopologyListener;
48 +import org.onosproject.net.topology.TopologyService;
49 +import org.slf4j.Logger;
50 +
51 +import java.nio.ByteBuffer;
52 +import java.util.List;
53 +import java.util.Map;
54 +import java.util.Optional;
55 +import java.util.Set;
56 +
57 +import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_ADDED;
58 +import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_REMOVED;
59 +import static org.slf4j.LoggerFactory.getLogger;
60 +
61 +/**
62 + * This is an implementation of the edge net service.
63 + */
64 +@Component(immediate = true)
65 +@Service
66 +public class EdgeManager implements EdgePortService {
67 +
68 + private final ListenerRegistry<EdgePortEvent, EdgePortListener>
69 + listenerRegistry = new ListenerRegistry<>();
70 +
71 + private final Logger log = getLogger(getClass());
72 +
73 + private Topology topology;
74 +
75 + private final TopologyListener topologyListener = new InnerTopologyListener();
76 +
77 + private final Map<DeviceId, Set<ConnectPoint>> connectionPoints = Maps.newConcurrentMap();
78 +
79 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 + protected EventDeliveryService eventDispatcher;
81 +
82 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 + protected PacketService packetService;
84 +
85 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 + protected DeviceService deviceService;
87 +
88 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 + protected TopologyService topologyService;
90 +
91 + @Activate
92 + public void activate() {
93 + eventDispatcher.addSink(EdgePortEvent.class, listenerRegistry);
94 + topologyService.addListener(topologyListener);
95 + log.info("Started");
96 + }
97 +
98 + @Deactivate
99 + public void deactivate() {
100 + eventDispatcher.removeSink(EdgePortEvent.class);
101 + topologyService.removeListener(topologyListener);
102 + log.info("Stopped");
103 + }
104 +
105 + public boolean isEdgePoint(ConnectPoint point) {
106 + return !topologyService.isInfrastructure(topologyService.currentTopology(), point);
107 + }
108 +
109 + public Iterable<ConnectPoint> getEdgePoints() {
110 + //TODO if this is called before any notifications need to populate structure
111 + ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
112 + connectionPoints.forEach((k, v) -> v.forEach(builder::add));
113 + return builder.build();
114 + }
115 +
116 + public Iterable<ConnectPoint> getEdgePoints(DeviceId deviceId) {
117 + //TODO if this is called before any notifications need to populate structure
118 + ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
119 + Set<ConnectPoint> set = connectionPoints.get(deviceId);
120 + if (set != null) {
121 + set.forEach(builder::add);
122 + }
123 + return builder.build();
124 + }
125 +
126 + public void emitPacket(ByteBuffer data, Optional<TrafficTreatment> treatment) {
127 + TrafficTreatment.Builder builder = treatment.isPresent() ?
128 + DefaultTrafficTreatment.builder(treatment.get()) :
129 + DefaultTrafficTreatment.builder();
130 + getEdgePoints().forEach(p -> packetService.emit(packet(builder, p, data)));
131 + }
132 +
133 + public void emitPacket(DeviceId deviceId, ByteBuffer data,
134 + Optional<TrafficTreatment> treatment) {
135 + TrafficTreatment.Builder builder = treatment.isPresent() ?
136 + DefaultTrafficTreatment.builder(treatment.get()) :
137 + DefaultTrafficTreatment.builder();
138 + getEdgePoints(deviceId).forEach(p -> packetService.emit(packet(builder, p, data)));
139 +
140 + }
141 +
142 + private OutboundPacket packet(TrafficTreatment.Builder builder, ConnectPoint point, ByteBuffer data) {
143 + builder.setOutput(point.port());
144 + return new DefaultOutboundPacket(point.deviceId(), builder.build(), data);
145 + }
146 +
147 + public void addListener(EdgePortListener listener) {
148 + listenerRegistry.addListener(listener);
149 + }
150 +
151 + public void removeListener(EdgePortListener listener) {
152 + listenerRegistry.removeListener(listener);
153 + }
154 +
155 +
156 + private class InnerTopologyListener implements TopologyListener {
157 + @Override
158 + public void event(TopologyEvent event) {
159 + topology = event.subject();
160 + List<Event> triggers = event.reasons();
161 + if (triggers != null) {
162 + triggers.forEach(reason -> {
163 + if (reason instanceof DeviceEvent) {
164 + //TODO spuriously catches events not handled in the handler method
165 + processDeviceEvent((DeviceEvent) reason);
166 + } else if (reason instanceof LinkEvent) {
167 + processLinkEvent((LinkEvent) reason);
168 + } else {
169 + System.out.println(reason.toString());
170 + }
171 + });
172 + } else {
173 + loadAllEdgePorts();
174 + }
175 + }
176 + }
177 +
178 +
179 + private void loadAllEdgePorts() {
180 + deviceService.getDevices().forEach(d -> deviceService.getPorts(d.id())
181 + .forEach(p -> addEdgePort(new ConnectPoint(d.id(), p.number()))));
182 + }
183 +
184 + private void processLinkEvent(LinkEvent event) {
185 + if (event.type() == LinkEvent.Type.LINK_ADDED) {
186 + removeEdgePort(event.subject().src());
187 + removeEdgePort(event.subject().dst());
188 + } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
189 + addEdgePort(event.subject().src());
190 + addEdgePort(event.subject().dst());
191 + }
192 +
193 + }
194 +
195 + private void processDeviceEvent(DeviceEvent event) {
196 +
197 + if (event.type() == DeviceEvent.Type.PORT_ADDED) {
198 + addEdgePort(new ConnectPoint(event.subject().id(), event.port().number()));
199 + } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
200 + removeEdgePort(new ConnectPoint(event.subject().id(), event.port().number()));
201 + }
202 + }
203 +
204 + private void addEdgePort(ConnectPoint point) {
205 + //TODO case of link removed and one of the end ports removed in same topo cycle
206 + //TODO pt2. resulting behavior will be adding a non-existent edge to the set
207 + if (!topologyService.isInfrastructure(topology, point)) {
208 + Set<ConnectPoint> set = connectionPoints.get(point.deviceId());
209 + if (set == null) {
210 + set = Sets.newConcurrentHashSet();
211 + connectionPoints.put(point.deviceId(), set);
212 + }
213 + if (set.add(point)) {
214 + eventDispatcher.post(new EdgePortEvent(EDGE_PORT_ADDED, point));
215 + }
216 + }
217 +
218 + }
219 +
220 + private void removeEdgePort(ConnectPoint point) {
221 + //TODO need to check that points still exist IE when a link and port are removed
222 + //TODO pt2 and both events are captures in the same topo update
223 + if (!topologyService.isInfrastructure(topology, point)) {
224 + Set<ConnectPoint> set = connectionPoints.get(point.deviceId());
225 + if (set == null) {
226 + return;
227 + }
228 + if (set.remove(point)) {
229 + eventDispatcher.post(new EdgePortEvent(EDGE_PORT_REMOVED, point));
230 + }
231 + if (set.isEmpty()) {
232 + connectionPoints.remove(point.deviceId());
233 + }
234 + }
235 +
236 + }
237 +}
1 +/**
2 + * Core subsystem for interacting with network edges.
3 + */
4 +package org.onosproject.net.edgeservice.impl;
...\ No newline at end of file ...\ No newline at end of file