Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Conflicts: core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoPoolUtil.java Change-Id: I6a8fc884f0c0b6578762d7b439177378e838735f
Showing
75 changed files
with
1429 additions
and
1073 deletions
... | @@ -16,4 +16,11 @@ | ... | @@ -16,4 +16,11 @@ |
16 | 16 | ||
17 | <description>ONOS simple reactive forwarding app</description> | 17 | <description>ONOS simple reactive forwarding app</description> |
18 | 18 | ||
19 | + <dependencies> | ||
20 | + <dependency> | ||
21 | + <groupId>org.osgi</groupId> | ||
22 | + <artifactId>org.osgi.compendium</artifactId> | ||
23 | + </dependency> | ||
24 | + </dependencies> | ||
25 | + | ||
19 | </project> | 26 | </project> | ... | ... |
1 | package org.onlab.onos.fwd; | 1 | package org.onlab.onos.fwd; |
2 | 2 | ||
3 | -import static org.slf4j.LoggerFactory.getLogger; | ||
4 | - | ||
5 | -import java.util.Set; | ||
6 | - | ||
7 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
9 | import org.apache.felix.scr.annotations.Deactivate; | 5 | import org.apache.felix.scr.annotations.Deactivate; |
6 | +import org.apache.felix.scr.annotations.Modified; | ||
7 | +import org.apache.felix.scr.annotations.Property; | ||
10 | import org.apache.felix.scr.annotations.Reference; | 8 | import org.apache.felix.scr.annotations.Reference; |
11 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 9 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
12 | import org.onlab.onos.ApplicationId; | 10 | import org.onlab.onos.ApplicationId; |
... | @@ -29,8 +27,14 @@ import org.onlab.onos.net.packet.PacketProcessor; | ... | @@ -29,8 +27,14 @@ import org.onlab.onos.net.packet.PacketProcessor; |
29 | import org.onlab.onos.net.packet.PacketService; | 27 | import org.onlab.onos.net.packet.PacketService; |
30 | import org.onlab.onos.net.topology.TopologyService; | 28 | import org.onlab.onos.net.topology.TopologyService; |
31 | import org.onlab.packet.Ethernet; | 29 | import org.onlab.packet.Ethernet; |
30 | +import org.osgi.service.component.ComponentContext; | ||
32 | import org.slf4j.Logger; | 31 | import org.slf4j.Logger; |
33 | 32 | ||
33 | +import java.util.Dictionary; | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | +import static org.slf4j.LoggerFactory.getLogger; | ||
37 | + | ||
34 | /** | 38 | /** |
35 | * Sample reactive forwarding application. | 39 | * Sample reactive forwarding application. |
36 | */ | 40 | */ |
... | @@ -61,6 +65,10 @@ public class ReactiveForwarding { | ... | @@ -61,6 +65,10 @@ public class ReactiveForwarding { |
61 | 65 | ||
62 | private ApplicationId appId; | 66 | private ApplicationId appId; |
63 | 67 | ||
68 | + @Property(name = "enabled", boolValue = true, | ||
69 | + label = "Enable forwarding; default is true") | ||
70 | + private boolean isEnabled = true; | ||
71 | + | ||
64 | @Activate | 72 | @Activate |
65 | public void activate() { | 73 | public void activate() { |
66 | appId = coreService.registerApplication("org.onlab.onos.fwd"); | 74 | appId = coreService.registerApplication("org.onlab.onos.fwd"); |
... | @@ -76,6 +84,22 @@ public class ReactiveForwarding { | ... | @@ -76,6 +84,22 @@ public class ReactiveForwarding { |
76 | log.info("Stopped"); | 84 | log.info("Stopped"); |
77 | } | 85 | } |
78 | 86 | ||
87 | + @Modified | ||
88 | + public void modified(ComponentContext context) { | ||
89 | + Dictionary properties = context.getProperties(); | ||
90 | + String flag = (String) properties.get("enabled"); | ||
91 | + if (flag != null) { | ||
92 | + boolean enabled = flag.equals("true"); | ||
93 | + if (isEnabled != enabled) { | ||
94 | + isEnabled = enabled; | ||
95 | + if (!isEnabled) { | ||
96 | + flowRuleService.removeFlowRulesById(appId); | ||
97 | + } | ||
98 | + log.info("Reconfigured. Forwarding is {}", | ||
99 | + isEnabled ? "enabled" : "disabled"); | ||
100 | + } | ||
101 | + } | ||
102 | + } | ||
79 | 103 | ||
80 | /** | 104 | /** |
81 | * Packet processor responsible for forwarding packets along their paths. | 105 | * Packet processor responsible for forwarding packets along their paths. |
... | @@ -86,7 +110,7 @@ public class ReactiveForwarding { | ... | @@ -86,7 +110,7 @@ public class ReactiveForwarding { |
86 | public void process(PacketContext context) { | 110 | public void process(PacketContext context) { |
87 | // Stop processing if the packet has been handled, since we | 111 | // Stop processing if the packet has been handled, since we |
88 | // can't do any more to it. | 112 | // can't do any more to it. |
89 | - if (context.isHandled()) { | 113 | + if (!isEnabled || context.isHandled()) { |
90 | return; | 114 | return; |
91 | } | 115 | } |
92 | 116 | ||
... | @@ -185,7 +209,6 @@ public class ReactiveForwarding { | ... | @@ -185,7 +209,6 @@ public class ReactiveForwarding { |
185 | builder.build(), treat.build(), PRIORITY, appId, TIMEOUT); | 209 | builder.build(), treat.build(), PRIORITY, appId, TIMEOUT); |
186 | 210 | ||
187 | flowRuleService.applyFlowRules(f); | 211 | flowRuleService.applyFlowRules(f); |
188 | - | ||
189 | } | 212 | } |
190 | 213 | ||
191 | } | 214 | } | ... | ... |
... | @@ -36,6 +36,12 @@ | ... | @@ -36,6 +36,12 @@ |
36 | <groupId>com.google.guava</groupId> | 36 | <groupId>com.google.guava</groupId> |
37 | <artifactId>guava</artifactId> | 37 | <artifactId>guava</artifactId> |
38 | </dependency> | 38 | </dependency> |
39 | + | ||
40 | + <dependency> | ||
41 | + <groupId>org.onlab.onos</groupId> | ||
42 | + <artifactId>onlab-thirdparty</artifactId> | ||
43 | + </dependency> | ||
44 | + | ||
39 | </dependencies> | 45 | </dependencies> |
40 | 46 | ||
41 | </project> | 47 | </project> | ... | ... |
... | @@ -126,8 +126,8 @@ public class PeerConnectivity { | ... | @@ -126,8 +126,8 @@ public class PeerConnectivity { |
126 | TrafficSelector selector = DefaultTrafficSelector.builder() | 126 | TrafficSelector selector = DefaultTrafficSelector.builder() |
127 | .matchEthType(Ethernet.TYPE_IPV4) | 127 | .matchEthType(Ethernet.TYPE_IPV4) |
128 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 128 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
129 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 129 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
130 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 130 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
131 | .matchTcpDst(BGP_PORT) | 131 | .matchTcpDst(BGP_PORT) |
132 | .build(); | 132 | .build(); |
133 | 133 | ||
... | @@ -147,8 +147,8 @@ public class PeerConnectivity { | ... | @@ -147,8 +147,8 @@ public class PeerConnectivity { |
147 | selector = DefaultTrafficSelector.builder() | 147 | selector = DefaultTrafficSelector.builder() |
148 | .matchEthType(Ethernet.TYPE_IPV4) | 148 | .matchEthType(Ethernet.TYPE_IPV4) |
149 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 149 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
150 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 150 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
151 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 151 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
152 | .matchTcpSrc(BGP_PORT) | 152 | .matchTcpSrc(BGP_PORT) |
153 | .build(); | 153 | .build(); |
154 | 154 | ||
... | @@ -165,8 +165,8 @@ public class PeerConnectivity { | ... | @@ -165,8 +165,8 @@ public class PeerConnectivity { |
165 | selector = DefaultTrafficSelector.builder() | 165 | selector = DefaultTrafficSelector.builder() |
166 | .matchEthType(Ethernet.TYPE_IPV4) | 166 | .matchEthType(Ethernet.TYPE_IPV4) |
167 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 167 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
168 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 168 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
169 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 169 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
170 | .matchTcpDst(BGP_PORT) | 170 | .matchTcpDst(BGP_PORT) |
171 | .build(); | 171 | .build(); |
172 | 172 | ||
... | @@ -183,8 +183,8 @@ public class PeerConnectivity { | ... | @@ -183,8 +183,8 @@ public class PeerConnectivity { |
183 | selector = DefaultTrafficSelector.builder() | 183 | selector = DefaultTrafficSelector.builder() |
184 | .matchEthType(Ethernet.TYPE_IPV4) | 184 | .matchEthType(Ethernet.TYPE_IPV4) |
185 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 185 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
186 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 186 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
187 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 187 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
188 | .matchTcpSrc(BGP_PORT) | 188 | .matchTcpSrc(BGP_PORT) |
189 | .build(); | 189 | .build(); |
190 | 190 | ||
... | @@ -251,8 +251,8 @@ public class PeerConnectivity { | ... | @@ -251,8 +251,8 @@ public class PeerConnectivity { |
251 | TrafficSelector selector = DefaultTrafficSelector.builder() | 251 | TrafficSelector selector = DefaultTrafficSelector.builder() |
252 | .matchEthType(Ethernet.TYPE_IPV4) | 252 | .matchEthType(Ethernet.TYPE_IPV4) |
253 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) | 253 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) |
254 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 254 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
255 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 255 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
256 | .build(); | 256 | .build(); |
257 | 257 | ||
258 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 258 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
... | @@ -269,8 +269,8 @@ public class PeerConnectivity { | ... | @@ -269,8 +269,8 @@ public class PeerConnectivity { |
269 | selector = DefaultTrafficSelector.builder() | 269 | selector = DefaultTrafficSelector.builder() |
270 | .matchEthType(Ethernet.TYPE_IPV4) | 270 | .matchEthType(Ethernet.TYPE_IPV4) |
271 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) | 271 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) |
272 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 272 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
273 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 273 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
274 | .build(); | 274 | .build(); |
275 | 275 | ||
276 | PointToPointIntent reversedIntent = new PointToPointIntent( | 276 | PointToPointIntent reversedIntent = new PointToPointIntent( | ... | ... |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Objects; | ||
6 | + | ||
7 | +import org.onlab.packet.IpAddress; | ||
8 | +import org.onlab.packet.IpPrefix; | ||
9 | + | ||
10 | +import com.google.common.base.MoreObjects; | ||
11 | + | ||
12 | +/** | ||
13 | + * Represents a route entry for an IP prefix. | ||
14 | + */ | ||
15 | +public class RouteEntry { | ||
16 | + private final IpPrefix prefix; // The IP prefix | ||
17 | + private final IpAddress nextHop; // Next-hop IP address | ||
18 | + | ||
19 | + /** | ||
20 | + * Class constructor. | ||
21 | + * | ||
22 | + * @param prefix the IP prefix of the route | ||
23 | + * @param nextHop the next hop IP address for the route | ||
24 | + */ | ||
25 | + public RouteEntry(IpPrefix prefix, IpAddress nextHop) { | ||
26 | + this.prefix = checkNotNull(prefix); | ||
27 | + this.nextHop = checkNotNull(nextHop); | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * Returns the IP prefix of the route. | ||
32 | + * | ||
33 | + * @return the IP prefix of the route | ||
34 | + */ | ||
35 | + public IpPrefix prefix() { | ||
36 | + return prefix; | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Returns the next hop IP address for the route. | ||
41 | + * | ||
42 | + * @return the next hop IP address for the route | ||
43 | + */ | ||
44 | + public IpAddress nextHop() { | ||
45 | + return nextHop; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Creates the binary string representation of an IPv4 prefix. | ||
50 | + * The string length is equal to the prefix length. | ||
51 | + * | ||
52 | + * @param ip4Prefix the IPv4 prefix to use | ||
53 | + * @return the binary string representation | ||
54 | + */ | ||
55 | + static String createBinaryString(IpPrefix ip4Prefix) { | ||
56 | + if (ip4Prefix.prefixLength() == 0) { | ||
57 | + return ""; | ||
58 | + } | ||
59 | + | ||
60 | + StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); | ||
61 | + long value = ip4Prefix.toInt(); | ||
62 | + for (int i = 0; i < ip4Prefix.prefixLength(); i++) { | ||
63 | + long mask = 1 << (IpAddress.MAX_INET_MASK - 1 - i); | ||
64 | + result.append(((value & mask) == 0) ? "0" : "1"); | ||
65 | + } | ||
66 | + return result.toString(); | ||
67 | + } | ||
68 | + | ||
69 | + @Override | ||
70 | + public boolean equals(Object other) { | ||
71 | + if (this == other) { | ||
72 | + return true; | ||
73 | + } | ||
74 | + | ||
75 | + // | ||
76 | + // NOTE: Subclasses are considered as change of identity, hence | ||
77 | + // equals() will return false if the class type doesn't match. | ||
78 | + // | ||
79 | + if (other == null || getClass() != other.getClass()) { | ||
80 | + return false; | ||
81 | + } | ||
82 | + | ||
83 | + RouteEntry otherRoute = (RouteEntry) other; | ||
84 | + return Objects.equals(this.prefix, otherRoute.prefix) && | ||
85 | + Objects.equals(this.nextHop, otherRoute.nextHop); | ||
86 | + } | ||
87 | + | ||
88 | + @Override | ||
89 | + public int hashCode() { | ||
90 | + return Objects.hash(prefix, nextHop); | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public String toString() { | ||
95 | + return MoreObjects.toStringHelper(getClass()) | ||
96 | + .add("prefix", prefix) | ||
97 | + .add("nextHop", nextHop) | ||
98 | + .toString(); | ||
99 | + } | ||
100 | +} |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +/** | ||
4 | + * An interface to receive route updates from route providers. | ||
5 | + */ | ||
6 | +public interface RouteListener { | ||
7 | + /** | ||
8 | + * Receives a route update from a route provider. | ||
9 | + * | ||
10 | + * @param routeUpdate the updated route information | ||
11 | + */ | ||
12 | + public void update(RouteUpdate routeUpdate); | ||
13 | +} |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Objects; | ||
6 | + | ||
7 | +import com.google.common.base.MoreObjects; | ||
8 | + | ||
9 | +/** | ||
10 | + * Represents a change in routing information. | ||
11 | + */ | ||
12 | +public class RouteUpdate { | ||
13 | + private final Type type; // The route update type | ||
14 | + private final RouteEntry routeEntry; // The updated route entry | ||
15 | + | ||
16 | + /** | ||
17 | + * Specifies the type of a route update. | ||
18 | + * <p/> | ||
19 | + * Route updates can either provide updated information for a route, or | ||
20 | + * withdraw a previously updated route. | ||
21 | + */ | ||
22 | + public enum Type { | ||
23 | + /** | ||
24 | + * The update contains updated route information for a route. | ||
25 | + */ | ||
26 | + UPDATE, | ||
27 | + /** | ||
28 | + * The update withdraws the route, meaning any previous information is | ||
29 | + * no longer valid. | ||
30 | + */ | ||
31 | + DELETE | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * Class constructor. | ||
36 | + * | ||
37 | + * @param type the type of the route update | ||
38 | + * @param routeEntry the route entry with the update | ||
39 | + */ | ||
40 | + public RouteUpdate(Type type, RouteEntry routeEntry) { | ||
41 | + this.type = type; | ||
42 | + this.routeEntry = checkNotNull(routeEntry); | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * Returns the type of the route update. | ||
47 | + * | ||
48 | + * @return the type of the update | ||
49 | + */ | ||
50 | + public Type type() { | ||
51 | + return type; | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Returns the route entry the route update is for. | ||
56 | + * | ||
57 | + * @return the route entry the route update is for | ||
58 | + */ | ||
59 | + public RouteEntry routeEntry() { | ||
60 | + return routeEntry; | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public boolean equals(Object other) { | ||
65 | + if (other == this) { | ||
66 | + return true; | ||
67 | + } | ||
68 | + | ||
69 | + if (!(other instanceof RouteUpdate)) { | ||
70 | + return false; | ||
71 | + } | ||
72 | + | ||
73 | + RouteUpdate otherUpdate = (RouteUpdate) other; | ||
74 | + | ||
75 | + return Objects.equals(this.type, otherUpdate.type) && | ||
76 | + Objects.equals(this.routeEntry, otherUpdate.routeEntry); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public int hashCode() { | ||
81 | + return Objects.hash(type, routeEntry); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public String toString() { | ||
86 | + return MoreObjects.toStringHelper(getClass()) | ||
87 | + .add("type", type) | ||
88 | + .add("routeEntry", routeEntry) | ||
89 | + .toString(); | ||
90 | + } | ||
91 | +} |
This diff is collapsed. Click to expand it.
... | @@ -9,7 +9,11 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -9,7 +9,11 @@ import org.apache.felix.scr.annotations.Reference; |
9 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 9 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
10 | import org.onlab.onos.net.host.HostService; | 10 | import org.onlab.onos.net.host.HostService; |
11 | import org.onlab.onos.net.intent.IntentService; | 11 | import org.onlab.onos.net.intent.IntentService; |
12 | +import org.onlab.onos.sdnip.RouteUpdate.Type; | ||
13 | +import org.onlab.onos.sdnip.bgp.BgpSessionManager; | ||
12 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; | 14 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; |
15 | +import org.onlab.packet.IpAddress; | ||
16 | +import org.onlab.packet.IpPrefix; | ||
13 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
14 | 18 | ||
15 | /** | 19 | /** |
... | @@ -28,6 +32,8 @@ public class SdnIp { | ... | @@ -28,6 +32,8 @@ public class SdnIp { |
28 | 32 | ||
29 | private SdnIpConfigReader config; | 33 | private SdnIpConfigReader config; |
30 | private PeerConnectivity peerConnectivity; | 34 | private PeerConnectivity peerConnectivity; |
35 | + private Router router; | ||
36 | + private BgpSessionManager bgpSessionManager; | ||
31 | 37 | ||
32 | @Activate | 38 | @Activate |
33 | protected void activate() { | 39 | protected void activate() { |
... | @@ -41,6 +47,17 @@ public class SdnIp { | ... | @@ -41,6 +47,17 @@ public class SdnIp { |
41 | peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); | 47 | peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); |
42 | peerConnectivity.start(); | 48 | peerConnectivity.start(); |
43 | 49 | ||
50 | + router = new Router(intentService, hostService, config, interfaceService); | ||
51 | + router.start(); | ||
52 | + | ||
53 | + bgpSessionManager = new BgpSessionManager(router); | ||
54 | + bgpSessionManager.startUp(2000); // TODO | ||
55 | + | ||
56 | + // TODO need to disable link discovery on external ports | ||
57 | + | ||
58 | + router.update(new RouteUpdate(Type.UPDATE, new RouteEntry( | ||
59 | + IpPrefix.valueOf("172.16.20.0/24"), | ||
60 | + IpAddress.valueOf("192.168.10.1")))); | ||
44 | } | 61 | } |
45 | 62 | ||
46 | @Deactivate | 63 | @Deactivate | ... | ... |
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
4 | +import org.jboss.netty.buffer.ChannelBuffers; | ||
5 | +import org.jboss.netty.channel.Channel; | ||
6 | +import org.jboss.netty.channel.ChannelHandlerContext; | ||
7 | +import org.jboss.netty.handler.codec.frame.FrameDecoder; | ||
8 | +import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError; | ||
9 | +import org.slf4j.Logger; | ||
10 | +import org.slf4j.LoggerFactory; | ||
11 | + | ||
12 | +/** | ||
13 | + * Class for handling the decoding of the BGP messages. | ||
14 | + */ | ||
15 | +class BgpFrameDecoder extends FrameDecoder { | ||
16 | + private static final Logger log = | ||
17 | + LoggerFactory.getLogger(BgpFrameDecoder.class); | ||
18 | + | ||
19 | + private final BgpSession bgpSession; | ||
20 | + | ||
21 | + /** | ||
22 | + * Constructor for a given BGP Session. | ||
23 | + * | ||
24 | + * @param bgpSession the BGP session state to use. | ||
25 | + */ | ||
26 | + BgpFrameDecoder(BgpSession bgpSession) { | ||
27 | + this.bgpSession = bgpSession; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + protected Object decode(ChannelHandlerContext ctx, | ||
32 | + Channel channel, | ||
33 | + ChannelBuffer buf) throws Exception { | ||
34 | + // | ||
35 | + // NOTE: If we close the channel during the decoding, we might still | ||
36 | + // see some incoming messages while the channel closing is completed. | ||
37 | + // | ||
38 | + if (bgpSession.isClosed()) { | ||
39 | + return null; | ||
40 | + } | ||
41 | + | ||
42 | + log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " + | ||
43 | + "messageSize = {}", | ||
44 | + ctx.getChannel().getRemoteAddress(), | ||
45 | + ctx.getChannel().getLocalAddress(), | ||
46 | + buf.readableBytes()); | ||
47 | + | ||
48 | + // Test for minimum length of the BGP message | ||
49 | + if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { | ||
50 | + // No enough data received | ||
51 | + return null; | ||
52 | + } | ||
53 | + | ||
54 | + // | ||
55 | + // Mark the current buffer position in case we haven't received | ||
56 | + // the whole message. | ||
57 | + // | ||
58 | + buf.markReaderIndex(); | ||
59 | + | ||
60 | + // | ||
61 | + // Read and check the BGP message Marker field: it must be all ones | ||
62 | + // (See RFC 4271, Section 4.1) | ||
63 | + // | ||
64 | + byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; | ||
65 | + buf.readBytes(marker); | ||
66 | + for (int i = 0; i < marker.length; i++) { | ||
67 | + if (marker[i] != (byte) 0xff) { | ||
68 | + log.debug("BGP RX Error: invalid marker {} at position {}", | ||
69 | + marker[i], i); | ||
70 | + // | ||
71 | + // ERROR: Connection Not Synchronized | ||
72 | + // | ||
73 | + // Send NOTIFICATION and close the connection | ||
74 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
75 | + int errorSubcode = | ||
76 | + MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED; | ||
77 | + ChannelBuffer txMessage = | ||
78 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
79 | + null); | ||
80 | + ctx.getChannel().write(txMessage); | ||
81 | + bgpSession.closeChannel(ctx); | ||
82 | + return null; | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + // | ||
87 | + // Read and check the BGP message Length field | ||
88 | + // | ||
89 | + int length = buf.readUnsignedShort(); | ||
90 | + if ((length < BgpConstants.BGP_HEADER_LENGTH) || | ||
91 | + (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { | ||
92 | + log.debug("BGP RX Error: invalid Length field {}. " + | ||
93 | + "Must be between {} and {}", | ||
94 | + length, | ||
95 | + BgpConstants.BGP_HEADER_LENGTH, | ||
96 | + BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
97 | + // | ||
98 | + // ERROR: Bad Message Length | ||
99 | + // | ||
100 | + // Send NOTIFICATION and close the connection | ||
101 | + ChannelBuffer txMessage = | ||
102 | + bgpSession.prepareBgpNotificationBadMessageLength(length); | ||
103 | + ctx.getChannel().write(txMessage); | ||
104 | + bgpSession.closeChannel(ctx); | ||
105 | + return null; | ||
106 | + } | ||
107 | + | ||
108 | + // | ||
109 | + // Test whether the rest of the message is received: | ||
110 | + // So far we have read the Marker (16 octets) and the | ||
111 | + // Length (2 octets) fields. | ||
112 | + // | ||
113 | + int remainingMessageLen = | ||
114 | + length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; | ||
115 | + if (buf.readableBytes() < remainingMessageLen) { | ||
116 | + // No enough data received | ||
117 | + buf.resetReaderIndex(); | ||
118 | + return null; | ||
119 | + } | ||
120 | + | ||
121 | + // | ||
122 | + // Read the BGP message Type field, and process based on that type | ||
123 | + // | ||
124 | + int type = buf.readUnsignedByte(); | ||
125 | + remainingMessageLen--; // Adjust after reading the type | ||
126 | + ChannelBuffer message = buf.readBytes(remainingMessageLen); | ||
127 | + | ||
128 | + // | ||
129 | + // Process the remaining of the message based on the message type | ||
130 | + // | ||
131 | + switch (type) { | ||
132 | + case BgpConstants.BGP_TYPE_OPEN: | ||
133 | + bgpSession.processBgpOpen(ctx, message); | ||
134 | + break; | ||
135 | + case BgpConstants.BGP_TYPE_UPDATE: | ||
136 | + bgpSession.processBgpUpdate(ctx, message); | ||
137 | + break; | ||
138 | + case BgpConstants.BGP_TYPE_NOTIFICATION: | ||
139 | + bgpSession.processBgpNotification(ctx, message); | ||
140 | + break; | ||
141 | + case BgpConstants.BGP_TYPE_KEEPALIVE: | ||
142 | + bgpSession.processBgpKeepalive(ctx, message); | ||
143 | + break; | ||
144 | + default: | ||
145 | + // | ||
146 | + // ERROR: Bad Message Type | ||
147 | + // | ||
148 | + // Send NOTIFICATION and close the connection | ||
149 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
150 | + int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE; | ||
151 | + ChannelBuffer data = ChannelBuffers.buffer(1); | ||
152 | + data.writeByte(type); | ||
153 | + ChannelBuffer txMessage = | ||
154 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
155 | + data); | ||
156 | + ctx.getChannel().write(txMessage); | ||
157 | + bgpSession.closeChannel(ctx); | ||
158 | + return null; | ||
159 | + } | ||
160 | + return null; | ||
161 | + } | ||
162 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static org.hamcrest.Matchers.is; | ||
4 | +import static org.hamcrest.Matchers.not; | ||
5 | +import static org.junit.Assert.assertThat; | ||
6 | + | ||
7 | +import org.junit.Test; | ||
8 | +import org.onlab.packet.IpAddress; | ||
9 | +import org.onlab.packet.IpPrefix; | ||
10 | + | ||
11 | +/** | ||
12 | + * Unit tests for the RouteEntry class. | ||
13 | + */ | ||
14 | +public class RouteEntryTest { | ||
15 | + /** | ||
16 | + * Tests valid class constructor. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testConstructor() { | ||
20 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
21 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
22 | + | ||
23 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
24 | + assertThat(routeEntry.toString(), | ||
25 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
26 | + } | ||
27 | + | ||
28 | + /** | ||
29 | + * Tests invalid class constructor for null IPv4 prefix. | ||
30 | + */ | ||
31 | + @Test(expected = NullPointerException.class) | ||
32 | + public void testInvalidConstructorNullPrefix() { | ||
33 | + IpPrefix prefix = null; | ||
34 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
35 | + | ||
36 | + new RouteEntry(prefix, nextHop); | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Tests invalid class constructor for null IPv4 next-hop. | ||
41 | + */ | ||
42 | + @Test(expected = NullPointerException.class) | ||
43 | + public void testInvalidConstructorNullNextHop() { | ||
44 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
45 | + IpAddress nextHop = null; | ||
46 | + | ||
47 | + new RouteEntry(prefix, nextHop); | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Tests getting the fields of a route entry. | ||
52 | + */ | ||
53 | + @Test | ||
54 | + public void testGetFields() { | ||
55 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
56 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
57 | + | ||
58 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
59 | + assertThat(routeEntry.prefix(), is(prefix)); | ||
60 | + assertThat(routeEntry.nextHop(), is(nextHop)); | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * Tests creating a binary string from IPv4 prefix. | ||
65 | + */ | ||
66 | + @Test | ||
67 | + public void testCreateBinaryString() { | ||
68 | + IpPrefix prefix; | ||
69 | + | ||
70 | + prefix = IpPrefix.valueOf("0.0.0.0/0"); | ||
71 | + assertThat(RouteEntry.createBinaryString(prefix), is("")); | ||
72 | + | ||
73 | + prefix = IpPrefix.valueOf("192.168.166.0/22"); | ||
74 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
75 | + is("1100000010101000101001")); | ||
76 | + | ||
77 | + prefix = IpPrefix.valueOf("192.168.166.0/23"); | ||
78 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
79 | + is("11000000101010001010011")); | ||
80 | + | ||
81 | + prefix = IpPrefix.valueOf("192.168.166.0/24"); | ||
82 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
83 | + is("110000001010100010100110")); | ||
84 | + | ||
85 | + prefix = IpPrefix.valueOf("130.162.10.1/25"); | ||
86 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
87 | + is("1000001010100010000010100")); | ||
88 | + | ||
89 | + prefix = IpPrefix.valueOf("255.255.255.255/32"); | ||
90 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
91 | + is("11111111111111111111111111111111")); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Tests equality of {@link RouteEntry}. | ||
96 | + */ | ||
97 | + @Test | ||
98 | + public void testEquality() { | ||
99 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
100 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
101 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
102 | + | ||
103 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/24"); | ||
104 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
105 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
106 | + | ||
107 | + assertThat(routeEntry1, is(routeEntry2)); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Tests non-equality of {@link RouteEntry}. | ||
112 | + */ | ||
113 | + @Test | ||
114 | + public void testNonEquality() { | ||
115 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
116 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
117 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
118 | + | ||
119 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/25"); // Different | ||
120 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
121 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
122 | + | ||
123 | + IpPrefix prefix3 = IpPrefix.valueOf("1.2.3.0/24"); | ||
124 | + IpAddress nextHop3 = IpAddress.valueOf("5.6.7.9"); // Different | ||
125 | + RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3); | ||
126 | + | ||
127 | + assertThat(routeEntry1, is(not(routeEntry2))); | ||
128 | + assertThat(routeEntry1, is(not(routeEntry3))); | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * Tests object string representation. | ||
133 | + */ | ||
134 | + @Test | ||
135 | + public void testToString() { | ||
136 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
137 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
138 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
139 | + | ||
140 | + assertThat(routeEntry.toString(), | ||
141 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
142 | + } | ||
143 | +} |
... | @@ -26,6 +26,16 @@ | ... | @@ -26,6 +26,16 @@ |
26 | <groupId>org.onlab.onos</groupId> | 26 | <groupId>org.onlab.onos</groupId> |
27 | <artifactId>onlab-osgi</artifactId> | 27 | <artifactId>onlab-osgi</artifactId> |
28 | </dependency> | 28 | </dependency> |
29 | + | ||
30 | + <dependency> | ||
31 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
32 | + <artifactId>jackson-databind</artifactId> | ||
33 | + </dependency> | ||
34 | + <dependency> | ||
35 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
36 | + <artifactId>jackson-annotations</artifactId> | ||
37 | + </dependency> | ||
38 | + | ||
29 | <dependency> | 39 | <dependency> |
30 | <groupId>org.osgi</groupId> | 40 | <groupId>org.osgi</groupId> |
31 | <artifactId>org.osgi.core</artifactId> | 41 | <artifactId>org.osgi.core</artifactId> | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import org.apache.karaf.shell.commands.Option; | ||
3 | import org.apache.karaf.shell.console.OsgiCommandSupport; | 4 | import org.apache.karaf.shell.console.OsgiCommandSupport; |
4 | import org.onlab.osgi.DefaultServiceDirectory; | 5 | import org.onlab.osgi.DefaultServiceDirectory; |
5 | import org.onlab.osgi.ServiceNotFoundException; | 6 | import org.onlab.osgi.ServiceNotFoundException; |
... | @@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException; | ... | @@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException; |
9 | */ | 10 | */ |
10 | public abstract class AbstractShellCommand extends OsgiCommandSupport { | 11 | public abstract class AbstractShellCommand extends OsgiCommandSupport { |
11 | 12 | ||
13 | + @Option(name = "-j", aliases = "--json", description = "Output JSON", | ||
14 | + required = false, multiValued = false) | ||
15 | + private boolean json = false; | ||
16 | + | ||
12 | /** | 17 | /** |
13 | * Returns the reference to the implementation of the specified service. | 18 | * Returns the reference to the implementation of the specified service. |
14 | * | 19 | * |
... | @@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { | ... | @@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { |
46 | */ | 51 | */ |
47 | protected abstract void execute(); | 52 | protected abstract void execute(); |
48 | 53 | ||
54 | + /** | ||
55 | + * Indicates whether JSON format should be output. | ||
56 | + * | ||
57 | + * @return true if JSON is requested | ||
58 | + */ | ||
59 | + protected boolean outputJson() { | ||
60 | + return json; | ||
61 | + } | ||
62 | + | ||
49 | @Override | 63 | @Override |
50 | protected Object doExecute() throws Exception { | 64 | protected Object doExecute() throws Exception { |
51 | try { | 65 | try { | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import com.google.common.collect.Lists; | 6 | import com.google.common.collect.Lists; |
4 | - | ||
5 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
6 | import org.onlab.onos.cluster.ClusterService; | 8 | import org.onlab.onos.cluster.ClusterService; |
7 | import org.onlab.onos.cluster.ControllerNode; | 9 | import org.onlab.onos.cluster.ControllerNode; |
... | @@ -26,7 +28,10 @@ public class MastersListCommand extends AbstractShellCommand { | ... | @@ -26,7 +28,10 @@ public class MastersListCommand extends AbstractShellCommand { |
26 | MastershipService mastershipService = get(MastershipService.class); | 28 | MastershipService mastershipService = get(MastershipService.class); |
27 | List<ControllerNode> nodes = newArrayList(service.getNodes()); | 29 | List<ControllerNode> nodes = newArrayList(service.getNodes()); |
28 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); | 30 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); |
29 | - ControllerNode self = service.getLocalNode(); | 31 | + |
32 | + if (outputJson()) { | ||
33 | + print("%s", json(service, mastershipService, nodes)); | ||
34 | + } else { | ||
30 | for (ControllerNode node : nodes) { | 35 | for (ControllerNode node : nodes) { |
31 | List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); | 36 | List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); |
32 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); | 37 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); |
... | @@ -36,5 +41,37 @@ public class MastersListCommand extends AbstractShellCommand { | ... | @@ -36,5 +41,37 @@ public class MastersListCommand extends AbstractShellCommand { |
36 | } | 41 | } |
37 | } | 42 | } |
38 | } | 43 | } |
44 | + } | ||
45 | + | ||
46 | + // Produces JSON structure. | ||
47 | + private JsonNode json(ClusterService service, MastershipService mastershipService, | ||
48 | + List<ControllerNode> nodes) { | ||
49 | + ObjectMapper mapper = new ObjectMapper(); | ||
50 | + ArrayNode result = mapper.createArrayNode(); | ||
51 | + ControllerNode self = service.getLocalNode(); | ||
52 | + for (ControllerNode node : nodes) { | ||
53 | + List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); | ||
54 | + result.add(mapper.createObjectNode() | ||
55 | + .put("id", node.id().toString()) | ||
56 | + .put("size", ids.size()) | ||
57 | + .set("devices", json(mapper, ids))); | ||
58 | + } | ||
59 | + return result; | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Produces a JSON array containing the specified device identifiers. | ||
64 | + * | ||
65 | + * @param mapper object mapper | ||
66 | + * @param ids collection of device identifiers | ||
67 | + * @return JSON array | ||
68 | + */ | ||
69 | + public static JsonNode json(ObjectMapper mapper, Iterable<DeviceId> ids) { | ||
70 | + ArrayNode result = mapper.createArrayNode(); | ||
71 | + for (DeviceId deviceId : ids) { | ||
72 | + result.add(deviceId.toString()); | ||
73 | + } | ||
74 | + return result; | ||
75 | + } | ||
39 | 76 | ||
40 | } | 77 | } | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 6 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cluster.ClusterService; | 7 | import org.onlab.onos.cluster.ClusterService; |
5 | import org.onlab.onos.cluster.ControllerNode; | 8 | import org.onlab.onos.cluster.ControllerNode; |
... | @@ -24,6 +27,9 @@ public class NodesListCommand extends AbstractShellCommand { | ... | @@ -24,6 +27,9 @@ public class NodesListCommand extends AbstractShellCommand { |
24 | ClusterService service = get(ClusterService.class); | 27 | ClusterService service = get(ClusterService.class); |
25 | List<ControllerNode> nodes = newArrayList(service.getNodes()); | 28 | List<ControllerNode> nodes = newArrayList(service.getNodes()); |
26 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); | 29 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); |
30 | + if (outputJson()) { | ||
31 | + print("%s", json(service, nodes)); | ||
32 | + } else { | ||
27 | ControllerNode self = service.getLocalNode(); | 33 | ControllerNode self = service.getLocalNode(); |
28 | for (ControllerNode node : nodes) { | 34 | for (ControllerNode node : nodes) { |
29 | print(FMT, node.id(), node.ip(), node.tcpPort(), | 35 | print(FMT, node.id(), node.ip(), node.tcpPort(), |
... | @@ -31,5 +37,22 @@ public class NodesListCommand extends AbstractShellCommand { | ... | @@ -31,5 +37,22 @@ public class NodesListCommand extends AbstractShellCommand { |
31 | node.equals(self) ? "*" : ""); | 37 | node.equals(self) ? "*" : ""); |
32 | } | 38 | } |
33 | } | 39 | } |
40 | + } | ||
41 | + | ||
42 | + // Produces JSON structure. | ||
43 | + private JsonNode json(ClusterService service, List<ControllerNode> nodes) { | ||
44 | + ObjectMapper mapper = new ObjectMapper(); | ||
45 | + ArrayNode result = mapper.createArrayNode(); | ||
46 | + ControllerNode self = service.getLocalNode(); | ||
47 | + for (ControllerNode node : nodes) { | ||
48 | + result.add(mapper.createObjectNode() | ||
49 | + .put("id", node.id().toString()) | ||
50 | + .put("ip", node.ip().toString()) | ||
51 | + .put("tcpPort", node.tcpPort()) | ||
52 | + .put("state", service.getState(node.id()).toString()) | ||
53 | + .put("self", node.equals(self))); | ||
54 | + } | ||
55 | + return result; | ||
56 | + } | ||
34 | 57 | ||
35 | } | 58 | } | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import org.apache.karaf.shell.commands.Command; | 4 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.CoreService; | 5 | import org.onlab.onos.CoreService; |
5 | import org.onlab.onos.cluster.ClusterService; | 6 | import org.onlab.onos.cluster.ClusterService; |
... | @@ -22,6 +23,19 @@ public class SummaryCommand extends AbstractShellCommand { | ... | @@ -22,6 +23,19 @@ public class SummaryCommand extends AbstractShellCommand { |
22 | protected void execute() { | 23 | protected void execute() { |
23 | TopologyService topologyService = get(TopologyService.class); | 24 | TopologyService topologyService = get(TopologyService.class); |
24 | Topology topology = topologyService.currentTopology(); | 25 | Topology topology = topologyService.currentTopology(); |
26 | + if (outputJson()) { | ||
27 | + print("%s", new ObjectMapper().createObjectNode() | ||
28 | + .put("node", get(ClusterService.class).getLocalNode().ip().toString()) | ||
29 | + .put("version", get(CoreService.class).version().toString()) | ||
30 | + .put("nodes", get(ClusterService.class).getNodes().size()) | ||
31 | + .put("devices", get(DeviceService.class).getDeviceCount()) | ||
32 | + .put("links", get(LinkService.class).getLinkCount()) | ||
33 | + .put("hosts", get(HostService.class).getHostCount()) | ||
34 | + .put("clusters", topologyService.getClusters(topology).size()) | ||
35 | + .put("paths", topology.pathCount()) | ||
36 | + .put("flows", get(FlowRuleService.class).getFlowRuleCount()) | ||
37 | + .put("intents", get(IntentService.class).getIntentCount())); | ||
38 | + } else { | ||
25 | print("node=%s, version=%s", | 39 | print("node=%s, version=%s", |
26 | get(ClusterService.class).getLocalNode().ip(), | 40 | get(ClusterService.class).getLocalNode().ip(), |
27 | get(CoreService.class).version().toString()); | 41 | get(CoreService.class).version().toString()); |
... | @@ -35,5 +49,6 @@ public class SummaryCommand extends AbstractShellCommand { | ... | @@ -35,5 +49,6 @@ public class SummaryCommand extends AbstractShellCommand { |
35 | get(FlowRuleService.class).getFlowRuleCount(), | 49 | get(FlowRuleService.class).getFlowRuleCount(), |
36 | get(IntentService.class).getIntentCount()); | 50 | get(IntentService.class).getIntentCount()); |
37 | } | 51 | } |
52 | + } | ||
38 | 53 | ||
39 | } | 54 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import com.google.common.collect.Lists; | 4 | import com.google.common.collect.Lists; |
4 | import org.apache.karaf.shell.commands.Argument; | 5 | import org.apache.karaf.shell.commands.Argument; |
5 | import org.apache.karaf.shell.commands.Command; | 6 | import org.apache.karaf.shell.commands.Command; |
... | @@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster; | ... | @@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster; |
10 | import java.util.Collections; | 11 | import java.util.Collections; |
11 | import java.util.List; | 12 | import java.util.List; |
12 | 13 | ||
14 | +import static org.onlab.onos.cli.MastersListCommand.json; | ||
13 | import static org.onlab.onos.net.topology.ClusterId.clusterId; | 15 | import static org.onlab.onos.net.topology.ClusterId.clusterId; |
14 | 16 | ||
15 | /** | 17 | /** |
... | @@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand { | ... | @@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand { |
33 | } else { | 35 | } else { |
34 | List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster)); | 36 | List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster)); |
35 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); | 37 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); |
38 | + if (outputJson()) { | ||
39 | + print("%s", json(new ObjectMapper(), ids)); | ||
40 | + } else { | ||
36 | for (DeviceId deviceId : ids) { | 41 | for (DeviceId deviceId : ids) { |
37 | print("%s", deviceId); | 42 | print("%s", deviceId); |
38 | } | 43 | } |
39 | } | 44 | } |
40 | } | 45 | } |
41 | - | 46 | + } |
42 | 47 | ||
43 | } | 48 | } | ... | ... |
... | @@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command; | ... | @@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.net.Link; | 5 | import org.onlab.onos.net.Link; |
6 | import org.onlab.onos.net.topology.TopologyCluster; | 6 | import org.onlab.onos.net.topology.TopologyCluster; |
7 | 7 | ||
8 | +import static org.onlab.onos.cli.net.LinksListCommand.json; | ||
8 | import static org.onlab.onos.cli.net.LinksListCommand.linkString; | 9 | import static org.onlab.onos.cli.net.LinksListCommand.linkString; |
9 | import static org.onlab.onos.net.topology.ClusterId.clusterId; | 10 | import static org.onlab.onos.net.topology.ClusterId.clusterId; |
10 | 11 | ||
... | @@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand { | ... | @@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand { |
26 | TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); | 27 | TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); |
27 | if (cluster == null) { | 28 | if (cluster == null) { |
28 | error("No such cluster %s", cid); | 29 | error("No such cluster %s", cid); |
30 | + } else if (outputJson()) { | ||
31 | + print("%s", json(service.getClusterLinks(topology, cluster))); | ||
29 | } else { | 32 | } else { |
30 | for (Link link : service.getClusterLinks(topology, cluster)) { | 33 | for (Link link : service.getClusterLinks(topology, cluster)) { |
31 | print(linkString(link)); | 34 | print(linkString(link)); | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import com.google.common.collect.Lists; | 6 | import com.google.common.collect.Lists; |
4 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.cli.Comparators; | 8 | import org.onlab.onos.cli.Comparators; |
... | @@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand { | ... | @@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand { |
24 | List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); | 27 | List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); |
25 | Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR); | 28 | Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR); |
26 | 29 | ||
30 | + if (outputJson()) { | ||
31 | + print("%s", json(clusters)); | ||
32 | + } else { | ||
27 | for (TopologyCluster cluster : clusters) { | 33 | for (TopologyCluster cluster : clusters) { |
28 | print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); | 34 | print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); |
29 | } | 35 | } |
30 | } | 36 | } |
37 | + } | ||
38 | + | ||
39 | + // Produces a JSON result. | ||
40 | + private JsonNode json(Iterable<TopologyCluster> clusters) { | ||
41 | + ObjectMapper mapper = new ObjectMapper(); | ||
42 | + ArrayNode result = mapper.createArrayNode(); | ||
43 | + for (TopologyCluster cluster : clusters) { | ||
44 | + result.add(mapper.createObjectNode() | ||
45 | + .put("id", cluster.id().index()) | ||
46 | + .put("deviceCount", cluster.deviceCount()) | ||
47 | + .put("linkCount", cluster.linkCount())); | ||
48 | + } | ||
49 | + return result; | ||
50 | + } | ||
31 | 51 | ||
32 | } | 52 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 7 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 8 | import org.apache.karaf.shell.commands.Command; |
9 | +import org.apache.karaf.shell.commands.Option; | ||
5 | import org.onlab.onos.cli.Comparators; | 10 | import org.onlab.onos.cli.Comparators; |
6 | import org.onlab.onos.net.Device; | 11 | import org.onlab.onos.net.Device; |
7 | import org.onlab.onos.net.Port; | 12 | import org.onlab.onos.net.Port; |
... | @@ -22,6 +27,14 @@ public class DevicePortsListCommand extends DevicesListCommand { | ... | @@ -22,6 +27,14 @@ public class DevicePortsListCommand extends DevicesListCommand { |
22 | 27 | ||
23 | private static final String FMT = " port=%s, state=%s"; | 28 | private static final String FMT = " port=%s, state=%s"; |
24 | 29 | ||
30 | + @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", | ||
31 | + required = false, multiValued = false) | ||
32 | + private boolean enabled = false; | ||
33 | + | ||
34 | + @Option(name = "-d", aliases = "--disabled", description = "Show only disabled ports", | ||
35 | + required = false, multiValued = false) | ||
36 | + private boolean disabled = false; | ||
37 | + | ||
25 | @Argument(index = 0, name = "uri", description = "Device ID", | 38 | @Argument(index = 0, name = "uri", description = "Device ID", |
26 | required = false, multiValued = false) | 39 | required = false, multiValued = false) |
27 | String uri = null; | 40 | String uri = null; |
... | @@ -30,27 +43,79 @@ public class DevicePortsListCommand extends DevicesListCommand { | ... | @@ -30,27 +43,79 @@ public class DevicePortsListCommand extends DevicesListCommand { |
30 | protected void execute() { | 43 | protected void execute() { |
31 | DeviceService service = get(DeviceService.class); | 44 | DeviceService service = get(DeviceService.class); |
32 | if (uri == null) { | 45 | if (uri == null) { |
46 | + if (outputJson()) { | ||
47 | + print("%s", jsonPorts(service, getSortedDevices(service))); | ||
48 | + } else { | ||
33 | for (Device device : getSortedDevices(service)) { | 49 | for (Device device : getSortedDevices(service)) { |
34 | printDevice(service, device); | 50 | printDevice(service, device); |
35 | } | 51 | } |
52 | + } | ||
53 | + | ||
36 | } else { | 54 | } else { |
37 | Device device = service.getDevice(deviceId(uri)); | 55 | Device device = service.getDevice(deviceId(uri)); |
38 | if (device == null) { | 56 | if (device == null) { |
39 | error("No such device %s", uri); | 57 | error("No such device %s", uri); |
58 | + } else if (outputJson()) { | ||
59 | + print("%s", jsonPorts(service, new ObjectMapper(), device)); | ||
40 | } else { | 60 | } else { |
41 | printDevice(service, device); | 61 | printDevice(service, device); |
42 | } | 62 | } |
43 | } | 63 | } |
44 | } | 64 | } |
45 | 65 | ||
66 | + /** | ||
67 | + * Produces JSON array containing ports of the specified devices. | ||
68 | + * | ||
69 | + * @param service device service | ||
70 | + * @param devices collection of devices | ||
71 | + * @return JSON array | ||
72 | + */ | ||
73 | + public JsonNode jsonPorts(DeviceService service, Iterable<Device> devices) { | ||
74 | + ObjectMapper mapper = new ObjectMapper(); | ||
75 | + ArrayNode result = mapper.createArrayNode(); | ||
76 | + for (Device device : devices) { | ||
77 | + result.add(jsonPorts(service, mapper, device)); | ||
78 | + } | ||
79 | + return result; | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Produces JSON array containing ports of the specified device. | ||
84 | + * | ||
85 | + * @param service device service | ||
86 | + * @param mapper object mapper | ||
87 | + * @param device infrastructure devices | ||
88 | + * @return JSON array | ||
89 | + */ | ||
90 | + public JsonNode jsonPorts(DeviceService service, ObjectMapper mapper, Device device) { | ||
91 | + ObjectNode result = mapper.createObjectNode(); | ||
92 | + ArrayNode ports = mapper.createArrayNode(); | ||
93 | + for (Port port : service.getPorts(device.id())) { | ||
94 | + if (isIncluded(port)) { | ||
95 | + ports.add(mapper.createObjectNode() | ||
96 | + .put("port", port.number().toString()) | ||
97 | + .put("isEnabled", port.isEnabled())); | ||
98 | + } | ||
99 | + } | ||
100 | + return result.put("device", device.id().toString()).set("ports", ports); | ||
101 | + } | ||
102 | + | ||
103 | + // Determines if a port should be included in output. | ||
104 | + private boolean isIncluded(Port port) { | ||
105 | + return enabled && port.isEnabled() || disabled && !port.isEnabled() || | ||
106 | + !enabled && !disabled; | ||
107 | + } | ||
108 | + | ||
46 | @Override | 109 | @Override |
47 | protected void printDevice(DeviceService service, Device device) { | 110 | protected void printDevice(DeviceService service, Device device) { |
48 | super.printDevice(service, device); | 111 | super.printDevice(service, device); |
49 | List<Port> ports = new ArrayList<>(service.getPorts(device.id())); | 112 | List<Port> ports = new ArrayList<>(service.getPorts(device.id())); |
50 | Collections.sort(ports, Comparators.PORT_COMPARATOR); | 113 | Collections.sort(ports, Comparators.PORT_COMPARATOR); |
51 | for (Port port : ports) { | 114 | for (Port port : ports) { |
115 | + if (isIncluded(port)) { | ||
52 | print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); | 116 | print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); |
53 | } | 117 | } |
54 | } | 118 | } |
119 | + } | ||
55 | 120 | ||
56 | } | 121 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 8 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.cli.Comparators; | 9 | import org.onlab.onos.cli.Comparators; |
... | @@ -24,10 +28,53 @@ public class DevicesListCommand extends AbstractShellCommand { | ... | @@ -24,10 +28,53 @@ public class DevicesListCommand extends AbstractShellCommand { |
24 | @Override | 28 | @Override |
25 | protected void execute() { | 29 | protected void execute() { |
26 | DeviceService service = get(DeviceService.class); | 30 | DeviceService service = get(DeviceService.class); |
31 | + if (outputJson()) { | ||
32 | + print("%s", json(service, getSortedDevices(service))); | ||
33 | + } else { | ||
27 | for (Device device : getSortedDevices(service)) { | 34 | for (Device device : getSortedDevices(service)) { |
28 | printDevice(service, device); | 35 | printDevice(service, device); |
29 | } | 36 | } |
30 | } | 37 | } |
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * Returns JSON node representing the specified devices. | ||
42 | + * | ||
43 | + * @param service device service | ||
44 | + * @param devices collection of devices | ||
45 | + * @return JSON node | ||
46 | + */ | ||
47 | + public static JsonNode json(DeviceService service, Iterable<Device> devices) { | ||
48 | + ObjectMapper mapper = new ObjectMapper(); | ||
49 | + ArrayNode result = mapper.createArrayNode(); | ||
50 | + for (Device device : devices) { | ||
51 | + result.add(json(service, mapper, device)); | ||
52 | + } | ||
53 | + return result; | ||
54 | + } | ||
55 | + | ||
56 | + /** | ||
57 | + * Returns JSON node representing the specified device. | ||
58 | + * | ||
59 | + * @param service device service | ||
60 | + * @param mapper object mapper | ||
61 | + * @param device infrastructure device | ||
62 | + * @return JSON node | ||
63 | + */ | ||
64 | + public static ObjectNode json(DeviceService service, ObjectMapper mapper, | ||
65 | + Device device) { | ||
66 | + ObjectNode result = mapper.createObjectNode(); | ||
67 | + if (device != null) { | ||
68 | + result.put("id", device.id().toString()) | ||
69 | + .put("available", service.isAvailable(device.id())) | ||
70 | + .put("role", service.getRole(device.id()).toString()) | ||
71 | + .put("mfr", device.manufacturer()) | ||
72 | + .put("hw", device.hwVersion()) | ||
73 | + .put("sw", device.swVersion()) | ||
74 | + .put("serial", device.serialNumber()); | ||
75 | + } | ||
76 | + return result; | ||
77 | + } | ||
31 | 78 | ||
32 | /** | 79 | /** |
33 | * Returns the list of devices sorted using the device ID URIs. | 80 | * Returns the list of devices sorted using the device ID URIs. | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import com.google.common.collect.Maps; | 7 | import com.google.common.collect.Maps; |
4 | import org.apache.karaf.shell.commands.Argument; | 8 | import org.apache.karaf.shell.commands.Argument; |
5 | import org.apache.karaf.shell.commands.Command; | 9 | import org.apache.karaf.shell.commands.Command; |
... | @@ -12,6 +16,8 @@ import org.onlab.onos.net.device.DeviceService; | ... | @@ -12,6 +16,8 @@ import org.onlab.onos.net.device.DeviceService; |
12 | import org.onlab.onos.net.flow.FlowEntry; | 16 | import org.onlab.onos.net.flow.FlowEntry; |
13 | import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; | 17 | import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; |
14 | import org.onlab.onos.net.flow.FlowRuleService; | 18 | import org.onlab.onos.net.flow.FlowRuleService; |
19 | +import org.onlab.onos.net.flow.criteria.Criterion; | ||
20 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
15 | 21 | ||
16 | import java.util.Collections; | 22 | import java.util.Collections; |
17 | import java.util.List; | 23 | import java.util.List; |
... | @@ -48,10 +54,74 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -48,10 +54,74 @@ public class FlowsListCommand extends AbstractShellCommand { |
48 | DeviceService deviceService = get(DeviceService.class); | 54 | DeviceService deviceService = get(DeviceService.class); |
49 | FlowRuleService service = get(FlowRuleService.class); | 55 | FlowRuleService service = get(FlowRuleService.class); |
50 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); | 56 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); |
57 | + | ||
58 | + if (outputJson()) { | ||
59 | + print("%s", json(coreService, getSortedDevices(deviceService), flows)); | ||
60 | + } else { | ||
51 | for (Device d : getSortedDevices(deviceService)) { | 61 | for (Device d : getSortedDevices(deviceService)) { |
52 | printFlows(d, flows.get(d), coreService); | 62 | printFlows(d, flows.get(d), coreService); |
53 | } | 63 | } |
54 | } | 64 | } |
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Produces a JSON array of flows grouped by the each device. | ||
69 | + * | ||
70 | + * @param coreService core service | ||
71 | + * @param devices collection of devices to group flow by | ||
72 | + * @param flows collection of flows per each device | ||
73 | + * @return JSON array | ||
74 | + */ | ||
75 | + private JsonNode json(CoreService coreService, Iterable<Device> devices, | ||
76 | + Map<Device, List<FlowEntry>> flows) { | ||
77 | + ObjectMapper mapper = new ObjectMapper(); | ||
78 | + ArrayNode result = mapper.createArrayNode(); | ||
79 | + for (Device device : devices) { | ||
80 | + result.add(json(coreService, mapper, device, flows.get(device))); | ||
81 | + } | ||
82 | + return result; | ||
83 | + } | ||
84 | + | ||
85 | + // Produces JSON object with the flows of the given device. | ||
86 | + private ObjectNode json(CoreService coreService, ObjectMapper mapper, | ||
87 | + Device device, List<FlowEntry> flows) { | ||
88 | + ObjectNode result = mapper.createObjectNode(); | ||
89 | + ArrayNode array = mapper.createArrayNode(); | ||
90 | + | ||
91 | + for (FlowEntry flow : flows) { | ||
92 | + array.add(json(coreService, mapper, flow)); | ||
93 | + } | ||
94 | + | ||
95 | + result.put("device", device.id().toString()) | ||
96 | + .put("flowCount", flows.size()) | ||
97 | + .put("flows", array); | ||
98 | + return result; | ||
99 | + } | ||
100 | + | ||
101 | + // Produces JSON structure with the specified flow data. | ||
102 | + private ObjectNode json(CoreService coreService, ObjectMapper mapper, | ||
103 | + FlowEntry flow) { | ||
104 | + ObjectNode result = mapper.createObjectNode(); | ||
105 | + ArrayNode crit = mapper.createArrayNode(); | ||
106 | + for (Criterion c : flow.selector().criteria()) { | ||
107 | + crit.add(c.toString()); | ||
108 | + } | ||
109 | + | ||
110 | + ArrayNode instr = mapper.createArrayNode(); | ||
111 | + for (Instruction i : flow.treatment().instructions()) { | ||
112 | + instr.add(i.toString()); | ||
113 | + } | ||
114 | + | ||
115 | + result.put("flowId", Long.toHexString(flow.id().value())) | ||
116 | + .put("state", flow.state().toString()) | ||
117 | + .put("bytes", flow.bytes()) | ||
118 | + .put("packets", flow.packets()) | ||
119 | + .put("life", flow.life()) | ||
120 | + .put("appId", coreService.getAppId(flow.appId()).name()); | ||
121 | + result.set("selector", crit); | ||
122 | + result.set("treatment", instr); | ||
123 | + return result; | ||
124 | + } | ||
55 | 125 | ||
56 | /** | 126 | /** |
57 | * Returns the list of devices sorted using the device ID URIs. | 127 | * Returns the list of devices sorted using the device ID URIs. | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 8 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.cli.Comparators; | 9 | import org.onlab.onos.cli.Comparators; |
6 | import org.onlab.onos.net.Host; | 10 | import org.onlab.onos.net.Host; |
7 | import org.onlab.onos.net.host.HostService; | 11 | import org.onlab.onos.net.host.HostService; |
12 | +import org.onlab.packet.IpPrefix; | ||
8 | 13 | ||
9 | import java.util.Collections; | 14 | import java.util.Collections; |
10 | import java.util.List; | 15 | import java.util.List; |
... | @@ -24,10 +29,41 @@ public class HostsListCommand extends AbstractShellCommand { | ... | @@ -24,10 +29,41 @@ public class HostsListCommand extends AbstractShellCommand { |
24 | @Override | 29 | @Override |
25 | protected void execute() { | 30 | protected void execute() { |
26 | HostService service = get(HostService.class); | 31 | HostService service = get(HostService.class); |
32 | + if (outputJson()) { | ||
33 | + print("%s", json(getSortedHosts(service))); | ||
34 | + } else { | ||
27 | for (Host host : getSortedHosts(service)) { | 35 | for (Host host : getSortedHosts(service)) { |
28 | printHost(host); | 36 | printHost(host); |
29 | } | 37 | } |
30 | } | 38 | } |
39 | + } | ||
40 | + | ||
41 | + // Produces JSON structure. | ||
42 | + private static JsonNode json(Iterable<Host> hosts) { | ||
43 | + ObjectMapper mapper = new ObjectMapper(); | ||
44 | + ArrayNode result = mapper.createArrayNode(); | ||
45 | + for (Host host : hosts) { | ||
46 | + result.add(json(mapper, host)); | ||
47 | + } | ||
48 | + return result; | ||
49 | + } | ||
50 | + | ||
51 | + // Produces JSON structure. | ||
52 | + private static JsonNode json(ObjectMapper mapper, Host host) { | ||
53 | + ObjectNode loc = LinksListCommand.json(mapper, host.location()) | ||
54 | + .put("time", host.location().time()); | ||
55 | + ArrayNode ips = mapper.createArrayNode(); | ||
56 | + for (IpPrefix ip : host.ipAddresses()) { | ||
57 | + ips.add(ip.toString()); | ||
58 | + } | ||
59 | + ObjectNode result = mapper.createObjectNode() | ||
60 | + .put("id", host.id().toString()) | ||
61 | + .put("mac", host.mac().toString()) | ||
62 | + .put("vlan", host.vlan().toString()); | ||
63 | + result.set("location", loc); | ||
64 | + result.set("ips", ips); | ||
65 | + return result; | ||
66 | + } | ||
31 | 67 | ||
32 | /** | 68 | /** |
33 | * Returns the list of devices sorted using the device ID URIs. | 69 | * Returns the list of devices sorted using the device ID URIs. |
... | @@ -44,7 +80,7 @@ public class HostsListCommand extends AbstractShellCommand { | ... | @@ -44,7 +80,7 @@ public class HostsListCommand extends AbstractShellCommand { |
44 | /** | 80 | /** |
45 | * Prints information about a host. | 81 | * Prints information about a host. |
46 | * | 82 | * |
47 | - * @param host | 83 | + * @param host end-station host |
48 | */ | 84 | */ |
49 | protected void printHost(Host host) { | 85 | protected void printHost(Host host) { |
50 | if (host != null) { | 86 | if (host != null) { |
... | @@ -54,4 +90,4 @@ public class HostsListCommand extends AbstractShellCommand { | ... | @@ -54,4 +90,4 @@ public class HostsListCommand extends AbstractShellCommand { |
54 | host.vlan(), host.ipAddresses()); | 90 | host.vlan(), host.ipAddresses()); |
55 | } | 91 | } |
56 | } | 92 | } |
57 | - } | 93 | +} | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 7 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 8 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.cli.AbstractShellCommand; | 9 | import org.onlab.onos.cli.AbstractShellCommand; |
10 | +import org.onlab.onos.net.ConnectPoint; | ||
6 | import org.onlab.onos.net.Link; | 11 | import org.onlab.onos.net.Link; |
7 | import org.onlab.onos.net.link.LinkService; | 12 | import org.onlab.onos.net.link.LinkService; |
8 | 13 | ||
... | @@ -27,10 +32,56 @@ public class LinksListCommand extends AbstractShellCommand { | ... | @@ -27,10 +32,56 @@ public class LinksListCommand extends AbstractShellCommand { |
27 | LinkService service = get(LinkService.class); | 32 | LinkService service = get(LinkService.class); |
28 | Iterable<Link> links = uri != null ? | 33 | Iterable<Link> links = uri != null ? |
29 | service.getDeviceLinks(deviceId(uri)) : service.getLinks(); | 34 | service.getDeviceLinks(deviceId(uri)) : service.getLinks(); |
35 | + if (outputJson()) { | ||
36 | + print("%s", json(links)); | ||
37 | + } else { | ||
30 | for (Link link : links) { | 38 | for (Link link : links) { |
31 | print(linkString(link)); | 39 | print(linkString(link)); |
32 | } | 40 | } |
33 | } | 41 | } |
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Produces a JSON array containing the specified links. | ||
46 | + * | ||
47 | + * @param links collection of links | ||
48 | + * @return JSON array | ||
49 | + */ | ||
50 | + public static JsonNode json(Iterable<Link> links) { | ||
51 | + ObjectMapper mapper = new ObjectMapper(); | ||
52 | + ArrayNode result = mapper.createArrayNode(); | ||
53 | + for (Link link : links) { | ||
54 | + result.add(json(mapper, link)); | ||
55 | + } | ||
56 | + return result; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Produces a JSON object for the specified link. | ||
61 | + * | ||
62 | + * @param mapper object mapper | ||
63 | + * @param link link to encode | ||
64 | + * @return JSON object | ||
65 | + */ | ||
66 | + public static ObjectNode json(ObjectMapper mapper, Link link) { | ||
67 | + ObjectNode result = mapper.createObjectNode(); | ||
68 | + result.set("src", json(mapper, link.src())); | ||
69 | + result.set("dst", json(mapper, link.dst())); | ||
70 | + return result; | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Produces a JSON object for the specified connect point. | ||
75 | + * | ||
76 | + * @param mapper object mapper | ||
77 | + * @param connectPoint connection point to encode | ||
78 | + * @return JSON object | ||
79 | + */ | ||
80 | + public static ObjectNode json(ObjectMapper mapper, ConnectPoint connectPoint) { | ||
81 | + return mapper.createObjectNode() | ||
82 | + .put("device", connectPoint.deviceId().toString()) | ||
83 | + .put("port", connectPoint.port().toString()); | ||
84 | + } | ||
34 | 85 | ||
35 | /** | 86 | /** |
36 | * Returns a formatted string representing the given link. | 87 | * Returns a formatted string representing the given link. | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 6 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.net.Link; | 8 | import org.onlab.onos.net.Link; |
... | @@ -32,10 +35,31 @@ public class PathListCommand extends TopologyCommand { | ... | @@ -32,10 +35,31 @@ public class PathListCommand extends TopologyCommand { |
32 | protected void execute() { | 35 | protected void execute() { |
33 | init(); | 36 | init(); |
34 | Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); | 37 | Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); |
38 | + if (outputJson()) { | ||
39 | + print("%s", json(paths)); | ||
40 | + } else { | ||
35 | for (Path path : paths) { | 41 | for (Path path : paths) { |
36 | print(pathString(path)); | 42 | print(pathString(path)); |
37 | } | 43 | } |
38 | } | 44 | } |
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Produces a JSON array containing the specified paths. | ||
49 | + * | ||
50 | + * @param paths collection of paths | ||
51 | + * @return JSON array | ||
52 | + */ | ||
53 | + public static JsonNode json(Iterable<Path> paths) { | ||
54 | + ObjectMapper mapper = new ObjectMapper(); | ||
55 | + ArrayNode result = mapper.createArrayNode(); | ||
56 | + for (Path path : paths) { | ||
57 | + result.add(LinksListCommand.json(mapper, path) | ||
58 | + .put("cost", path.cost()) | ||
59 | + .set("links", LinksListCommand.json(path.links()))); | ||
60 | + } | ||
61 | + return result; | ||
62 | + } | ||
39 | 63 | ||
40 | /** | 64 | /** |
41 | * Produces a formatted string representing the specified path. | 65 | * Produces a formatted string representing the specified path. | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import org.apache.karaf.shell.commands.Command; | 4 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 5 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.net.topology.Topology; | 6 | import org.onlab.onos.net.topology.Topology; |
... | @@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand { | ... | @@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand { |
30 | @Override | 31 | @Override |
31 | protected void execute() { | 32 | protected void execute() { |
32 | init(); | 33 | init(); |
34 | + if (outputJson()) { | ||
35 | + print("%s", new ObjectMapper().createObjectNode() | ||
36 | + .put("time", topology.time()) | ||
37 | + .put("deviceCount", topology.deviceCount()) | ||
38 | + .put("linkCount", topology.linkCount()) | ||
39 | + .put("clusterCount", topology.clusterCount()) | ||
40 | + .put("pathCount", topology.pathCount())); | ||
41 | + } else { | ||
33 | print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), | 42 | print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), |
34 | topology.clusterCount(), topology.pathCount()); | 43 | topology.clusterCount(), topology.pathCount()); |
35 | } | 44 | } |
45 | + } | ||
36 | 46 | ||
37 | } | 47 | } | ... | ... |
... | @@ -12,8 +12,12 @@ public final class ControllerNodeToNodeId | ... | @@ -12,8 +12,12 @@ public final class ControllerNodeToNodeId |
12 | 12 | ||
13 | @Override | 13 | @Override |
14 | public NodeId apply(ControllerNode input) { | 14 | public NodeId apply(ControllerNode input) { |
15 | + if (input == null) { | ||
16 | + return null; | ||
17 | + } else { | ||
15 | return input.id(); | 18 | return input.id(); |
16 | } | 19 | } |
20 | + } | ||
17 | 21 | ||
18 | /** | 22 | /** |
19 | * Returns a Function to convert ControllerNode to NodeId. | 23 | * Returns a Function to convert ControllerNode to NodeId. | ... | ... |
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | +import java.util.Collections; | ||
4 | +import java.util.Set; | ||
5 | + | ||
3 | import org.onlab.onos.net.AbstractDescription; | 6 | import org.onlab.onos.net.AbstractDescription; |
4 | import org.onlab.onos.net.HostLocation; | 7 | import org.onlab.onos.net.HostLocation; |
5 | import org.onlab.onos.net.SparseAnnotations; | 8 | import org.onlab.onos.net.SparseAnnotations; |
... | @@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix; | ... | @@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix; |
7 | import org.onlab.packet.MacAddress; | 10 | import org.onlab.packet.MacAddress; |
8 | import org.onlab.packet.VlanId; | 11 | import org.onlab.packet.VlanId; |
9 | 12 | ||
13 | +import com.google.common.collect.ImmutableSet; | ||
14 | + | ||
10 | import static com.google.common.base.MoreObjects.toStringHelper; | 15 | import static com.google.common.base.MoreObjects.toStringHelper; |
11 | 16 | ||
12 | /** | 17 | /** |
... | @@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription |
18 | private final MacAddress mac; | 23 | private final MacAddress mac; |
19 | private final VlanId vlan; | 24 | private final VlanId vlan; |
20 | private final HostLocation location; | 25 | private final HostLocation location; |
21 | - private final IpPrefix ip; | 26 | + private final Set<IpPrefix> ip; |
22 | 27 | ||
23 | /** | 28 | /** |
24 | * Creates a host description using the supplied information. | 29 | * Creates a host description using the supplied information. |
... | @@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription |
31 | public DefaultHostDescription(MacAddress mac, VlanId vlan, | 36 | public DefaultHostDescription(MacAddress mac, VlanId vlan, |
32 | HostLocation location, | 37 | HostLocation location, |
33 | SparseAnnotations... annotations) { | 38 | SparseAnnotations... annotations) { |
34 | - this(mac, vlan, location, null, annotations); | 39 | + this(mac, vlan, location, Collections.<IpPrefix>emptySet(), annotations); |
35 | } | 40 | } |
36 | 41 | ||
37 | /** | 42 | /** |
... | @@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription |
46 | public DefaultHostDescription(MacAddress mac, VlanId vlan, | 51 | public DefaultHostDescription(MacAddress mac, VlanId vlan, |
47 | HostLocation location, IpPrefix ip, | 52 | HostLocation location, IpPrefix ip, |
48 | SparseAnnotations... annotations) { | 53 | SparseAnnotations... annotations) { |
54 | + this(mac, vlan, location, ImmutableSet.of(ip), annotations); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Creates a host description using the supplied information. | ||
59 | + * | ||
60 | + * @param mac host MAC address | ||
61 | + * @param vlan host VLAN identifier | ||
62 | + * @param location host location | ||
63 | + * @param ip host IP addresses | ||
64 | + * @param annotations optional key/value annotations map | ||
65 | + */ | ||
66 | + public DefaultHostDescription(MacAddress mac, VlanId vlan, | ||
67 | + HostLocation location, Set<IpPrefix> ip, | ||
68 | + SparseAnnotations... annotations) { | ||
49 | super(annotations); | 69 | super(annotations); |
50 | this.mac = mac; | 70 | this.mac = mac; |
51 | this.vlan = vlan; | 71 | this.vlan = vlan; |
52 | this.location = location; | 72 | this.location = location; |
53 | - this.ip = ip; | 73 | + this.ip = ImmutableSet.copyOf(ip); |
54 | } | 74 | } |
55 | 75 | ||
56 | @Override | 76 | @Override |
... | @@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription |
69 | } | 89 | } |
70 | 90 | ||
71 | @Override | 91 | @Override |
72 | - public IpPrefix ipAddress() { | 92 | + public Set<IpPrefix> ipAddress() { |
73 | return ip; | 93 | return ip; |
74 | } | 94 | } |
75 | 95 | ... | ... |
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | +import java.util.Set; | ||
4 | + | ||
3 | import org.onlab.onos.net.Description; | 5 | import org.onlab.onos.net.Description; |
4 | import org.onlab.onos.net.HostLocation; | 6 | import org.onlab.onos.net.HostLocation; |
5 | import org.onlab.packet.IpPrefix; | 7 | import org.onlab.packet.IpPrefix; |
... | @@ -38,6 +40,6 @@ public interface HostDescription extends Description { | ... | @@ -38,6 +40,6 @@ public interface HostDescription extends Description { |
38 | * @return host IP address | 40 | * @return host IP address |
39 | */ | 41 | */ |
40 | // FIXME: Switch to IpAddress | 42 | // FIXME: Switch to IpAddress |
41 | - IpPrefix ipAddress(); | 43 | + Set<IpPrefix> ipAddress(); |
42 | 44 | ||
43 | } | 45 | } | ... | ... |
1 | package org.onlab.onos.cluster; | 1 | package org.onlab.onos.cluster; |
2 | 2 | ||
3 | +import static com.google.common.base.Predicates.notNull; | ||
3 | import static org.junit.Assert.*; | 4 | import static org.junit.Assert.*; |
4 | import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId; | 5 | import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId; |
5 | 6 | ||
... | @@ -30,12 +31,13 @@ public class ControllerNodeToNodeIdTest { | ... | @@ -30,12 +31,13 @@ public class ControllerNodeToNodeIdTest { |
30 | @Test | 31 | @Test |
31 | public final void testToNodeId() { | 32 | public final void testToNodeId() { |
32 | 33 | ||
33 | - final Iterable<ControllerNode> nodes = Arrays.asList(CN1, CN2, CN3); | 34 | + final Iterable<ControllerNode> nodes = Arrays.asList(CN1, CN2, CN3, null); |
34 | final List<NodeId> nodeIds = Arrays.asList(NID1, NID2, NID3); | 35 | final List<NodeId> nodeIds = Arrays.asList(NID1, NID2, NID3); |
35 | 36 | ||
36 | assertEquals(nodeIds, | 37 | assertEquals(nodeIds, |
37 | FluentIterable.from(nodes) | 38 | FluentIterable.from(nodes) |
38 | .transform(toNodeId()) | 39 | .transform(toNodeId()) |
40 | + .filter(notNull()) | ||
39 | .toList()); | 41 | .toList()); |
40 | } | 42 | } |
41 | 43 | ... | ... |
... | @@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix; | ... | @@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix; |
8 | import org.onlab.packet.MacAddress; | 8 | import org.onlab.packet.MacAddress; |
9 | import org.onlab.packet.VlanId; | 9 | import org.onlab.packet.VlanId; |
10 | 10 | ||
11 | +import com.google.common.collect.ImmutableSet; | ||
12 | + | ||
11 | import static org.junit.Assert.assertEquals; | 13 | import static org.junit.Assert.assertEquals; |
12 | import static org.junit.Assert.assertTrue; | 14 | import static org.junit.Assert.assertTrue; |
13 | 15 | ||
... | @@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest { | ... | @@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest { |
33 | assertEquals("incorrect mac", MAC, host.hwAddress()); | 35 | assertEquals("incorrect mac", MAC, host.hwAddress()); |
34 | assertEquals("incorrect vlan", VLAN, host.vlan()); | 36 | assertEquals("incorrect vlan", VLAN, host.vlan()); |
35 | assertEquals("incorrect location", LOC, host.location()); | 37 | assertEquals("incorrect location", LOC, host.location()); |
36 | - assertEquals("incorrect ip's", IP, host.ipAddress()); | 38 | + assertEquals("incorrect ip's", ImmutableSet.of(IP), host.ipAddress()); |
37 | assertTrue("incorrect toString", host.toString().contains("vlan=10")); | 39 | assertTrue("incorrect toString", host.toString().contains("vlan=10")); |
38 | } | 40 | } |
39 | 41 | ... | ... |
... | @@ -355,7 +355,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -355,7 +355,7 @@ public class ProxyArpManager implements ProxyArpService { |
355 | 355 | ||
356 | arp.setTargetProtocolAddress(((ARP) request.getPayload()) | 356 | arp.setTargetProtocolAddress(((ARP) request.getPayload()) |
357 | .getSenderProtocolAddress()); | 357 | .getSenderProtocolAddress()); |
358 | - arp.setSenderProtocolAddress(srcIp.toRealInt()); | 358 | + arp.setSenderProtocolAddress(srcIp.toInt()); |
359 | eth.setPayload(arp); | 359 | eth.setPayload(arp); |
360 | return eth; | 360 | return eth; |
361 | } | 361 | } | ... | ... |
... | @@ -515,12 +515,12 @@ public class GossipDeviceStore | ... | @@ -515,12 +515,12 @@ public class GossipDeviceStore |
515 | Map<PortNumber, Port> ports, | 515 | Map<PortNumber, Port> ports, |
516 | Set<PortNumber> processed) { | 516 | Set<PortNumber> processed) { |
517 | List<DeviceEvent> events = new ArrayList<>(); | 517 | List<DeviceEvent> events = new ArrayList<>(); |
518 | - Iterator<PortNumber> iterator = ports.keySet().iterator(); | 518 | + Iterator<Entry<PortNumber, Port>> iterator = ports.entrySet().iterator(); |
519 | while (iterator.hasNext()) { | 519 | while (iterator.hasNext()) { |
520 | - PortNumber portNumber = iterator.next(); | 520 | + Entry<PortNumber, Port> e = iterator.next(); |
521 | + PortNumber portNumber = e.getKey(); | ||
521 | if (!processed.contains(portNumber)) { | 522 | if (!processed.contains(portNumber)) { |
522 | - events.add(new DeviceEvent(PORT_REMOVED, device, | 523 | + events.add(new DeviceEvent(PORT_REMOVED, device, e.getValue())); |
523 | - ports.get(portNumber))); | ||
524 | iterator.remove(); | 524 | iterator.remove(); |
525 | } | 525 | } |
526 | } | 526 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -4,6 +4,11 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject; | ... | @@ -4,6 +4,11 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject; |
4 | 4 | ||
5 | public final class GossipHostStoreMessageSubjects { | 5 | public final class GossipHostStoreMessageSubjects { |
6 | private GossipHostStoreMessageSubjects() {} | 6 | private GossipHostStoreMessageSubjects() {} |
7 | - public static final MessageSubject HOST_UPDATED = new MessageSubject("peer-host-updated"); | 7 | + |
8 | - public static final MessageSubject HOST_REMOVED = new MessageSubject("peer-host-removed"); | 8 | + public static final MessageSubject HOST_UPDATED |
9 | + = new MessageSubject("peer-host-updated"); | ||
10 | + public static final MessageSubject HOST_REMOVED | ||
11 | + = new MessageSubject("peer-host-removed"); | ||
12 | + public static final MessageSubject HOST_ANTI_ENTROPY_ADVERTISEMENT | ||
13 | + = new MessageSubject("host-enti-entropy-advertisement");; | ||
9 | } | 14 | } | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/HostAntiEntropyAdvertisement.java
0 → 100644
1 | +package org.onlab.onos.store.host.impl; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import org.onlab.onos.cluster.NodeId; | ||
8 | +import org.onlab.onos.net.HostId; | ||
9 | +import org.onlab.onos.store.Timestamp; | ||
10 | + | ||
11 | +/** | ||
12 | + * Host AE Advertisement message. | ||
13 | + */ | ||
14 | +public final class HostAntiEntropyAdvertisement { | ||
15 | + | ||
16 | + private final NodeId sender; | ||
17 | + private final Map<HostFragmentId, Timestamp> timestamps; | ||
18 | + private final Map<HostId, Timestamp> tombstones; | ||
19 | + | ||
20 | + | ||
21 | + public HostAntiEntropyAdvertisement(NodeId sender, | ||
22 | + Map<HostFragmentId, Timestamp> timestamps, | ||
23 | + Map<HostId, Timestamp> tombstones) { | ||
24 | + this.sender = checkNotNull(sender); | ||
25 | + this.timestamps = checkNotNull(timestamps); | ||
26 | + this.tombstones = checkNotNull(tombstones); | ||
27 | + } | ||
28 | + | ||
29 | + public NodeId sender() { | ||
30 | + return sender; | ||
31 | + } | ||
32 | + | ||
33 | + public Map<HostFragmentId, Timestamp> timestamps() { | ||
34 | + return timestamps; | ||
35 | + } | ||
36 | + | ||
37 | + public Map<HostId, Timestamp> tombstones() { | ||
38 | + return tombstones; | ||
39 | + } | ||
40 | + | ||
41 | + // For serializer | ||
42 | + @SuppressWarnings("unused") | ||
43 | + private HostAntiEntropyAdvertisement() { | ||
44 | + this.sender = null; | ||
45 | + this.timestamps = null; | ||
46 | + this.tombstones = null; | ||
47 | + } | ||
48 | +} |
1 | +package org.onlab.onos.store.host.impl; | ||
2 | + | ||
3 | +import java.util.Objects; | ||
4 | + | ||
5 | +import org.onlab.onos.net.HostId; | ||
6 | +import org.onlab.onos.net.provider.ProviderId; | ||
7 | + | ||
8 | +import com.google.common.base.MoreObjects; | ||
9 | + | ||
10 | +/** | ||
11 | + * Identifier for HostDescription from a Provider. | ||
12 | + */ | ||
13 | +public final class HostFragmentId { | ||
14 | + public final ProviderId providerId; | ||
15 | + public final HostId hostId; | ||
16 | + | ||
17 | + public HostFragmentId(HostId hostId, ProviderId providerId) { | ||
18 | + this.providerId = providerId; | ||
19 | + this.hostId = hostId; | ||
20 | + } | ||
21 | + | ||
22 | + public HostId hostId() { | ||
23 | + return hostId; | ||
24 | + } | ||
25 | + | ||
26 | + public ProviderId providerId() { | ||
27 | + return providerId; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + public int hashCode() { | ||
32 | + return Objects.hash(providerId, hostId); | ||
33 | + } | ||
34 | + | ||
35 | + @Override | ||
36 | + public boolean equals(Object obj) { | ||
37 | + if (this == obj) { | ||
38 | + return true; | ||
39 | + } | ||
40 | + if (!(obj instanceof HostFragmentId)) { | ||
41 | + return false; | ||
42 | + } | ||
43 | + HostFragmentId that = (HostFragmentId) obj; | ||
44 | + return Objects.equals(this.hostId, that.hostId) && | ||
45 | + Objects.equals(this.providerId, that.providerId); | ||
46 | + } | ||
47 | + | ||
48 | + @Override | ||
49 | + public String toString() { | ||
50 | + return MoreObjects.toStringHelper(getClass()) | ||
51 | + .add("providerId", providerId) | ||
52 | + .add("hostId", hostId) | ||
53 | + .toString(); | ||
54 | + } | ||
55 | + | ||
56 | + // for serializer | ||
57 | + @SuppressWarnings("unused") | ||
58 | + private HostFragmentId() { | ||
59 | + this.providerId = null; | ||
60 | + this.hostId = null; | ||
61 | + } | ||
62 | +} |
This diff is collapsed. Click to expand it.
core/store/hz/net/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
5 | - <modelVersion>4.0.0</modelVersion> | ||
6 | - | ||
7 | - <parent> | ||
8 | - <groupId>org.onlab.onos</groupId> | ||
9 | - <artifactId>onos-core-hz</artifactId> | ||
10 | - <version>1.0.0-SNAPSHOT</version> | ||
11 | - <relativePath>../pom.xml</relativePath> | ||
12 | - </parent> | ||
13 | - | ||
14 | - <artifactId>onos-core-hz-net</artifactId> | ||
15 | - <packaging>bundle</packaging> | ||
16 | - | ||
17 | - <description>ONOS Hazelcast based distributed store subsystems</description> | ||
18 | - | ||
19 | - <dependencies> | ||
20 | - <dependency> | ||
21 | - <groupId>org.onlab.onos</groupId> | ||
22 | - <artifactId>onos-api</artifactId> | ||
23 | - </dependency> | ||
24 | - <dependency> | ||
25 | - <groupId>org.onlab.onos</groupId> | ||
26 | - <artifactId>onos-core-hz-common</artifactId> | ||
27 | - <version>${project.version}</version> | ||
28 | - </dependency> | ||
29 | - <dependency> | ||
30 | - <groupId>org.onlab.onos</groupId> | ||
31 | - <artifactId>onos-core-hz-common</artifactId> | ||
32 | - <classifier>tests</classifier> | ||
33 | - <scope>test</scope> | ||
34 | - <version>${project.version}</version> | ||
35 | - </dependency> | ||
36 | - <dependency> | ||
37 | - <groupId>org.apache.felix</groupId> | ||
38 | - <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
39 | - </dependency> | ||
40 | - <dependency> | ||
41 | - <groupId>com.hazelcast</groupId> | ||
42 | - <artifactId>hazelcast</artifactId> | ||
43 | - </dependency> | ||
44 | - </dependencies> | ||
45 | - | ||
46 | - <build> | ||
47 | - <plugins> | ||
48 | - <plugin> | ||
49 | - <groupId>org.apache.felix</groupId> | ||
50 | - <artifactId>maven-scr-plugin</artifactId> | ||
51 | - </plugin> | ||
52 | - </plugins> | ||
53 | - </build> | ||
54 | - | ||
55 | -</project> |
core/store/hz/net/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
1 | -package org.onlab.onos.store.device.impl; | ||
2 | - | ||
3 | -import org.apache.felix.scr.annotations.Component; | ||
4 | -import org.apache.felix.scr.annotations.Service; | ||
5 | -import org.onlab.onos.mastership.MastershipTerm; | ||
6 | -import org.onlab.onos.net.DeviceId; | ||
7 | -import org.onlab.onos.net.device.DeviceClockProviderService; | ||
8 | - | ||
9 | -// FIXME: Code clone in onos-core-trivial, onos-core-hz-net | ||
10 | -/** | ||
11 | - * Dummy implementation of {@link DeviceClockProviderService}. | ||
12 | - */ | ||
13 | -@Component(immediate = true) | ||
14 | -@Service | ||
15 | -public class NoOpClockProviderService implements DeviceClockProviderService { | ||
16 | - | ||
17 | - @Override | ||
18 | - public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) { | ||
19 | - } | ||
20 | -} |
core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
deleted
100644 → 0
1 | -package org.onlab.onos.store.flow.impl; | ||
2 | - | ||
3 | -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | ||
4 | -import static org.slf4j.LoggerFactory.getLogger; | ||
5 | - | ||
6 | -import java.util.Collection; | ||
7 | -import java.util.Collections; | ||
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.Service; | ||
13 | -import org.onlab.onos.ApplicationId; | ||
14 | -import org.onlab.onos.net.DeviceId; | ||
15 | -import org.onlab.onos.net.flow.DefaultFlowEntry; | ||
16 | -import org.onlab.onos.net.flow.FlowEntry; | ||
17 | -import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; | ||
18 | -import org.onlab.onos.net.flow.FlowRule; | ||
19 | -import org.onlab.onos.net.flow.FlowRuleEvent; | ||
20 | -import org.onlab.onos.net.flow.FlowRuleEvent.Type; | ||
21 | -import org.onlab.onos.net.flow.FlowRuleStore; | ||
22 | -import org.onlab.onos.net.flow.FlowRuleStoreDelegate; | ||
23 | -import org.onlab.onos.store.AbstractStore; | ||
24 | -import org.slf4j.Logger; | ||
25 | - | ||
26 | -import com.google.common.collect.ArrayListMultimap; | ||
27 | -import com.google.common.collect.ImmutableSet; | ||
28 | -import com.google.common.collect.Multimap; | ||
29 | - | ||
30 | -/** | ||
31 | - * Manages inventory of flow rules using trivial in-memory implementation. | ||
32 | - */ | ||
33 | -//FIXME I LIE. I AIN'T DISTRIBUTED | ||
34 | -@Component(immediate = true) | ||
35 | -@Service | ||
36 | -public class DistributedFlowRuleStore | ||
37 | - extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate> | ||
38 | - implements FlowRuleStore { | ||
39 | - | ||
40 | - private final Logger log = getLogger(getClass()); | ||
41 | - | ||
42 | - // store entries as a pile of rules, no info about device tables | ||
43 | - private final Multimap<DeviceId, FlowEntry> flowEntries = | ||
44 | - ArrayListMultimap.<DeviceId, FlowEntry>create(); | ||
45 | - | ||
46 | - private final Multimap<Short, FlowRule> flowEntriesById = | ||
47 | - ArrayListMultimap.<Short, FlowRule>create(); | ||
48 | - | ||
49 | - @Activate | ||
50 | - public void activate() { | ||
51 | - log.info("Started"); | ||
52 | - } | ||
53 | - | ||
54 | - @Deactivate | ||
55 | - public void deactivate() { | ||
56 | - log.info("Stopped"); | ||
57 | - } | ||
58 | - | ||
59 | - | ||
60 | - @Override | ||
61 | - public int getFlowRuleCount() { | ||
62 | - return flowEntries.size(); | ||
63 | - } | ||
64 | - | ||
65 | - @Override | ||
66 | - public synchronized FlowEntry getFlowEntry(FlowRule rule) { | ||
67 | - for (FlowEntry f : flowEntries.get(rule.deviceId())) { | ||
68 | - if (f.equals(rule)) { | ||
69 | - return f; | ||
70 | - } | ||
71 | - } | ||
72 | - return null; | ||
73 | - } | ||
74 | - | ||
75 | - @Override | ||
76 | - public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { | ||
77 | - Collection<FlowEntry> rules = flowEntries.get(deviceId); | ||
78 | - if (rules == null) { | ||
79 | - return Collections.emptyList(); | ||
80 | - } | ||
81 | - return ImmutableSet.copyOf(rules); | ||
82 | - } | ||
83 | - | ||
84 | - @Override | ||
85 | - public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) { | ||
86 | - Collection<FlowRule> rules = flowEntriesById.get(appId.id()); | ||
87 | - if (rules == null) { | ||
88 | - return Collections.emptyList(); | ||
89 | - } | ||
90 | - return ImmutableSet.copyOf(rules); | ||
91 | - } | ||
92 | - | ||
93 | - @Override | ||
94 | - public synchronized void storeFlowRule(FlowRule rule) { | ||
95 | - FlowEntry f = new DefaultFlowEntry(rule); | ||
96 | - DeviceId did = f.deviceId(); | ||
97 | - if (!flowEntries.containsEntry(did, f)) { | ||
98 | - flowEntries.put(did, f); | ||
99 | - flowEntriesById.put(rule.appId(), f); | ||
100 | - } | ||
101 | - } | ||
102 | - | ||
103 | - @Override | ||
104 | - public synchronized void deleteFlowRule(FlowRule rule) { | ||
105 | - FlowEntry entry = getFlowEntry(rule); | ||
106 | - if (entry == null) { | ||
107 | - return; | ||
108 | - } | ||
109 | - entry.setState(FlowEntryState.PENDING_REMOVE); | ||
110 | - } | ||
111 | - | ||
112 | - @Override | ||
113 | - public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) { | ||
114 | - DeviceId did = rule.deviceId(); | ||
115 | - | ||
116 | - // check if this new rule is an update to an existing entry | ||
117 | - FlowEntry stored = getFlowEntry(rule); | ||
118 | - if (stored != null) { | ||
119 | - stored.setBytes(rule.bytes()); | ||
120 | - stored.setLife(rule.life()); | ||
121 | - stored.setPackets(rule.packets()); | ||
122 | - if (stored.state() == FlowEntryState.PENDING_ADD) { | ||
123 | - stored.setState(FlowEntryState.ADDED); | ||
124 | - return new FlowRuleEvent(Type.RULE_ADDED, rule); | ||
125 | - } | ||
126 | - return new FlowRuleEvent(Type.RULE_UPDATED, rule); | ||
127 | - } | ||
128 | - | ||
129 | - flowEntries.put(did, rule); | ||
130 | - return null; | ||
131 | - } | ||
132 | - | ||
133 | - @Override | ||
134 | - public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) { | ||
135 | - // This is where one could mark a rule as removed and still keep it in the store. | ||
136 | - if (flowEntries.remove(rule.deviceId(), rule)) { | ||
137 | - return new FlowRuleEvent(RULE_REMOVED, rule); | ||
138 | - } else { | ||
139 | - return null; | ||
140 | - } | ||
141 | - } | ||
142 | -} |
core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
deleted
100644 → 0
1 | -package org.onlab.onos.store.host.impl; | ||
2 | - | ||
3 | -import com.google.common.collect.HashMultimap; | ||
4 | -import com.google.common.collect.ImmutableSet; | ||
5 | -import com.google.common.collect.Multimap; | ||
6 | -import com.google.common.collect.Sets; | ||
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.Service; | ||
11 | -import org.onlab.onos.net.Annotations; | ||
12 | -import org.onlab.onos.net.ConnectPoint; | ||
13 | -import org.onlab.onos.net.DefaultHost; | ||
14 | -import org.onlab.onos.net.DeviceId; | ||
15 | -import org.onlab.onos.net.Host; | ||
16 | -import org.onlab.onos.net.HostId; | ||
17 | -import org.onlab.onos.net.HostLocation; | ||
18 | -import org.onlab.onos.net.host.HostDescription; | ||
19 | -import org.onlab.onos.net.host.HostEvent; | ||
20 | -import org.onlab.onos.net.host.HostStore; | ||
21 | -import org.onlab.onos.net.host.HostStoreDelegate; | ||
22 | -import org.onlab.onos.net.host.PortAddresses; | ||
23 | -import org.onlab.onos.net.provider.ProviderId; | ||
24 | -import org.onlab.onos.store.AbstractStore; | ||
25 | -import org.onlab.packet.IpPrefix; | ||
26 | -import org.onlab.packet.MacAddress; | ||
27 | -import org.onlab.packet.VlanId; | ||
28 | -import org.slf4j.Logger; | ||
29 | - | ||
30 | -import java.util.HashSet; | ||
31 | -import java.util.Map; | ||
32 | -import java.util.Set; | ||
33 | -import java.util.concurrent.ConcurrentHashMap; | ||
34 | - | ||
35 | -import static org.onlab.onos.net.host.HostEvent.Type.*; | ||
36 | -import static org.slf4j.LoggerFactory.getLogger; | ||
37 | - | ||
38 | -/** | ||
39 | - * TEMPORARY: Manages inventory of end-station hosts using distributed | ||
40 | - * structures implementation. | ||
41 | - */ | ||
42 | -//FIXME: I LIE I AM NOT DISTRIBUTED | ||
43 | -@Component(immediate = true) | ||
44 | -@Service | ||
45 | -public class DistributedHostStore | ||
46 | - extends AbstractStore<HostEvent, HostStoreDelegate> | ||
47 | - implements HostStore { | ||
48 | - | ||
49 | - private final Logger log = getLogger(getClass()); | ||
50 | - | ||
51 | - // Host inventory | ||
52 | - private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(2000000, 0.75f, 16); | ||
53 | - | ||
54 | - // Hosts tracked by their location | ||
55 | - private final Multimap<ConnectPoint, Host> locations = HashMultimap.create(); | ||
56 | - | ||
57 | - private final Map<ConnectPoint, PortAddresses> portAddresses = | ||
58 | - new ConcurrentHashMap<>(); | ||
59 | - | ||
60 | - @Activate | ||
61 | - public void activate() { | ||
62 | - log.info("Started"); | ||
63 | - } | ||
64 | - | ||
65 | - @Deactivate | ||
66 | - public void deactivate() { | ||
67 | - log.info("Stopped"); | ||
68 | - } | ||
69 | - | ||
70 | - @Override | ||
71 | - public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId, | ||
72 | - HostDescription hostDescription) { | ||
73 | - StoredHost host = hosts.get(hostId); | ||
74 | - if (host == null) { | ||
75 | - return createHost(providerId, hostId, hostDescription); | ||
76 | - } | ||
77 | - return updateHost(providerId, host, hostDescription); | ||
78 | - } | ||
79 | - | ||
80 | - // creates a new host and sends HOST_ADDED | ||
81 | - private HostEvent createHost(ProviderId providerId, HostId hostId, | ||
82 | - HostDescription descr) { | ||
83 | - StoredHost newhost = new StoredHost(providerId, hostId, | ||
84 | - descr.hwAddress(), | ||
85 | - descr.vlan(), | ||
86 | - descr.location(), | ||
87 | - ImmutableSet.of(descr.ipAddress())); | ||
88 | - synchronized (this) { | ||
89 | - hosts.put(hostId, newhost); | ||
90 | - locations.put(descr.location(), newhost); | ||
91 | - } | ||
92 | - return new HostEvent(HOST_ADDED, newhost); | ||
93 | - } | ||
94 | - | ||
95 | - // checks for type of update to host, sends appropriate event | ||
96 | - private HostEvent updateHost(ProviderId providerId, StoredHost host, | ||
97 | - HostDescription descr) { | ||
98 | - HostEvent event; | ||
99 | - if (!host.location().equals(descr.location())) { | ||
100 | - host.setLocation(descr.location()); | ||
101 | - return new HostEvent(HOST_MOVED, host); | ||
102 | - } | ||
103 | - | ||
104 | - if (host.ipAddresses().contains(descr.ipAddress())) { | ||
105 | - return null; | ||
106 | - } | ||
107 | - | ||
108 | - Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses()); | ||
109 | - addresses.add(descr.ipAddress()); | ||
110 | - StoredHost updated = new StoredHost(providerId, host.id(), | ||
111 | - host.mac(), host.vlan(), | ||
112 | - descr.location(), addresses); | ||
113 | - event = new HostEvent(HOST_UPDATED, updated); | ||
114 | - synchronized (this) { | ||
115 | - hosts.put(host.id(), updated); | ||
116 | - locations.remove(host.location(), host); | ||
117 | - locations.put(updated.location(), updated); | ||
118 | - } | ||
119 | - return event; | ||
120 | - } | ||
121 | - | ||
122 | - @Override | ||
123 | - public HostEvent removeHost(HostId hostId) { | ||
124 | - synchronized (this) { | ||
125 | - Host host = hosts.remove(hostId); | ||
126 | - if (host != null) { | ||
127 | - locations.remove((host.location()), host); | ||
128 | - return new HostEvent(HOST_REMOVED, host); | ||
129 | - } | ||
130 | - return null; | ||
131 | - } | ||
132 | - } | ||
133 | - | ||
134 | - @Override | ||
135 | - public int getHostCount() { | ||
136 | - return hosts.size(); | ||
137 | - } | ||
138 | - | ||
139 | - @Override | ||
140 | - public Iterable<Host> getHosts() { | ||
141 | - return ImmutableSet.<Host>copyOf(hosts.values()); | ||
142 | - } | ||
143 | - | ||
144 | - @Override | ||
145 | - public Host getHost(HostId hostId) { | ||
146 | - return hosts.get(hostId); | ||
147 | - } | ||
148 | - | ||
149 | - @Override | ||
150 | - public Set<Host> getHosts(VlanId vlanId) { | ||
151 | - Set<Host> vlanset = new HashSet<>(); | ||
152 | - for (Host h : hosts.values()) { | ||
153 | - if (h.vlan().equals(vlanId)) { | ||
154 | - vlanset.add(h); | ||
155 | - } | ||
156 | - } | ||
157 | - return vlanset; | ||
158 | - } | ||
159 | - | ||
160 | - @Override | ||
161 | - public Set<Host> getHosts(MacAddress mac) { | ||
162 | - Set<Host> macset = new HashSet<>(); | ||
163 | - for (Host h : hosts.values()) { | ||
164 | - if (h.mac().equals(mac)) { | ||
165 | - macset.add(h); | ||
166 | - } | ||
167 | - } | ||
168 | - return macset; | ||
169 | - } | ||
170 | - | ||
171 | - @Override | ||
172 | - public Set<Host> getHosts(IpPrefix ip) { | ||
173 | - Set<Host> ipset = new HashSet<>(); | ||
174 | - for (Host h : hosts.values()) { | ||
175 | - if (h.ipAddresses().contains(ip)) { | ||
176 | - ipset.add(h); | ||
177 | - } | ||
178 | - } | ||
179 | - return ipset; | ||
180 | - } | ||
181 | - | ||
182 | - @Override | ||
183 | - public Set<Host> getConnectedHosts(ConnectPoint connectPoint) { | ||
184 | - return ImmutableSet.copyOf(locations.get(connectPoint)); | ||
185 | - } | ||
186 | - | ||
187 | - @Override | ||
188 | - public Set<Host> getConnectedHosts(DeviceId deviceId) { | ||
189 | - Set<Host> hostset = new HashSet<>(); | ||
190 | - for (ConnectPoint p : locations.keySet()) { | ||
191 | - if (p.deviceId().equals(deviceId)) { | ||
192 | - hostset.addAll(locations.get(p)); | ||
193 | - } | ||
194 | - } | ||
195 | - return hostset; | ||
196 | - } | ||
197 | - | ||
198 | - @Override | ||
199 | - public void updateAddressBindings(PortAddresses addresses) { | ||
200 | - synchronized (portAddresses) { | ||
201 | - PortAddresses existing = portAddresses.get(addresses.connectPoint()); | ||
202 | - if (existing == null) { | ||
203 | - portAddresses.put(addresses.connectPoint(), addresses); | ||
204 | - } else { | ||
205 | - Set<IpPrefix> union = Sets.union(existing.ips(), addresses.ips()) | ||
206 | - .immutableCopy(); | ||
207 | - | ||
208 | - MacAddress newMac = (addresses.mac() == null) ? existing.mac() | ||
209 | - : addresses.mac(); | ||
210 | - | ||
211 | - PortAddresses newAddresses = | ||
212 | - new PortAddresses(addresses.connectPoint(), union, newMac); | ||
213 | - | ||
214 | - portAddresses.put(newAddresses.connectPoint(), newAddresses); | ||
215 | - } | ||
216 | - } | ||
217 | - } | ||
218 | - | ||
219 | - @Override | ||
220 | - public void removeAddressBindings(PortAddresses addresses) { | ||
221 | - synchronized (portAddresses) { | ||
222 | - PortAddresses existing = portAddresses.get(addresses.connectPoint()); | ||
223 | - if (existing != null) { | ||
224 | - Set<IpPrefix> difference = | ||
225 | - Sets.difference(existing.ips(), addresses.ips()).immutableCopy(); | ||
226 | - | ||
227 | - // If they removed the existing mac, set the new mac to null. | ||
228 | - // Otherwise, keep the existing mac. | ||
229 | - MacAddress newMac = existing.mac(); | ||
230 | - if (addresses.mac() != null && addresses.mac().equals(existing.mac())) { | ||
231 | - newMac = null; | ||
232 | - } | ||
233 | - | ||
234 | - PortAddresses newAddresses = | ||
235 | - new PortAddresses(addresses.connectPoint(), difference, newMac); | ||
236 | - | ||
237 | - portAddresses.put(newAddresses.connectPoint(), newAddresses); | ||
238 | - } | ||
239 | - } | ||
240 | - } | ||
241 | - | ||
242 | - @Override | ||
243 | - public void clearAddressBindings(ConnectPoint connectPoint) { | ||
244 | - synchronized (portAddresses) { | ||
245 | - portAddresses.remove(connectPoint); | ||
246 | - } | ||
247 | - } | ||
248 | - | ||
249 | - @Override | ||
250 | - public Set<PortAddresses> getAddressBindings() { | ||
251 | - synchronized (portAddresses) { | ||
252 | - return new HashSet<>(portAddresses.values()); | ||
253 | - } | ||
254 | - } | ||
255 | - | ||
256 | - @Override | ||
257 | - public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) { | ||
258 | - PortAddresses addresses; | ||
259 | - | ||
260 | - synchronized (portAddresses) { | ||
261 | - addresses = portAddresses.get(connectPoint); | ||
262 | - } | ||
263 | - | ||
264 | - if (addresses == null) { | ||
265 | - addresses = new PortAddresses(connectPoint, null, null); | ||
266 | - } | ||
267 | - | ||
268 | - return addresses; | ||
269 | - } | ||
270 | - | ||
271 | - // Auxiliary extension to allow location to mutate. | ||
272 | - private class StoredHost extends DefaultHost { | ||
273 | - private HostLocation location; | ||
274 | - | ||
275 | - /** | ||
276 | - * Creates an end-station host using the supplied information. | ||
277 | - * | ||
278 | - * @param providerId provider identity | ||
279 | - * @param id host identifier | ||
280 | - * @param mac host MAC address | ||
281 | - * @param vlan host VLAN identifier | ||
282 | - * @param location host location | ||
283 | - * @param ips host IP addresses | ||
284 | - * @param annotations optional key/value annotations | ||
285 | - */ | ||
286 | - public StoredHost(ProviderId providerId, HostId id, | ||
287 | - MacAddress mac, VlanId vlan, HostLocation location, | ||
288 | - Set<IpPrefix> ips, Annotations... annotations) { | ||
289 | - super(providerId, id, mac, vlan, location, ips, annotations); | ||
290 | - this.location = location; | ||
291 | - } | ||
292 | - | ||
293 | - void setLocation(HostLocation location) { | ||
294 | - this.location = location; | ||
295 | - } | ||
296 | - | ||
297 | - @Override | ||
298 | - public HostLocation location() { | ||
299 | - return location; | ||
300 | - } | ||
301 | - } | ||
302 | -} |
core/store/hz/net/src/main/java/org/onlab/onos/store/link/impl/DistributedLinkStore.java
deleted
100644 → 0
1 | -package org.onlab.onos.store.link.impl; | ||
2 | - | ||
3 | -import static com.google.common.cache.CacheBuilder.newBuilder; | ||
4 | -import static org.onlab.onos.net.Link.Type.DIRECT; | ||
5 | -import static org.onlab.onos.net.Link.Type.INDIRECT; | ||
6 | -import static org.onlab.onos.net.LinkKey.linkKey; | ||
7 | -import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED; | ||
8 | -import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED; | ||
9 | -import static org.onlab.onos.net.link.LinkEvent.Type.LINK_UPDATED; | ||
10 | -import static org.slf4j.LoggerFactory.getLogger; | ||
11 | - | ||
12 | -import java.util.HashSet; | ||
13 | -import java.util.Set; | ||
14 | - | ||
15 | -import org.apache.felix.scr.annotations.Activate; | ||
16 | -import org.apache.felix.scr.annotations.Component; | ||
17 | -import org.apache.felix.scr.annotations.Deactivate; | ||
18 | -import org.apache.felix.scr.annotations.Service; | ||
19 | -import org.onlab.onos.net.ConnectPoint; | ||
20 | -import org.onlab.onos.net.DefaultLink; | ||
21 | -import org.onlab.onos.net.DeviceId; | ||
22 | -import org.onlab.onos.net.Link; | ||
23 | -import org.onlab.onos.net.LinkKey; | ||
24 | -import org.onlab.onos.net.link.LinkDescription; | ||
25 | -import org.onlab.onos.net.link.LinkEvent; | ||
26 | -import org.onlab.onos.net.link.LinkStore; | ||
27 | -import org.onlab.onos.net.link.LinkStoreDelegate; | ||
28 | -import org.onlab.onos.net.provider.ProviderId; | ||
29 | -import org.onlab.onos.store.common.AbsentInvalidatingLoadingCache; | ||
30 | -import org.onlab.onos.store.common.AbstractHazelcastStore; | ||
31 | -import org.onlab.onos.store.common.OptionalCacheLoader; | ||
32 | -import org.slf4j.Logger; | ||
33 | - | ||
34 | -import com.google.common.base.Optional; | ||
35 | -import com.google.common.cache.LoadingCache; | ||
36 | -import com.google.common.collect.HashMultimap; | ||
37 | -import com.google.common.collect.ImmutableSet; | ||
38 | -import com.google.common.collect.Multimap; | ||
39 | -import com.google.common.collect.ImmutableSet.Builder; | ||
40 | -import com.hazelcast.core.IMap; | ||
41 | - | ||
42 | -//TODO: Add support for multiple provider and annotations | ||
43 | -/** | ||
44 | - * Manages inventory of infrastructure links using Hazelcast-backed map. | ||
45 | - */ | ||
46 | -@Component(immediate = true) | ||
47 | -@Service | ||
48 | -public class DistributedLinkStore | ||
49 | - extends AbstractHazelcastStore<LinkEvent, LinkStoreDelegate> | ||
50 | - implements LinkStore { | ||
51 | - | ||
52 | - private final Logger log = getLogger(getClass()); | ||
53 | - | ||
54 | - // Link inventory | ||
55 | - private IMap<byte[], byte[]> rawLinks; | ||
56 | - private LoadingCache<LinkKey, Optional<DefaultLink>> links; | ||
57 | - | ||
58 | - // TODO synchronize? | ||
59 | - // Egress and ingress link sets | ||
60 | - private final Multimap<DeviceId, Link> srcLinks = HashMultimap.create(); | ||
61 | - private final Multimap<DeviceId, Link> dstLinks = HashMultimap.create(); | ||
62 | - | ||
63 | - private String linksListener; | ||
64 | - | ||
65 | - @Override | ||
66 | - @Activate | ||
67 | - public void activate() { | ||
68 | - super.activate(); | ||
69 | - | ||
70 | - boolean includeValue = true; | ||
71 | - | ||
72 | - // TODO decide on Map name scheme to avoid collision | ||
73 | - rawLinks = theInstance.getMap("links"); | ||
74 | - final OptionalCacheLoader<LinkKey, DefaultLink> linkLoader | ||
75 | - = new OptionalCacheLoader<>(serializer, rawLinks); | ||
76 | - links = new AbsentInvalidatingLoadingCache<>(newBuilder().build(linkLoader)); | ||
77 | - // refresh/populate cache based on notification from other instance | ||
78 | - linksListener = rawLinks.addEntryListener(new RemoteLinkEventHandler(links), includeValue); | ||
79 | - | ||
80 | - loadLinkCache(); | ||
81 | - | ||
82 | - log.info("Started"); | ||
83 | - } | ||
84 | - | ||
85 | - @Deactivate | ||
86 | - public void deactivate() { | ||
87 | - rawLinks.removeEntryListener(linksListener); | ||
88 | - log.info("Stopped"); | ||
89 | - } | ||
90 | - | ||
91 | - private void loadLinkCache() { | ||
92 | - for (byte[] keyBytes : rawLinks.keySet()) { | ||
93 | - final LinkKey id = deserialize(keyBytes); | ||
94 | - links.refresh(id); | ||
95 | - } | ||
96 | - } | ||
97 | - | ||
98 | - @Override | ||
99 | - public int getLinkCount() { | ||
100 | - return links.asMap().size(); | ||
101 | - } | ||
102 | - | ||
103 | - @Override | ||
104 | - public Iterable<Link> getLinks() { | ||
105 | - Builder<Link> builder = ImmutableSet.builder(); | ||
106 | - for (Optional<DefaultLink> e : links.asMap().values()) { | ||
107 | - if (e.isPresent()) { | ||
108 | - builder.add(e.get()); | ||
109 | - } | ||
110 | - } | ||
111 | - return builder.build(); | ||
112 | - } | ||
113 | - | ||
114 | - @Override | ||
115 | - public Set<Link> getDeviceEgressLinks(DeviceId deviceId) { | ||
116 | - return ImmutableSet.copyOf(srcLinks.get(deviceId)); | ||
117 | - } | ||
118 | - | ||
119 | - @Override | ||
120 | - public Set<Link> getDeviceIngressLinks(DeviceId deviceId) { | ||
121 | - return ImmutableSet.copyOf(dstLinks.get(deviceId)); | ||
122 | - } | ||
123 | - | ||
124 | - @Override | ||
125 | - public Link getLink(ConnectPoint src, ConnectPoint dst) { | ||
126 | - return links.getUnchecked(linkKey(src, dst)).orNull(); | ||
127 | - } | ||
128 | - | ||
129 | - @Override | ||
130 | - public Set<Link> getEgressLinks(ConnectPoint src) { | ||
131 | - Set<Link> egress = new HashSet<>(); | ||
132 | - for (Link link : srcLinks.get(src.deviceId())) { | ||
133 | - if (link.src().equals(src)) { | ||
134 | - egress.add(link); | ||
135 | - } | ||
136 | - } | ||
137 | - return egress; | ||
138 | - } | ||
139 | - | ||
140 | - @Override | ||
141 | - public Set<Link> getIngressLinks(ConnectPoint dst) { | ||
142 | - Set<Link> ingress = new HashSet<>(); | ||
143 | - for (Link link : dstLinks.get(dst.deviceId())) { | ||
144 | - if (link.dst().equals(dst)) { | ||
145 | - ingress.add(link); | ||
146 | - } | ||
147 | - } | ||
148 | - return ingress; | ||
149 | - } | ||
150 | - | ||
151 | - @Override | ||
152 | - public LinkEvent createOrUpdateLink(ProviderId providerId, | ||
153 | - LinkDescription linkDescription) { | ||
154 | - LinkKey key = linkKey(linkDescription.src(), linkDescription.dst()); | ||
155 | - Optional<DefaultLink> link = links.getUnchecked(key); | ||
156 | - if (!link.isPresent()) { | ||
157 | - return createLink(providerId, key, linkDescription); | ||
158 | - } | ||
159 | - return updateLink(providerId, link.get(), key, linkDescription); | ||
160 | - } | ||
161 | - | ||
162 | - // Creates and stores the link and returns the appropriate event. | ||
163 | - private LinkEvent createLink(ProviderId providerId, LinkKey key, | ||
164 | - LinkDescription linkDescription) { | ||
165 | - DefaultLink link = new DefaultLink(providerId, key.src(), key.dst(), | ||
166 | - linkDescription.type()); | ||
167 | - synchronized (this) { | ||
168 | - final byte[] keyBytes = serialize(key); | ||
169 | - rawLinks.put(keyBytes, serialize(link)); | ||
170 | - links.asMap().putIfAbsent(key, Optional.of(link)); | ||
171 | - | ||
172 | - addNewLink(link); | ||
173 | - } | ||
174 | - return new LinkEvent(LINK_ADDED, link); | ||
175 | - } | ||
176 | - | ||
177 | - // update Egress and ingress link sets | ||
178 | - private void addNewLink(DefaultLink link) { | ||
179 | - synchronized (this) { | ||
180 | - srcLinks.put(link.src().deviceId(), link); | ||
181 | - dstLinks.put(link.dst().deviceId(), link); | ||
182 | - } | ||
183 | - } | ||
184 | - | ||
185 | - // Updates, if necessary the specified link and returns the appropriate event. | ||
186 | - private LinkEvent updateLink(ProviderId providerId, DefaultLink link, | ||
187 | - LinkKey key, LinkDescription linkDescription) { | ||
188 | - // FIXME confirm Link update condition is OK | ||
189 | - if (link.type() == INDIRECT && linkDescription.type() == DIRECT) { | ||
190 | - synchronized (this) { | ||
191 | - | ||
192 | - DefaultLink updated = | ||
193 | - new DefaultLink(providerId, link.src(), link.dst(), | ||
194 | - linkDescription.type()); | ||
195 | - final byte[] keyBytes = serialize(key); | ||
196 | - rawLinks.put(keyBytes, serialize(updated)); | ||
197 | - links.asMap().replace(key, Optional.of(link), Optional.of(updated)); | ||
198 | - | ||
199 | - replaceLink(link, updated); | ||
200 | - return new LinkEvent(LINK_UPDATED, updated); | ||
201 | - } | ||
202 | - } | ||
203 | - return null; | ||
204 | - } | ||
205 | - | ||
206 | - // update Egress and ingress link sets | ||
207 | - private void replaceLink(DefaultLink link, DefaultLink updated) { | ||
208 | - synchronized (this) { | ||
209 | - srcLinks.remove(link.src().deviceId(), link); | ||
210 | - dstLinks.remove(link.dst().deviceId(), link); | ||
211 | - | ||
212 | - srcLinks.put(link.src().deviceId(), updated); | ||
213 | - dstLinks.put(link.dst().deviceId(), updated); | ||
214 | - } | ||
215 | - } | ||
216 | - | ||
217 | - @Override | ||
218 | - public LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) { | ||
219 | - synchronized (this) { | ||
220 | - LinkKey key = linkKey(src, dst); | ||
221 | - byte[] keyBytes = serialize(key); | ||
222 | - Link link = deserialize(rawLinks.remove(keyBytes)); | ||
223 | - links.invalidate(key); | ||
224 | - if (link != null) { | ||
225 | - removeLink(link); | ||
226 | - return new LinkEvent(LINK_REMOVED, link); | ||
227 | - } | ||
228 | - return null; | ||
229 | - } | ||
230 | - } | ||
231 | - | ||
232 | - // update Egress and ingress link sets | ||
233 | - private void removeLink(Link link) { | ||
234 | - synchronized (this) { | ||
235 | - srcLinks.remove(link.src().deviceId(), link); | ||
236 | - dstLinks.remove(link.dst().deviceId(), link); | ||
237 | - } | ||
238 | - } | ||
239 | - | ||
240 | - private class RemoteLinkEventHandler extends RemoteCacheEventHandler<LinkKey, DefaultLink> { | ||
241 | - public RemoteLinkEventHandler(LoadingCache<LinkKey, Optional<DefaultLink>> cache) { | ||
242 | - super(cache); | ||
243 | - } | ||
244 | - | ||
245 | - @Override | ||
246 | - protected void onAdd(LinkKey key, DefaultLink newVal) { | ||
247 | - addNewLink(newVal); | ||
248 | - notifyDelegate(new LinkEvent(LINK_ADDED, newVal)); | ||
249 | - } | ||
250 | - | ||
251 | - @Override | ||
252 | - protected void onUpdate(LinkKey key, DefaultLink oldVal, DefaultLink newVal) { | ||
253 | - replaceLink(oldVal, newVal); | ||
254 | - notifyDelegate(new LinkEvent(LINK_UPDATED, newVal)); | ||
255 | - } | ||
256 | - | ||
257 | - @Override | ||
258 | - protected void onRemove(LinkKey key, DefaultLink val) { | ||
259 | - removeLink(val); | ||
260 | - notifyDelegate(new LinkEvent(LINK_REMOVED, val)); | ||
261 | - } | ||
262 | - } | ||
263 | -} |
core/store/hz/net/src/main/java/org/onlab/onos/store/topology/impl/DefaultTopology.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/topology/impl/DefaultTopologyGraph.java
deleted
100644 → 0
1 | -package org.onlab.onos.store.topology.impl; | ||
2 | - | ||
3 | -import org.onlab.graph.AdjacencyListsGraph; | ||
4 | -import org.onlab.onos.net.topology.TopologyEdge; | ||
5 | -import org.onlab.onos.net.topology.TopologyGraph; | ||
6 | -import org.onlab.onos.net.topology.TopologyVertex; | ||
7 | - | ||
8 | -import java.util.Set; | ||
9 | - | ||
10 | -/** | ||
11 | - * Default implementation of an immutable topology graph based on a generic | ||
12 | - * implementation of adjacency lists graph. | ||
13 | - */ | ||
14 | -public class DefaultTopologyGraph | ||
15 | - extends AdjacencyListsGraph<TopologyVertex, TopologyEdge> | ||
16 | - implements TopologyGraph { | ||
17 | - | ||
18 | - /** | ||
19 | - * Creates a topology graph comprising of the specified vertexes and edges. | ||
20 | - * | ||
21 | - * @param vertexes set of graph vertexes | ||
22 | - * @param edges set of graph edges | ||
23 | - */ | ||
24 | - public DefaultTopologyGraph(Set<TopologyVertex> vertexes, Set<TopologyEdge> edges) { | ||
25 | - super(vertexes, edges); | ||
26 | - } | ||
27 | - | ||
28 | -} |
1 | -package org.onlab.onos.store.topology.impl; | ||
2 | - | ||
3 | -import static org.slf4j.LoggerFactory.getLogger; | ||
4 | - | ||
5 | -import java.util.List; | ||
6 | -import java.util.Set; | ||
7 | - | ||
8 | -import org.apache.felix.scr.annotations.Activate; | ||
9 | -import org.apache.felix.scr.annotations.Component; | ||
10 | -import org.apache.felix.scr.annotations.Deactivate; | ||
11 | -import org.apache.felix.scr.annotations.Service; | ||
12 | -import org.onlab.onos.event.Event; | ||
13 | -import org.onlab.onos.net.ConnectPoint; | ||
14 | -import org.onlab.onos.net.DeviceId; | ||
15 | -import org.onlab.onos.net.Link; | ||
16 | -import org.onlab.onos.net.Path; | ||
17 | -import org.onlab.onos.net.provider.ProviderId; | ||
18 | -import org.onlab.onos.net.topology.ClusterId; | ||
19 | -import org.onlab.onos.net.topology.GraphDescription; | ||
20 | -import org.onlab.onos.net.topology.LinkWeight; | ||
21 | -import org.onlab.onos.net.topology.Topology; | ||
22 | -import org.onlab.onos.net.topology.TopologyCluster; | ||
23 | -import org.onlab.onos.net.topology.TopologyEvent; | ||
24 | -import org.onlab.onos.net.topology.TopologyGraph; | ||
25 | -import org.onlab.onos.net.topology.TopologyStore; | ||
26 | -import org.onlab.onos.net.topology.TopologyStoreDelegate; | ||
27 | -import org.onlab.onos.store.AbstractStore; | ||
28 | -import org.slf4j.Logger; | ||
29 | - | ||
30 | -/** | ||
31 | - * TEMPORARY: Manages inventory of topology snapshots using distributed | ||
32 | - * structures implementation. | ||
33 | - */ | ||
34 | -//FIXME: I LIE I AM NOT DISTRIBUTED | ||
35 | -@Component(immediate = true) | ||
36 | -@Service | ||
37 | -public class DistributedTopologyStore | ||
38 | -extends AbstractStore<TopologyEvent, TopologyStoreDelegate> | ||
39 | -implements TopologyStore { | ||
40 | - | ||
41 | - private final Logger log = getLogger(getClass()); | ||
42 | - | ||
43 | - private volatile DefaultTopology current; | ||
44 | - | ||
45 | - @Activate | ||
46 | - public void activate() { | ||
47 | - log.info("Started"); | ||
48 | - } | ||
49 | - | ||
50 | - @Deactivate | ||
51 | - public void deactivate() { | ||
52 | - log.info("Stopped"); | ||
53 | - } | ||
54 | - @Override | ||
55 | - public Topology currentTopology() { | ||
56 | - return current; | ||
57 | - } | ||
58 | - | ||
59 | - @Override | ||
60 | - public boolean isLatest(Topology topology) { | ||
61 | - // Topology is current only if it is the same as our current topology | ||
62 | - return topology == current; | ||
63 | - } | ||
64 | - | ||
65 | - @Override | ||
66 | - public TopologyGraph getGraph(Topology topology) { | ||
67 | - return defaultTopology(topology).getGraph(); | ||
68 | - } | ||
69 | - | ||
70 | - @Override | ||
71 | - public Set<TopologyCluster> getClusters(Topology topology) { | ||
72 | - return defaultTopology(topology).getClusters(); | ||
73 | - } | ||
74 | - | ||
75 | - @Override | ||
76 | - public TopologyCluster getCluster(Topology topology, ClusterId clusterId) { | ||
77 | - return defaultTopology(topology).getCluster(clusterId); | ||
78 | - } | ||
79 | - | ||
80 | - @Override | ||
81 | - public Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster) { | ||
82 | - return defaultTopology(topology).getClusterDevices(cluster); | ||
83 | - } | ||
84 | - | ||
85 | - @Override | ||
86 | - public Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster) { | ||
87 | - return defaultTopology(topology).getClusterLinks(cluster); | ||
88 | - } | ||
89 | - | ||
90 | - @Override | ||
91 | - public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) { | ||
92 | - return defaultTopology(topology).getPaths(src, dst); | ||
93 | - } | ||
94 | - | ||
95 | - @Override | ||
96 | - public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, | ||
97 | - LinkWeight weight) { | ||
98 | - return defaultTopology(topology).getPaths(src, dst, weight); | ||
99 | - } | ||
100 | - | ||
101 | - @Override | ||
102 | - public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { | ||
103 | - return defaultTopology(topology).isInfrastructure(connectPoint); | ||
104 | - } | ||
105 | - | ||
106 | - @Override | ||
107 | - public boolean isBroadcastPoint(Topology topology, ConnectPoint connectPoint) { | ||
108 | - return defaultTopology(topology).isBroadcastPoint(connectPoint); | ||
109 | - } | ||
110 | - | ||
111 | - @Override | ||
112 | - public TopologyEvent updateTopology(ProviderId providerId, | ||
113 | - GraphDescription graphDescription, | ||
114 | - List<Event> reasons) { | ||
115 | - // First off, make sure that what we're given is indeed newer than | ||
116 | - // what we already have. | ||
117 | - if (current != null && graphDescription.timestamp() < current.time()) { | ||
118 | - return null; | ||
119 | - } | ||
120 | - | ||
121 | - // Have the default topology construct self from the description data. | ||
122 | - DefaultTopology newTopology = | ||
123 | - new DefaultTopology(providerId, graphDescription); | ||
124 | - | ||
125 | - // Promote the new topology to current and return a ready-to-send event. | ||
126 | - synchronized (this) { | ||
127 | - current = newTopology; | ||
128 | - return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, | ||
129 | - current, reasons); | ||
130 | - } | ||
131 | - } | ||
132 | - | ||
133 | - // Validates the specified topology and returns it as a default | ||
134 | - private DefaultTopology defaultTopology(Topology topology) { | ||
135 | - if (topology instanceof DefaultTopology) { | ||
136 | - return (DefaultTopology) topology; | ||
137 | - } | ||
138 | - throw new IllegalArgumentException("Topology class " + topology.getClass() + | ||
139 | - " not supported"); | ||
140 | - } | ||
141 | - | ||
142 | -} |
1 | -package org.onlab.onos.store.topology.impl; | ||
2 | - | ||
3 | -import org.onlab.onos.net.DeviceId; | ||
4 | - | ||
5 | -import java.util.Objects; | ||
6 | - | ||
7 | -/** | ||
8 | - * Key for filing pre-computed paths between source and destination devices. | ||
9 | - */ | ||
10 | -class PathKey { | ||
11 | - private final DeviceId src; | ||
12 | - private final DeviceId dst; | ||
13 | - | ||
14 | - /** | ||
15 | - * Creates a path key from the given source/dest pair. | ||
16 | - * @param src source device | ||
17 | - * @param dst destination device | ||
18 | - */ | ||
19 | - PathKey(DeviceId src, DeviceId dst) { | ||
20 | - this.src = src; | ||
21 | - this.dst = dst; | ||
22 | - } | ||
23 | - | ||
24 | - @Override | ||
25 | - public int hashCode() { | ||
26 | - return Objects.hash(src, dst); | ||
27 | - } | ||
28 | - | ||
29 | - @Override | ||
30 | - public boolean equals(Object obj) { | ||
31 | - if (this == obj) { | ||
32 | - return true; | ||
33 | - } | ||
34 | - if (obj instanceof PathKey) { | ||
35 | - final PathKey other = (PathKey) obj; | ||
36 | - return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | ||
37 | - } | ||
38 | - return false; | ||
39 | - } | ||
40 | -} |
This diff is collapsed. Click to expand it.
core/store/hz/net/src/test/java/org/onlab/onos/store/link/impl/DistributedLinkStoreTest.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/HostLocationSerializer.java
0 → 100644
1 | +package org.onlab.onos.store.serializers; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | +import org.onlab.onos.net.HostLocation; | ||
5 | +import org.onlab.onos.net.PortNumber; | ||
6 | + | ||
7 | +import com.esotericsoftware.kryo.Kryo; | ||
8 | +import com.esotericsoftware.kryo.Serializer; | ||
9 | +import com.esotericsoftware.kryo.io.Input; | ||
10 | +import com.esotericsoftware.kryo.io.Output; | ||
11 | + | ||
12 | +/** | ||
13 | +* Kryo Serializer for {@link HostLocation}. | ||
14 | +*/ | ||
15 | +public class HostLocationSerializer extends Serializer<HostLocation> { | ||
16 | + | ||
17 | + /** | ||
18 | + * Creates {@link HostLocation} serializer instance. | ||
19 | + */ | ||
20 | + public HostLocationSerializer() { | ||
21 | + // non-null, immutable | ||
22 | + super(false, true); | ||
23 | + } | ||
24 | + | ||
25 | + @Override | ||
26 | + public void write(Kryo kryo, Output output, HostLocation object) { | ||
27 | + kryo.writeClassAndObject(output, object.deviceId()); | ||
28 | + kryo.writeClassAndObject(output, object.port()); | ||
29 | + output.writeLong(object.time()); | ||
30 | + } | ||
31 | + | ||
32 | + @Override | ||
33 | + public HostLocation read(Kryo kryo, Input input, Class<HostLocation> type) { | ||
34 | + DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); | ||
35 | + PortNumber portNumber = (PortNumber) kryo.readClassAndObject(input); | ||
36 | + long time = input.readLong(); | ||
37 | + return new HostLocation(deviceId, portNumber, time); | ||
38 | + } | ||
39 | + | ||
40 | +} |
... | @@ -20,8 +20,7 @@ public class IpAddressSerializer extends Serializer<IpAddress> { | ... | @@ -20,8 +20,7 @@ public class IpAddressSerializer extends Serializer<IpAddress> { |
20 | } | 20 | } |
21 | 21 | ||
22 | @Override | 22 | @Override |
23 | - public void write(Kryo kryo, Output output, | 23 | + public void write(Kryo kryo, Output output, IpAddress object) { |
24 | - IpAddress object) { | ||
25 | byte[] octs = object.toOctets(); | 24 | byte[] octs = object.toOctets(); |
26 | output.writeInt(octs.length); | 25 | output.writeInt(octs.length); |
27 | output.writeBytes(octs); | 26 | output.writeBytes(octs); |
... | @@ -29,11 +28,10 @@ public class IpAddressSerializer extends Serializer<IpAddress> { | ... | @@ -29,11 +28,10 @@ public class IpAddressSerializer extends Serializer<IpAddress> { |
29 | } | 28 | } |
30 | 29 | ||
31 | @Override | 30 | @Override |
32 | - public IpAddress read(Kryo kryo, Input input, | 31 | + public IpAddress read(Kryo kryo, Input input, Class<IpAddress> type) { |
33 | - Class<IpAddress> type) { | 32 | + final int octLen = input.readInt(); |
34 | - int octLen = input.readInt(); | ||
35 | byte[] octs = new byte[octLen]; | 33 | byte[] octs = new byte[octLen]; |
36 | - input.read(octs); | 34 | + input.readBytes(octs); |
37 | int prefLen = input.readInt(); | 35 | int prefLen = input.readInt(); |
38 | return IpAddress.valueOf(octs, prefLen); | 36 | return IpAddress.valueOf(octs, prefLen); |
39 | } | 37 | } | ... | ... |
... | @@ -34,7 +34,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { | ... | @@ -34,7 +34,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { |
34 | Class<IpPrefix> type) { | 34 | Class<IpPrefix> type) { |
35 | int octLen = input.readInt(); | 35 | int octLen = input.readInt(); |
36 | byte[] octs = new byte[octLen]; | 36 | byte[] octs = new byte[octLen]; |
37 | - input.read(octs); | 37 | + input.readBytes(octs); |
38 | int prefLen = input.readInt(); | 38 | int prefLen = input.readInt(); |
39 | return IpPrefix.valueOf(octs, prefLen); | 39 | return IpPrefix.valueOf(octs, prefLen); |
40 | } | 40 | } | ... | ... |
... | @@ -17,21 +17,28 @@ import org.onlab.onos.net.DefaultPort; | ... | @@ -17,21 +17,28 @@ import org.onlab.onos.net.DefaultPort; |
17 | import org.onlab.onos.net.Device; | 17 | import org.onlab.onos.net.Device; |
18 | import org.onlab.onos.net.DeviceId; | 18 | import org.onlab.onos.net.DeviceId; |
19 | import org.onlab.onos.net.Element; | 19 | import org.onlab.onos.net.Element; |
20 | +import org.onlab.onos.net.HostId; | ||
21 | +import org.onlab.onos.net.HostLocation; | ||
20 | import org.onlab.onos.net.Link; | 22 | import org.onlab.onos.net.Link; |
21 | import org.onlab.onos.net.LinkKey; | 23 | import org.onlab.onos.net.LinkKey; |
22 | import org.onlab.onos.net.Port; | 24 | import org.onlab.onos.net.Port; |
23 | import org.onlab.onos.net.PortNumber; | 25 | import org.onlab.onos.net.PortNumber; |
24 | import org.onlab.onos.net.device.DefaultDeviceDescription; | 26 | import org.onlab.onos.net.device.DefaultDeviceDescription; |
25 | import org.onlab.onos.net.device.DefaultPortDescription; | 27 | import org.onlab.onos.net.device.DefaultPortDescription; |
28 | +import org.onlab.onos.net.host.DefaultHostDescription; | ||
29 | +import org.onlab.onos.net.host.HostDescription; | ||
26 | import org.onlab.onos.net.link.DefaultLinkDescription; | 30 | import org.onlab.onos.net.link.DefaultLinkDescription; |
27 | import org.onlab.onos.net.provider.ProviderId; | 31 | import org.onlab.onos.net.provider.ProviderId; |
28 | import org.onlab.onos.store.Timestamp; | 32 | import org.onlab.onos.store.Timestamp; |
29 | import org.onlab.packet.IpAddress; | 33 | import org.onlab.packet.IpAddress; |
30 | import org.onlab.packet.IpPrefix; | 34 | import org.onlab.packet.IpPrefix; |
35 | +import org.onlab.packet.MacAddress; | ||
36 | +import org.onlab.packet.VlanId; | ||
31 | import org.onlab.util.KryoPool; | 37 | import org.onlab.util.KryoPool; |
32 | 38 | ||
33 | import com.google.common.collect.ImmutableList; | 39 | import com.google.common.collect.ImmutableList; |
34 | import com.google.common.collect.ImmutableMap; | 40 | import com.google.common.collect.ImmutableMap; |
41 | +import com.google.common.collect.ImmutableSet; | ||
35 | 42 | ||
36 | public final class KryoPoolUtil { | 43 | public final class KryoPoolUtil { |
37 | 44 | ||
... | @@ -41,6 +48,8 @@ public final class KryoPoolUtil { | ... | @@ -41,6 +48,8 @@ public final class KryoPoolUtil { |
41 | public static final KryoPool MISC = KryoPool.newBuilder() | 48 | public static final KryoPool MISC = KryoPool.newBuilder() |
42 | .register(IpPrefix.class, new IpPrefixSerializer()) | 49 | .register(IpPrefix.class, new IpPrefixSerializer()) |
43 | .register(IpAddress.class, new IpAddressSerializer()) | 50 | .register(IpAddress.class, new IpAddressSerializer()) |
51 | + .register(MacAddress.class, new MacAddressSerializer()) | ||
52 | + .register(VlanId.class) | ||
44 | .build(); | 53 | .build(); |
45 | 54 | ||
46 | // TODO: Populate other classes | 55 | // TODO: Populate other classes |
... | @@ -51,6 +60,7 @@ public final class KryoPoolUtil { | ... | @@ -51,6 +60,7 @@ public final class KryoPoolUtil { |
51 | .register(MISC) | 60 | .register(MISC) |
52 | .register(ImmutableMap.class, new ImmutableMapSerializer()) | 61 | .register(ImmutableMap.class, new ImmutableMapSerializer()) |
53 | .register(ImmutableList.class, new ImmutableListSerializer()) | 62 | .register(ImmutableList.class, new ImmutableListSerializer()) |
63 | + .register(ImmutableSet.class, new ImmutableSetSerializer()) | ||
54 | .register( | 64 | .register( |
55 | // | 65 | // |
56 | ArrayList.class, | 66 | ArrayList.class, |
... | @@ -69,8 +79,10 @@ public final class KryoPoolUtil { | ... | @@ -69,8 +79,10 @@ public final class KryoPoolUtil { |
69 | DefaultPortDescription.class, | 79 | DefaultPortDescription.class, |
70 | Element.class, | 80 | Element.class, |
71 | Link.Type.class, | 81 | Link.Type.class, |
72 | - Timestamp.class | 82 | + Timestamp.class, |
73 | - | 83 | + HostId.class, |
84 | + HostDescription.class, | ||
85 | + DefaultHostDescription.class | ||
74 | ) | 86 | ) |
75 | .register(URI.class, new URISerializer()) | 87 | .register(URI.class, new URISerializer()) |
76 | .register(NodeId.class, new NodeIdSerializer()) | 88 | .register(NodeId.class, new NodeIdSerializer()) |
... | @@ -82,6 +94,8 @@ public final class KryoPoolUtil { | ... | @@ -82,6 +94,8 @@ public final class KryoPoolUtil { |
82 | .register(ConnectPoint.class, new ConnectPointSerializer()) | 94 | .register(ConnectPoint.class, new ConnectPointSerializer()) |
83 | .register(DefaultLink.class, new DefaultLinkSerializer()) | 95 | .register(DefaultLink.class, new DefaultLinkSerializer()) |
84 | .register(MastershipTerm.class, new MastershipTermSerializer()) | 96 | .register(MastershipTerm.class, new MastershipTermSerializer()) |
97 | + .register(MastershipRole.class, new MastershipRoleSerializer()) | ||
98 | + .register(HostLocation.class, new HostLocationSerializer()) | ||
85 | 99 | ||
86 | .build(); | 100 | .build(); |
87 | 101 | ... | ... |
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/MacAddressSerializer.java
0 → 100644
1 | +package org.onlab.onos.store.serializers; | ||
2 | + | ||
3 | +import org.onlab.packet.MacAddress; | ||
4 | + | ||
5 | +import com.esotericsoftware.kryo.Kryo; | ||
6 | +import com.esotericsoftware.kryo.Serializer; | ||
7 | +import com.esotericsoftware.kryo.io.Input; | ||
8 | +import com.esotericsoftware.kryo.io.Output; | ||
9 | + | ||
10 | +/** | ||
11 | + * Kryo Serializer for {@link MacAddress}. | ||
12 | + */ | ||
13 | +public class MacAddressSerializer extends Serializer<MacAddress> { | ||
14 | + | ||
15 | + /** | ||
16 | + * Creates {@link MacAddress} serializer instance. | ||
17 | + */ | ||
18 | + public MacAddressSerializer() { | ||
19 | + super(false, true); | ||
20 | + } | ||
21 | + | ||
22 | + @Override | ||
23 | + public void write(Kryo kryo, Output output, MacAddress object) { | ||
24 | + output.writeBytes(object.getAddress()); | ||
25 | + } | ||
26 | + | ||
27 | + @Override | ||
28 | + public MacAddress read(Kryo kryo, Input input, Class<MacAddress> type) { | ||
29 | + return MacAddress.valueOf(input.readBytes(MacAddress.MAC_ADDRESS_LENGTH)); | ||
30 | + } | ||
31 | + | ||
32 | +} |
... | @@ -84,7 +84,7 @@ public class SimpleHostStore | ... | @@ -84,7 +84,7 @@ public class SimpleHostStore |
84 | descr.hwAddress(), | 84 | descr.hwAddress(), |
85 | descr.vlan(), | 85 | descr.vlan(), |
86 | descr.location(), | 86 | descr.location(), |
87 | - ImmutableSet.of(descr.ipAddress())); | 87 | + ImmutableSet.copyOf(descr.ipAddress())); |
88 | synchronized (this) { | 88 | synchronized (this) { |
89 | hosts.put(hostId, newhost); | 89 | hosts.put(hostId, newhost); |
90 | locations.put(descr.location(), newhost); | 90 | locations.put(descr.location(), newhost); |
... | @@ -101,12 +101,12 @@ public class SimpleHostStore | ... | @@ -101,12 +101,12 @@ public class SimpleHostStore |
101 | return new HostEvent(HOST_MOVED, host); | 101 | return new HostEvent(HOST_MOVED, host); |
102 | } | 102 | } |
103 | 103 | ||
104 | - if (host.ipAddresses().contains(descr.ipAddress())) { | 104 | + if (host.ipAddresses().containsAll(descr.ipAddress())) { |
105 | return null; | 105 | return null; |
106 | } | 106 | } |
107 | 107 | ||
108 | Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses()); | 108 | Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses()); |
109 | - addresses.add(descr.ipAddress()); | 109 | + addresses.addAll(descr.ipAddress()); |
110 | StoredHost updated = new StoredHost(providerId, host.id(), | 110 | StoredHost updated = new StoredHost(providerId, host.id(), |
111 | host.mac(), host.vlan(), | 111 | host.mac(), host.vlan(), |
112 | descr.location(), addresses); | 112 | descr.location(), addresses); | ... | ... |
... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
30 | 30 | ||
31 | <bundle>mvn:org.codehaus.jackson/jackson-core-asl/1.9.13</bundle> | 31 | <bundle>mvn:org.codehaus.jackson/jackson-core-asl/1.9.13</bundle> |
32 | <bundle>mvn:org.codehaus.jackson/jackson-mapper-asl/1.9.13</bundle> | 32 | <bundle>mvn:org.codehaus.jackson/jackson-mapper-asl/1.9.13</bundle> |
33 | + <bundle>mvn:org.onlab.onos/onlab-thirdparty/1.0.0-SNAPSHOT</bundle> | ||
33 | </feature> | 34 | </feature> |
34 | 35 | ||
35 | <feature name="onos-thirdparty-web" version="1.0.0" | 36 | <feature name="onos-thirdparty-web" version="1.0.0" | ... | ... |
... | @@ -107,6 +107,12 @@ | ... | @@ -107,6 +107,12 @@ |
107 | </dependency> | 107 | </dependency> |
108 | 108 | ||
109 | <dependency> | 109 | <dependency> |
110 | + <groupId>com.googlecode.concurrent-trees</groupId> | ||
111 | + <artifactId>concurrent-trees</artifactId> | ||
112 | + <version>2.4.0</version> | ||
113 | + </dependency> | ||
114 | + | ||
115 | + <dependency> | ||
110 | <groupId>commons-lang</groupId> | 116 | <groupId>commons-lang</groupId> |
111 | <artifactId>commons-lang</artifactId> | 117 | <artifactId>commons-lang</artifactId> |
112 | <version>2.6</version> | 118 | <version>2.6</version> |
... | @@ -164,6 +170,12 @@ | ... | @@ -164,6 +170,12 @@ |
164 | <scope>provided</scope> | 170 | <scope>provided</scope> |
165 | </dependency> | 171 | </dependency> |
166 | <dependency> | 172 | <dependency> |
173 | + <groupId>org.osgi</groupId> | ||
174 | + <artifactId>org.osgi.compendium</artifactId> | ||
175 | + <version>4.3.1</version> | ||
176 | + <scope>provided</scope> | ||
177 | + </dependency> | ||
178 | + <dependency> | ||
167 | <groupId>org.apache.felix</groupId> | 179 | <groupId>org.apache.felix</groupId> |
168 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 180 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
169 | <version>1.9.8</version> | 181 | <version>1.9.8</version> |
... | @@ -260,6 +272,13 @@ | ... | @@ -260,6 +272,13 @@ |
260 | <artifactId>onos-of-api</artifactId> | 272 | <artifactId>onos-of-api</artifactId> |
261 | <version>${project.version}</version> | 273 | <version>${project.version}</version> |
262 | </dependency> | 274 | </dependency> |
275 | + | ||
276 | + <dependency> | ||
277 | + <groupId>org.onlab.onos</groupId> | ||
278 | + <artifactId>onlab-thirdparty</artifactId> | ||
279 | + <version>${project.version}</version> | ||
280 | + </dependency> | ||
281 | + | ||
263 | <dependency> | 282 | <dependency> |
264 | <groupId>org.onlab.onos</groupId> | 283 | <groupId>org.onlab.onos</groupId> |
265 | <artifactId>onos-of-api</artifactId> | 284 | <artifactId>onos-of-api</artifactId> | ... | ... |
... | @@ -161,10 +161,10 @@ public class FlowModBuilder { | ... | @@ -161,10 +161,10 @@ public class FlowModBuilder { |
161 | switch (l3m.subtype()) { | 161 | switch (l3m.subtype()) { |
162 | case IP_DST: | 162 | case IP_DST: |
163 | ip = (ModIPInstruction) i; | 163 | ip = (ModIPInstruction) i; |
164 | - return factory.actions().setNwDst(IPv4Address.of(ip.ip().toRealInt())); | 164 | + return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt())); |
165 | case IP_SRC: | 165 | case IP_SRC: |
166 | ip = (ModIPInstruction) i; | 166 | ip = (ModIPInstruction) i; |
167 | - return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toRealInt())); | 167 | + return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt())); |
168 | default: | 168 | default: |
169 | log.warn("Unimplemented action type {}.", l3m.subtype()); | 169 | log.warn("Unimplemented action type {}.", l3m.subtype()); |
170 | break; | 170 | break; |
... | @@ -220,21 +220,21 @@ public class FlowModBuilder { | ... | @@ -220,21 +220,21 @@ public class FlowModBuilder { |
220 | case IPV4_DST: | 220 | case IPV4_DST: |
221 | ip = (IPCriterion) c; | 221 | ip = (IPCriterion) c; |
222 | if (ip.ip().isMasked()) { | 222 | if (ip.ip().isMasked()) { |
223 | - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()), | 223 | + Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), |
224 | - IPv4Address.of(ip.ip().netmask().toRealInt())); | 224 | + IPv4Address.of(ip.ip().netmask().toInt())); |
225 | mBuilder.setMasked(MatchField.IPV4_DST, maskedIp); | 225 | mBuilder.setMasked(MatchField.IPV4_DST, maskedIp); |
226 | } else { | 226 | } else { |
227 | - mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toRealInt())); | 227 | + mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt())); |
228 | } | 228 | } |
229 | break; | 229 | break; |
230 | case IPV4_SRC: | 230 | case IPV4_SRC: |
231 | ip = (IPCriterion) c; | 231 | ip = (IPCriterion) c; |
232 | if (ip.ip().isMasked()) { | 232 | if (ip.ip().isMasked()) { |
233 | - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()), | 233 | + Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), |
234 | - IPv4Address.of(ip.ip().netmask().toRealInt())); | 234 | + IPv4Address.of(ip.ip().netmask().toInt())); |
235 | mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp); | 235 | mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp); |
236 | } else { | 236 | } else { |
237 | - mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toRealInt())); | 237 | + mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt())); |
238 | } | 238 | } |
239 | break; | 239 | break; |
240 | case IP_PROTO: | 240 | case IP_PROTO: | ... | ... |
... | @@ -339,9 +339,14 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -339,9 +339,14 @@ public class LinkDiscovery implements TimerTask { |
339 | final Iterator<Integer> fastIterator = this.fastPorts.iterator(); | 339 | final Iterator<Integer> fastIterator = this.fastPorts.iterator(); |
340 | while (fastIterator.hasNext()) { | 340 | while (fastIterator.hasNext()) { |
341 | final Integer portNumber = fastIterator.next(); | 341 | final Integer portNumber = fastIterator.next(); |
342 | + OFPortDesc port = findPort(portNumber); | ||
343 | + if (port == null) { | ||
344 | + // port can be null | ||
345 | + // #removePort modifies `ports` outside synchronized block | ||
346 | + continue; | ||
347 | + } | ||
342 | final int probeCount = this.portProbeCount.get(portNumber) | 348 | final int probeCount = this.portProbeCount.get(portNumber) |
343 | .getAndIncrement(); | 349 | .getAndIncrement(); |
344 | - OFPortDesc port = findPort(portNumber); | ||
345 | if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) { | 350 | if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) { |
346 | this.log.debug("sending fast probe to port"); | 351 | this.log.debug("sending fast probe to port"); |
347 | 352 | ... | ... |
... | @@ -25,6 +25,9 @@ export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS | ... | @@ -25,6 +25,9 @@ export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS |
25 | export ONOS_TAR=$ONOS_STAGE.tar.gz | 25 | export ONOS_TAR=$ONOS_STAGE.tar.gz |
26 | 26 | ||
27 | # Defaults for ONOS testing using remote machines. | 27 | # Defaults for ONOS testing using remote machines. |
28 | +if [ -n "${ONOS_CELL}" -a -f $ONOS_ROOT/tools/test/cells/${ONOS_CELL} ]; then | ||
29 | + . $ONOS_ROOT/tools/test/cells/${ONOS_CELL} | ||
30 | +fi | ||
28 | export ONOS_INSTALL_DIR="/opt/onos" # Installation directory on remote | 31 | export ONOS_INSTALL_DIR="/opt/onos" # Installation directory on remote |
29 | export OCI="${OCI:-192.168.56.101}" # ONOS Controller Instance | 32 | export OCI="${OCI:-192.168.56.101}" # ONOS Controller Instance |
30 | export ONOS_USER="sdn" # ONOS user on remote system | 33 | export ONOS_USER="sdn" # ONOS user on remote system | ... | ... |
... | @@ -6,7 +6,13 @@ | ... | @@ -6,7 +6,13 @@ |
6 | export ONOS_ROOT=${ONOS_ROOT:-~/onos-next} | 6 | export ONOS_ROOT=${ONOS_ROOT:-~/onos-next} |
7 | 7 | ||
8 | # Setup some environmental context for developers | 8 | # Setup some environmental context for developers |
9 | -export JAVA_HOME=${JAVA_HOME:-$(/usr/libexec/java_home -v 1.7)} | 9 | +if [ -z "${JAVA_HOME}" ]; then |
10 | + if [ -x /usr/libexec/java_home ]; then | ||
11 | + export JAVA_HOME=$(/usr/libexec/java_home -v 1.7) | ||
12 | + elif [ -d /usr/lib/jvm/java-7-openjdk-amd64 ]; then | ||
13 | + export JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64" | ||
14 | + fi | ||
15 | +fi | ||
10 | export MAVEN=${MAVEN:-~/Applications/apache-maven-3.2.2} | 16 | export MAVEN=${MAVEN:-~/Applications/apache-maven-3.2.2} |
11 | export KARAF=${KARAF:-~/Applications/apache-karaf-3.0.1} | 17 | export KARAF=${KARAF:-~/Applications/apache-karaf-3.0.1} |
12 | export KARAF_LOG=$KARAF/data/log/karaf.log | 18 | export KARAF_LOG=$KARAF/data/log/karaf.log |
... | @@ -15,7 +21,6 @@ export KARAF_LOG=$KARAF/data/log/karaf.log | ... | @@ -15,7 +21,6 @@ export KARAF_LOG=$KARAF/data/log/karaf.log |
15 | export PATH="$PATH:$ONOS_ROOT/tools/dev/bin:$ONOS_ROOT/tools/test/bin" | 21 | export PATH="$PATH:$ONOS_ROOT/tools/dev/bin:$ONOS_ROOT/tools/test/bin" |
16 | export PATH="$PATH:$ONOS_ROOT/tools/build" | 22 | export PATH="$PATH:$ONOS_ROOT/tools/build" |
17 | export PATH="$PATH:$MAVEN/bin:$KARAF/bin" | 23 | export PATH="$PATH:$MAVEN/bin:$KARAF/bin" |
18 | -export PATH="$PATH:." | ||
19 | 24 | ||
20 | # Convenience utility to warp to various ONOS source projects | 25 | # Convenience utility to warp to various ONOS source projects |
21 | # e.g. 'o api', 'o dev', 'o' | 26 | # e.g. 'o api', 'o dev', 'o' | ... | ... |
... | @@ -2,13 +2,15 @@ package org.onlab.packet; | ... | @@ -2,13 +2,15 @@ package org.onlab.packet; |
2 | 2 | ||
3 | import java.util.Arrays; | 3 | import java.util.Arrays; |
4 | 4 | ||
5 | + | ||
6 | + | ||
5 | /** | 7 | /** |
6 | * A class representing an IPv4 address. | 8 | * A class representing an IPv4 address. |
7 | * <p/> | 9 | * <p/> |
8 | * TODO this class is a clone of IpPrefix and still needs to be modified to | 10 | * TODO this class is a clone of IpPrefix and still needs to be modified to |
9 | * look more like an IpAddress. | 11 | * look more like an IpAddress. |
10 | */ | 12 | */ |
11 | -public final class IpAddress { | 13 | +public final class IpAddress implements Comparable<IpAddress> { |
12 | 14 | ||
13 | // TODO a comparator for netmasks? E.g. for sorting by prefix match order. | 15 | // TODO a comparator for netmasks? E.g. for sorting by prefix match order. |
14 | 16 | ||
... | @@ -121,7 +123,7 @@ public final class IpAddress { | ... | @@ -121,7 +123,7 @@ public final class IpAddress { |
121 | 123 | ||
122 | int mask = DEFAULT_MASK; | 124 | int mask = DEFAULT_MASK; |
123 | if (parts.length == 2) { | 125 | if (parts.length == 2) { |
124 | - mask = Integer.valueOf(parts[1]); | 126 | + mask = Integer.parseInt(parts[1]); |
125 | if (mask > MAX_INET_MASK) { | 127 | if (mask > MAX_INET_MASK) { |
126 | throw new IllegalArgumentException( | 128 | throw new IllegalArgumentException( |
127 | "Value of subnet mask cannot exceed " | 129 | "Value of subnet mask cannot exceed " |
... | @@ -174,14 +176,6 @@ public final class IpAddress { | ... | @@ -174,14 +176,6 @@ public final class IpAddress { |
174 | * @return the IP address's value as an integer | 176 | * @return the IP address's value as an integer |
175 | */ | 177 | */ |
176 | public int toInt() { | 178 | public int toInt() { |
177 | - int address = 0; | ||
178 | - for (int i = 0; i < INET_LEN; i++) { | ||
179 | - address |= octets[i] << ((INET_LEN - (i + 1)) * 8); | ||
180 | - } | ||
181 | - return address; | ||
182 | - } | ||
183 | - | ||
184 | - public int toRealInt() { | ||
185 | int val = 0; | 179 | int val = 0; |
186 | for (int i = 0; i < octets.length; i++) { | 180 | for (int i = 0; i < octets.length; i++) { |
187 | val <<= 8; | 181 | val <<= 8; |
... | @@ -191,6 +185,15 @@ public final class IpAddress { | ... | @@ -191,6 +185,15 @@ public final class IpAddress { |
191 | } | 185 | } |
192 | 186 | ||
193 | /** | 187 | /** |
188 | + * Converts the IP address to a /32 IP prefix. | ||
189 | + * | ||
190 | + * @return the new IP prefix | ||
191 | + */ | ||
192 | + public IpPrefix toPrefix() { | ||
193 | + return IpPrefix.valueOf(octets, MAX_INET_MASK); | ||
194 | + } | ||
195 | + | ||
196 | + /** | ||
194 | * Helper for computing the mask value from CIDR. | 197 | * Helper for computing the mask value from CIDR. |
195 | * | 198 | * |
196 | * @return an integer bitmask | 199 | * @return an integer bitmask |
... | @@ -280,6 +283,13 @@ public final class IpAddress { | ... | @@ -280,6 +283,13 @@ public final class IpAddress { |
280 | } | 283 | } |
281 | 284 | ||
282 | @Override | 285 | @Override |
286 | + public int compareTo(IpAddress o) { | ||
287 | + Long lv = ((long) this.toInt()) & 0xffffffffL; | ||
288 | + Long rv = ((long) o.toInt()) & 0xffffffffL; | ||
289 | + return lv.compareTo(rv); | ||
290 | + } | ||
291 | + | ||
292 | + @Override | ||
283 | public int hashCode() { | 293 | public int hashCode() { |
284 | final int prime = 31; | 294 | final int prime = 31; |
285 | int result = 1; | 295 | int result = 1; | ... | ... |
... | @@ -120,7 +120,7 @@ public final class IpPrefix { | ... | @@ -120,7 +120,7 @@ public final class IpPrefix { |
120 | 120 | ||
121 | int mask = DEFAULT_MASK; | 121 | int mask = DEFAULT_MASK; |
122 | if (parts.length == 2) { | 122 | if (parts.length == 2) { |
123 | - mask = Integer.valueOf(parts[1]); | 123 | + mask = Integer.parseInt(parts[1]); |
124 | if (mask > MAX_INET_MASK) { | 124 | if (mask > MAX_INET_MASK) { |
125 | throw new IllegalArgumentException( | 125 | throw new IllegalArgumentException( |
126 | "Value of subnet mask cannot exceed " | 126 | "Value of subnet mask cannot exceed " |
... | @@ -173,14 +173,6 @@ public final class IpPrefix { | ... | @@ -173,14 +173,6 @@ public final class IpPrefix { |
173 | * @return the IP address's value as an integer | 173 | * @return the IP address's value as an integer |
174 | */ | 174 | */ |
175 | public int toInt() { | 175 | public int toInt() { |
176 | - int address = 0; | ||
177 | - for (int i = 0; i < INET_LEN; i++) { | ||
178 | - address |= octets[i] << ((INET_LEN - (i + 1)) * 8); | ||
179 | - } | ||
180 | - return address; | ||
181 | - } | ||
182 | - | ||
183 | - public int toRealInt() { | ||
184 | int val = 0; | 176 | int val = 0; |
185 | for (int i = 0; i < octets.length; i++) { | 177 | for (int i = 0; i < octets.length; i++) { |
186 | val <<= 8; | 178 | val <<= 8; | ... | ... |
utils/thirdparty/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <groupId>org.onlab.onos</groupId> | ||
9 | + <artifactId>onlab-utils</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onlab-thirdparty</artifactId> | ||
15 | + <packaging>bundle</packaging> | ||
16 | + | ||
17 | + <description>ONLab third-party dependencies</description> | ||
18 | + | ||
19 | + <dependencies> | ||
20 | + <dependency> | ||
21 | + <groupId>com.googlecode.concurrent-trees</groupId> | ||
22 | + <artifactId>concurrent-trees</artifactId> | ||
23 | + <version>2.4.0</version> | ||
24 | + </dependency> | ||
25 | + </dependencies> | ||
26 | + | ||
27 | + <build> | ||
28 | + <plugins> | ||
29 | + <plugin> | ||
30 | + <groupId>org.apache.maven.plugins</groupId> | ||
31 | + <artifactId>maven-shade-plugin</artifactId> | ||
32 | + <version>2.3</version> | ||
33 | + <configuration> | ||
34 | + <filters> | ||
35 | + <filter> | ||
36 | + <artifact>com.googlecode.concurrent-trees:concurrent-trees</artifact> | ||
37 | + <includes> | ||
38 | + <include>com/googlecode/**</include> | ||
39 | + </includes> | ||
40 | + | ||
41 | + </filter> | ||
42 | + <filter> | ||
43 | + <artifact>com.google.guava:guava</artifact> | ||
44 | + <excludes> | ||
45 | + <exclude>**</exclude> | ||
46 | + </excludes> | ||
47 | + </filter> | ||
48 | + </filters> | ||
49 | + </configuration> | ||
50 | + <executions> | ||
51 | + <execution> | ||
52 | + <phase>package</phase> | ||
53 | + <goals> | ||
54 | + <goal>shade</goal> | ||
55 | + </goals> | ||
56 | + </execution> | ||
57 | + </executions> | ||
58 | + </plugin> | ||
59 | + <plugin> | ||
60 | + <groupId>org.apache.felix</groupId> | ||
61 | + <artifactId>maven-bundle-plugin</artifactId> | ||
62 | + <configuration> | ||
63 | + <instructions> | ||
64 | + <Export-Package> | ||
65 | + com.googlecode.concurrenttrees.* | ||
66 | + </Export-Package> | ||
67 | + </instructions> | ||
68 | + </configuration> | ||
69 | + </plugin> | ||
70 | + </plugins> | ||
71 | + </build> | ||
72 | + | ||
73 | +</project> |
-
Please register or login to post a comment