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