summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/utils')
-rw-r--r--framework/src/onos/utils/catalyst/pom.xml62
-rw-r--r--framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/OnlabCatalyst.java7
-rw-r--r--framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/package-info.java4
-rwxr-xr-xframework/src/onos/utils/jdvue/bin/jdvue31
-rwxr-xr-xframework/src/onos/utils/jdvue/bin/jdvue-scan12
-rw-r--r--framework/src/onos/utils/jdvue/pom.xml108
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java406
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java82
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java133
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java203
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java59
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java94
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java115
-rw-r--r--framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/package-info.java20
-rw-r--r--framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/d3.v3.min.js5
-rw-r--r--framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/index.html371
-rw-r--r--framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java58
-rw-r--r--framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java62
-rw-r--r--framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java44
-rw-r--r--framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java46
-rw-r--r--framework/src/onos/utils/jdvue/src/test/resources/catalog.db33
-rw-r--r--framework/src/onos/utils/jdvue/src/test/resources/catalog.html376
-rw-r--r--framework/src/onos/utils/jdvue/src/test/resources/expected.html376
-rw-r--r--framework/src/onos/utils/jnc/pom.xml102
-rw-r--r--framework/src/onos/utils/junit/pom.xml57
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ExceptionTest.java55
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ImmutableClassChecker.java168
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/IntegrationTest.java25
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/NullScheduledExecutor.java135
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestTools.java227
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestUtils.java207
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java149
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/package-info.java20
-rw-r--r--framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jksbin1295 -> 0 bytes
-rw-r--r--framework/src/onos/utils/junit/src/test/java/org/onlab/junit/ImmutableClassCheckerTest.java135
-rw-r--r--framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestToolsTest.java47
-rw-r--r--framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java185
-rw-r--r--framework/src/onos/utils/junit/src/test/java/org/onlab/junit/UtilityClassCheckerTest.java160
-rw-r--r--framework/src/onos/utils/misc/pom.xml87
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java76
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractGraphPathSearch.java316
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java122
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BellmanFordGraphSearch.java60
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BreadthFirstSearch.java79
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java136
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java103
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DepthFirstSearch.java183
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DijkstraGraphSearch.java97
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java137
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Edge.java39
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/EdgeWeight.java31
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java53
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java90
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Graph.java59
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphPathSearch.java87
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphSearch.java43
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Heap.java211
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java286
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java160
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableGraph.java59
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutablePath.java62
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Path.java45
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SrlgGraphSearch.java253
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java193
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/TarjanGraphSearch.java212
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Vertex.java22
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/graph/package-info.java20
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/EventMetric.java118
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponent.java60
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponentRegistry.java36
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsFeature.java41
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsManager.java304
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsService.java178
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsUtil.java56
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/package-info.java20
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ARP.java439
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/BasePacket.java127
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ChassisId.java86
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java632
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPOption.java136
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPPacketType.java116
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Data.java132
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DeserializationException.java32
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Deserializer.java36
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAP.java264
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java199
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EthType.java159
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ethernet.java718
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP.java223
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP6.java366
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMP.java335
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPGroup.java98
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPMembership.java158
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPQuery.java202
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPacket.java89
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java733
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv6.java384
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Address.java174
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Prefix.java104
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java152
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Prefix.java93
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java559
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpPrefix.java303
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLC.java102
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java300
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPOrganizationalTLV.java225
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPTLV.java165
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java162
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MacAddress.java218
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java74
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java185
-rwxr-xr-xframework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java299
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PacketUtils.java84
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUS.java423
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUSAttribute.java142
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TCP.java462
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TpPort.java104
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/UDP.java306
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/VlanId.java102
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java300
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java260
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/DestinationOptions.java29
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java188
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java253
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/HopByHopOptions.java29
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/IExtensionHeader.java37
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java291
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/package-info.java20
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java278
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java281
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java192
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java225
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java325
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java155
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/package-info.java21
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/package-info.java21
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java259
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java282
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java185
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java118
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java147
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java271
-rwxr-xr-xframework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java21
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java214
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Accumulator.java49
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Bandwidth.java149
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/BlockingBoolean.java97
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/BoundedThreadPool.java176
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/ByteArraySizeHashPrinter.java69
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Counter.java139
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/DataRateUnit.java64
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/DefaultHashMap.java42
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Frequency.java181
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/GeoLocation.java85
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/GroupedThreadFactory.java88
-rwxr-xr-xframework/src/onos/utils/misc/src/main/java/org/onlab/util/HexDump.java57
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexString.java148
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/ItemNotFoundException.java46
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java437
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/NewConcurrentHashMap.java47
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/PositionalParameterStringFormatter.java48
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/RetryingFunction.java60
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/RichComparable.java45
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutorService.java138
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutors.java123
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java129
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Spectrum.java55
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Timer.java52
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/Tools.java577
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/TriConsumer.java35
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/util/package-info.java20
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractEdgeTest.java37
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractGraphPathSearchTest.java61
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AdjacencyListsGraphTest.java72
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BellmanFordGraphSearchTest.java77
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BreadthFirstSearchTest.java100
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultMutablePathTest.java110
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultPathTest.java57
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DepthFirstSearchTest.java97
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DijkstraGraphSearchTest.java165
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DisjointPathPairTest.java43
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/GraphTest.java66
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/HeapTest.java97
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java197
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SrlgGraphSearchTest.java174
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java154
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TarjanGraphSearchTest.java125
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestEdge.java73
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestVertex.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ArpTest.java88
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java137
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/EthernetTest.java103
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMP6Test.java110
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMPTest.java70
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IGMPTest.java96
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv4Test.java99
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv6Test.java154
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4AddressTest.java432
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4PrefixTest.java534
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6AddressTest.java499
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6PrefixTest.java568
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpAddressTest.java946
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java1080
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLCTest.java70
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLDPTest.java115
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/MplsTest.java74
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java132
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PacketTestUtils.java98
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/TCPTest.java163
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/UDPTest.java134
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/VlanIdTest.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/AuthenticationTest.java121
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/BaseOptionsTest.java115
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/DestinationOptionsTest.java37
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/EncapSecurityPayloadTest.java104
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/FragmentTest.java113
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/HopByHopOptionsTest.java37
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/RoutingTest.java128
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborAdvertisementTest.java140
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java134
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RedirectTest.java147
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterAdvertisementTest.java140
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterSolicitationTest.java114
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java181
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java82
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java210
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java227
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java86
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/DefaultHashMapTest.java81
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java107
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/GeoLocationTest.java38
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java53
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java87
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimer.java522
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java263
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java61
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java94
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java54
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java105
-rw-r--r--framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java76
-rw-r--r--framework/src/onos/utils/netty/pom.xml83
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/DecoderState.java31
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/InternalMessage.java66
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageDecoder.java115
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageEncoder.java98
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/NettyMessaging.java454
-rw-r--r--framework/src/onos/utils/netty/src/main/java/org/onlab/netty/package-info.java20
-rw-r--r--framework/src/onos/utils/nio/pom.xml58
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AbstractMessage.java30
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AcceptorLoop.java123
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/IOLoop.java302
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/Message.java30
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/MessageStream.java424
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/SelectorLoop.java175
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/package-info.java21
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultIOLoop.java66
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessage.java104
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessageStream.java139
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/IOLoopMessaging.java334
-rw-r--r--framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/package-info.java20
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AbstractLoopTest.java60
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AcceptorLoopTest.java87
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopIntegrationTest.java82
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java324
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java256
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MessageStreamTest.java359
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MockSelector.java85
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessage.java56
-rw-r--r--framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessageStream.java89
-rw-r--r--framework/src/onos/utils/osgi/pom.xml46
-rw-r--r--framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/DefaultServiceDirectory.java53
-rw-r--r--framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceDirectory.java34
-rw-r--r--framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceNotFoundException.java46
-rw-r--r--framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/package-info.java20
-rw-r--r--framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/ComponentContextAdapter.java118
-rw-r--r--framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/TestServiceDirectory.java46
-rw-r--r--framework/src/onos/utils/pom.xml69
-rw-r--r--framework/src/onos/utils/rest/pom.xml53
-rw-r--r--framework/src/onos/utils/rest/src/main/java/org/onlab/rest/BaseResource.java57
-rw-r--r--framework/src/onos/utils/rest/src/main/java/org/onlab/rest/package-info.java20
-rwxr-xr-xframework/src/onos/utils/stc/bin/stc12
-rwxr-xr-xframework/src/onos/utils/stc/bin/stc-launcher19
-rw-r--r--framework/src/onos/utils/stc/pom.xml122
-rw-r--r--framework/src/onos/utils/stc/sample/scenario.xml20
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Compiler.java541
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java387
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Dependency.java77
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Group.java60
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java387
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Monitor.java154
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java31
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java307
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java149
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java137
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java37
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Scenario.java106
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java226
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Step.java129
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepEvent.java116
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java50
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java141
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/package-info.java20
-rw-r--r--framework/src/onos/utils/stc/src/main/resources/data.json1087
-rw-r--r--framework/src/onos/utils/stc/src/main/resources/index.html29
-rw-r--r--framework/src/onos/utils/stc/src/main/resources/stc.css37
-rw-r--r--framework/src/onos/utils/stc/src/main/resources/stc.js148
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java86
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java83
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java68
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/GroupTest.java54
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java146
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java44
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java84
-rw-r--r--framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepTest.java62
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml27
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml25
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml41
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml30
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml20
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/scenario.xml54
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml26
-rw-r--r--framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml21
-rw-r--r--framework/src/onos/utils/thirdparty/pom.xml115
-rw-r--r--framework/src/onos/utils/thirdparty/src/main/java/org/onlab/thirdparty/OnlabThirdparty.java26
325 files changed, 0 insertions, 47890 deletions
diff --git a/framework/src/onos/utils/catalyst/pom.xml b/framework/src/onos/utils/catalyst/pom.xml
deleted file mode 100644
index 8a504bbd..00000000
--- a/framework/src/onos/utils/catalyst/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>onlab-utils</artifactId>
- <groupId>org.onosproject</groupId>
- <version>1.4.0-rc1</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>utils.catalyst</artifactId>
- <packaging>bundle</packaging>
-
- <description>ONLab catalyst dependency</description>
-
- <dependencies>
- <dependency>
- <groupId>io.atomix.catalyst</groupId>
- <artifactId>catalyst-netty</artifactId>
- <version>1.0.0-rc5</version>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <configuration>
- <artifactSet>
- <includes>
- <include>io/atomix/catalyst/**</include>
- </includes>
- </artifactSet>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- io.atomix.catalyst.*
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
-
- </plugins>
- </build>
-</project> \ No newline at end of file
diff --git a/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/OnlabCatalyst.java b/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/OnlabCatalyst.java
deleted file mode 100644
index c3ecc860..00000000
--- a/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/OnlabCatalyst.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.onlab.catalyst;
-
-/**
- * Created by admin on 11/24/15.
- */
-public class OnlabCatalyst {
-}
diff --git a/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/package-info.java b/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/package-info.java
deleted file mode 100644
index 1fdb9ea2..00000000
--- a/framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Created by admin on 11/24/15.
- */
-package org.onlab.catalyst; \ No newline at end of file
diff --git a/framework/src/onos/utils/jdvue/bin/jdvue b/framework/src/onos/utils/jdvue/bin/jdvue
deleted file mode 100755
index db9d164b..00000000
--- a/framework/src/onos/utils/jdvue/bin/jdvue
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-# Java Package Dependency viewer
-#
-# written by Thomas Vachuska
-# -- Doobs --
-#-------------------------------------------------------------------------------
-
-JDVUE_ROOT=${JDVUE_ROOT:-$(dirname $0)/..}
-cd $JDVUE_ROOT
-VER=1.4.0-rc1
-JAR=$PWD/target/jdvue-${VER}.jar # start with the dev jar first
-cd - >/dev/null
-
-# If the dev jar is not available, use one from .m2/repository
-[ -f ${JAR} ] || JAR=~/.m2/repository/org/onlab/tools/jdvue/${VER}/jdvue-${VER}.jar
-
-# Assume default project to be the base-name of the argument or of current dir
-name=$(basename ${1:-$PWD})
-
-# If the -n option is specified use the next argument as the catalog name
-[ "$1" = "-n" -a $# -ge 2 ] && name=$2 && shift 2
-
-# Use the rest of the arguments as paths to scan for sources to build catalog
-find "${@:-.}" -type f -name \*.java \
- | grep -v -E '/lost+found/|/target/|archetype-resources' \
- | xargs grep -E "^[ \t]*import .*;.*|^[ \t]*package .*;.*" \
- | tr -d '\r' > $name.db
-
-# Now run the Java Dependency Viewer jar on the catalog
-java -jar ${JAR} $name && rm $name.db && open $name.html
diff --git a/framework/src/onos/utils/jdvue/bin/jdvue-scan b/framework/src/onos/utils/jdvue/bin/jdvue-scan
deleted file mode 100755
index 216c68d7..00000000
--- a/framework/src/onos/utils/jdvue/bin/jdvue-scan
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-# Java Package Dependency scanner
-#
-# written by Thomas Vachuska
-# -- Doobs --
-#-------------------------------------------------------------------------------
-
-find "${@:-.}" -type f -name \*.java \
- | grep -v -E '/lost+found/|/target/' \
- | xargs grep -E "^[ \t]*import .*;.*|^[ \t]*package .*;.*" \
- | tr -d '\r' > jpd.db
diff --git a/framework/src/onos/utils/jdvue/pom.xml b/framework/src/onos/utils/jdvue/pom.xml
deleted file mode 100644
index 777eba3d..00000000
--- a/framework/src/onos/utils/jdvue/pom.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0"?>
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <prerequisites>
- <maven>3.0.4</maven>
- </prerequisites>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>jdvue</artifactId>
- <packaging>jar</packaging>
-
- <description>Java Package Dependency &amp; Analyzer</description>
-
- <properties>
- <!-- FIXME skipping checkstyle for now -->
- <checkstyle.skip>true</checkstyle.skip>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>18.0</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- <version>18.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.4.2</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.4.2</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.onlab.jdvue.DependencyViewer
- </mainClass>
- </transformer>
- </transformers>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java
deleted file mode 100644
index 40cb99a3..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Catalog.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Produces a package &amp; source catalogue.
- *
- * @author Thomas Vachuska
- */
-public class Catalog {
-
- private static final String PACKAGE = "package";
- private static final String IMPORT = "import";
- private static final String STATIC = "static";
- private static final String SRC_ROOT = "src/main/java/";
- private static final String WILDCARD = "\\.*$";
-
- private final Map<String, JavaSource> sources = new HashMap<>();
- private final Map<String, JavaPackage> packages = new HashMap<>();
- private final Set<DependencyCycle> cycles = new HashSet<>();
- private final Set<Dependency> cycleSegments = new HashSet<>();
- private final Map<JavaPackage, Set<DependencyCycle>> packageCycles = new HashMap<>();
- private final Map<JavaPackage, Set<Dependency>> packageCycleSegments = new HashMap<>();
-
- /**
- * Loads the catalog from the specified catalog file.
- *
- * @param catalogPath catalog file path
- * @throws IOException if unable to read the catalog file
- */
- public void load(String catalogPath) throws IOException {
- InputStream is = new FileInputStream(catalogPath);
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
-
- String line;
- while ((line = br.readLine()) != null) {
- // Split the line into the two fields: path and pragmas
- String fields[] = line.trim().split(":");
- if (fields.length <= 1) {
- continue;
- }
- String path = fields[0];
-
- // Now split the pragmas on whitespace and trim punctuation
- String pragma[] = fields[1].trim().replaceAll("[;\n\r]", "").split("[\t ]");
-
- // Locate (or create) Java source entity based on the path
- JavaSource source = getOrCreateSource(path);
-
- // Now process the package or import statements
- if (pragma[0].equals(PACKAGE)) {
- processPackageDeclaration(source, pragma[1]);
-
- } else if (pragma[0].equals(IMPORT)) {
- if (pragma[1].equals(STATIC)) {
- processImportStatement(source, pragma[2]);
- } else {
- processImportStatement(source, pragma[1]);
- }
- }
- }
- }
-
- /**
- * Analyzes the catalog by resolving imports and identifying circular
- * package dependencies.
- */
- public void analyze() {
- resolveImports();
- findCircularDependencies();
- }
-
- /**
- * Identifies circular package dependencies through what amounts to be a
- * depth-first search rooted with each package.
- */
- private void findCircularDependencies() {
- cycles.clear();
- for (JavaPackage javaPackage : getPackages()) {
- findCircularDependencies(javaPackage);
- }
-
- cycleSegments.clear();
- packageCycles.clear();
- packageCycleSegments.clear();
-
- for (DependencyCycle cycle : getCycles()) {
- recordCycleForPackages(cycle);
- cycleSegments.addAll(cycle.getCycleSegments());
- }
- }
-
- /**
- * Records the specified cycle into a set for each involved package.
- *
- * @param cycle cycle to record for involved packages
- */
- private void recordCycleForPackages(DependencyCycle cycle) {
- for (JavaPackage javaPackage : cycle.getCycle()) {
- Set<DependencyCycle> cset = packageCycles.get(javaPackage);
- if (cset == null) {
- cset = new HashSet<>();
- packageCycles.put(javaPackage, cset);
- }
- cset.add(cycle);
-
- Set<Dependency> sset = packageCycleSegments.get(javaPackage);
- if (sset == null) {
- sset = new HashSet<>();
- packageCycleSegments.put(javaPackage, sset);
- }
- sset.addAll(cycle.getCycleSegments());
- }
- }
-
- /**
- * Identifies circular dependencies in which this package participates
- * using depth-first search.
- *
- * @param javaPackage Java package to inspect for dependency cycles
- */
- private void findCircularDependencies(JavaPackage javaPackage) {
- // Setup a depth trace anchored at the given java package.
- List<JavaPackage> trace = newTrace(new ArrayList<JavaPackage>(), javaPackage);
-
- Set<JavaPackage> searched = new HashSet<>();
- searchDependencies(javaPackage, trace, searched);
- }
-
- /**
- * Generates a new trace using the previous one and a new element
- *
- * @param trace old search trace
- * @param javaPackage package to add to the trace
- * @return new search trace
- */
- private List<JavaPackage> newTrace(List<JavaPackage> trace,
- JavaPackage javaPackage) {
- List<JavaPackage> newTrace = new ArrayList<>(trace);
- newTrace.add(javaPackage);
- return newTrace;
- }
-
-
- /**
- * Recursive depth-first search through dependency tree
- *
- * @param javaPackage java package being searched currently
- * @param trace search trace
- * @param searched set of java packages already searched
- */
- private void searchDependencies(JavaPackage javaPackage,
- List<JavaPackage> trace,
- Set<JavaPackage> searched) {
- if (!searched.contains(javaPackage)) {
- searched.add(javaPackage);
- for (JavaPackage dependency : javaPackage.getDependencies()) {
- if (trace.contains(dependency)) {
- cycles.add(new DependencyCycle(trace, dependency));
- } else {
- searchDependencies(dependency, newTrace(trace, dependency), searched);
- }
- }
- }
- }
-
- /**
- * Resolves import names of Java sources into imports of entities known
- * to this catalog. All other import names will be ignored.
- */
- private void resolveImports() {
- for (JavaPackage javaPackage : getPackages()) {
- Set<JavaPackage> dependencies = new HashSet<>();
- for (JavaSource source : javaPackage.getSources()) {
- Set<JavaEntity> imports = resolveImports(source);
- source.setImports(imports);
- dependencies.addAll(importedPackages(imports));
- }
- javaPackage.setDependencies(dependencies);
- }
- }
-
- /**
- * Produces a set of imported Java packages from the specified set of
- * Java source entities.
- *
- * @param imports list of imported Java source entities
- * @return list of imported Java packages
- */
- private Set<JavaPackage> importedPackages(Set<JavaEntity> imports) {
- Set<JavaPackage> packages = new HashSet<>();
- for (JavaEntity entity : imports) {
- packages.add(entity instanceof JavaPackage ? (JavaPackage) entity :
- ((JavaSource) entity).getPackage());
- }
- return packages;
- }
-
- /**
- * Resolves import names of the specified Java source into imports of
- * entities known to this catalog. All other import names will be ignored.
- *
- * @param source Java source
- * @return list of resolved imports
- */
- private Set<JavaEntity> resolveImports(JavaSource source) {
- Set<JavaEntity> imports = new HashSet<>();
- for (String importName : source.getImportNames()) {
- JavaEntity entity = importName.matches(WILDCARD) ?
- getPackage(importName.replaceAll(WILDCARD, "")) :
- getSource(importName);
- if (entity != null) {
- imports.add(entity);
- }
- }
- return imports;
- }
-
- /**
- * Returns either an existing or a newly created Java package.
- *
- * @param packageName Java package name
- * @return Java package
- */
- private JavaPackage getOrCreatePackage(String packageName) {
- JavaPackage javaPackage = packages.get(packageName);
- if (javaPackage == null) {
- javaPackage = new JavaPackage(packageName);
- packages.put(packageName, javaPackage);
- }
- return javaPackage;
- }
-
- /**
- * Returns either an existing or a newly created Java source.
- *
- * @param path Java source path
- * @return Java source
- */
- private JavaSource getOrCreateSource(String path) {
- String name = nameFromPath(path);
- JavaSource source = sources.get(name);
- if (source == null) {
- source = new JavaSource(name, path);
- sources.put(name, source);
- }
- return source;
- }
-
- /**
- * Extracts a fully qualified source class name from the given path.
- * <p/>
- * For now, this implementation assumes standard Maven source structure
- * and thus will look for start of package name under 'src/main/java/'.
- * If it will not find such a prefix, it will simply return the path as
- * the name.
- *
- * @param path source path
- * @return source name
- */
- private String nameFromPath(String path) {
- int i = path.indexOf(SRC_ROOT);
- String name = i < 0 ? path : path.substring(i + SRC_ROOT.length());
- return name.replaceAll("\\.java$", "").replace("/", ".");
- }
-
- /**
- * Processes the package declaration pragma for the given source.
- *
- * @param source Java source
- * @param packageName Java package name
- */
- private void processPackageDeclaration(JavaSource source, String packageName) {
- JavaPackage javaPackage = getOrCreatePackage(packageName);
- source.setPackage(javaPackage);
- javaPackage.addSource(source);
- }
-
- /**
- * Processes the import pragma for the given source.
- *
- * @param source Java source
- * @param name name of the Java entity being imported (class or package)
- */
- private void processImportStatement(JavaSource source, String name) {
- source.addImportName(name);
- }
-
- /**
- * Returns the collection of java sources.
- *
- * @return collection of java sources
- */
- public Collection<JavaSource> getSources() {
- return Collections.unmodifiableCollection(sources.values());
- }
-
- /**
- * Returns the Java source with the specified name.
- *
- * @param name Java source name
- * @return Java source
- */
- public JavaSource getSource(String name) {
- return sources.get(name);
- }
-
- /**
- * Returns the collection of all Java packages.
- *
- * @return collection of java packages
- */
- public Collection<JavaPackage> getPackages() {
- return Collections.unmodifiableCollection(packages.values());
- }
-
- /**
- * Returns the set of all Java package dependency cycles.
- *
- * @return set of dependency cycles
- */
- public Set<DependencyCycle> getCycles() {
- return Collections.unmodifiableSet(cycles);
- }
-
- /**
- * Returns the set of all Java package dependency cycle segments.
- *
- * @return set of dependency cycle segments
- */
- public Set<Dependency> getCycleSegments() {
- return Collections.unmodifiableSet(cycleSegments);
- }
-
- /**
- * Returns the set of dependency cycles which involve the specified package.
- *
- * @param javaPackage java package
- * @return set of dependency cycles
- */
- public Set<DependencyCycle> getPackageCycles(JavaPackage javaPackage) {
- Set<DependencyCycle> set = packageCycles.get(javaPackage);
- return Collections.unmodifiableSet(set == null ? new HashSet<DependencyCycle>() : set);
- }
-
- /**
- * Returns the set of dependency cycle segments which involve the specified package.
- *
- * @param javaPackage java package
- * @return set of dependency cycle segments
- */
- public Set<Dependency> getPackageCycleSegments(JavaPackage javaPackage) {
- Set<Dependency> set = packageCycleSegments.get(javaPackage);
- return Collections.unmodifiableSet(set == null ? new HashSet<Dependency>() : set);
- }
-
- /**
- * Returns the Java package with the specified name.
- *
- * @param name Java package name
- * @return Java package
- */
- public JavaPackage getPackage(String name) {
- return packages.get(name);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("packages", packages.size())
- .add("sources", sources.size())
- .add("cycles", cycles.size())
- .add("cycleSegments", cycleSegments.size()).toString();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java
deleted file mode 100644
index 21fae479..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/Dependency.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Abstraction of a dependency segment.
- *
- * @author Thomas Vachuska
- */
-public class Dependency {
-
- private final JavaPackage source;
- private final JavaPackage target;
-
- /**
- * Creates a dependency from the specified source on the given target.
- *
- * @param source source of the dependency
- * @param target target of the dependency
- */
- public Dependency(JavaPackage source, JavaPackage target) {
- this.source = source;
- this.target = target;
- }
-
- /**
- * Returns the dependency source.
- *
- * @return source Java package
- */
- public JavaPackage getSource() {
- return source;
- }
-
- /**
- * Returns the dependency target.
- *
- * @return target Java package
- */
- public JavaPackage getTarget() {
- return target;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Dependency) {
- Dependency that = (Dependency) obj;
- return Objects.equals(source, that.source) &&
- Objects.equals(target, that.target);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(source, target);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("source", source).add("target", target).toString();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java
deleted file mode 100644
index 0fc761d4..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyCycle.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Simple representation of a Java package dependency cycle.
- */
-public class DependencyCycle {
-
- private final List<JavaPackage> cycle;
-
- /**
- * Creates a normalized dependency cycle represented by the specified list
- * of Java packages, which are expected to be given in order of dependency.
- * List is assumed to be non-empty.
- *
- * @param cycle list of Java packages in the dependency cycle
- * @param cause Java package that caused the cycle
- */
- DependencyCycle(List<JavaPackage> cycle, JavaPackage cause) {
- this.cycle = normalize(cycle, cause);
- }
-
- /**
- * Produces a normalized dependency cycle list. Normalization is performed
- * by rotating the list so that the package with the least lexicographic
- * name is at the start of the list.
- *
- * @param cycle list of Java packages in the dependency cycle
- * @param cause Java package that caused the cycle
- * @return normalized cycle
- */
- private List<JavaPackage> normalize(List<JavaPackage> cycle, JavaPackage cause) {
- int start = cycle.indexOf(cause);
- List<JavaPackage> clone = new ArrayList<>(cycle.subList(start, cycle.size()));
- int leastIndex = findIndexOfLeastName(clone);
- Collections.rotate(clone, -leastIndex);
- return Collections.unmodifiableList(clone);
- }
-
- /**
- * Returns the index of the Java package with the least name.
- *
- * @param cycle list of Java packages in the dependency cycle
- * @return index of the least Java package name
- */
- private int findIndexOfLeastName(List<JavaPackage> cycle) {
- int leastIndex = 0;
- String leastName = cycle.get(leastIndex).name();
- for (int i = 1, n = cycle.size(); i < n; i++) {
- JavaPackage javaPackage = cycle.get(i);
- if (leastName.compareTo(javaPackage.name()) > 0) {
- leastIndex = i;
- leastName = javaPackage.name();
- }
- }
- return leastIndex;
- }
-
- /**
- * Returns the normalized Java package dependency cycle
- *
- * @return list of packages in the dependency cycle
- */
- public List<JavaPackage> getCycle() {
- return cycle;
- }
-
- /**
- * Returns the dependency cycle in form of individual dependencies.
- *
- * @return list of dependencies forming the cycle
- */
- public List<Dependency> getCycleSegments() {
- List<Dependency> dependencies = new ArrayList<>();
- for (int i = 0, n = cycle.size(); i < n; i++) {
- dependencies.add(new Dependency(cycle.get(i), cycle.get(i < n - 1 ? i + 1 : 0)));
- }
- return dependencies;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof DependencyCycle) {
- DependencyCycle that = (DependencyCycle) o;
- return Objects.equals(cycle, that.cycle);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return cycle.hashCode();
- }
-
- @Override
- public String toString() {
- return toStringHelper(this).add("cycle", cycle).toString();
- }
-
- public String toShortString() {
- StringBuilder sb = new StringBuilder("[");
- for (JavaPackage javaPackage : cycle) {
- sb.append(javaPackage.name()).append(", ");
- }
- if (sb.length() > 1) {
- sb.delete(sb.length() - 2, sb.length());
- }
- sb.append("]");
- return sb.toString();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java
deleted file mode 100644
index 32e9ef1c..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/DependencyViewer.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectWriter;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import java.io.BufferedReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Set;
-
-/**
- * Generator of a self-contained HTML file which serves as a GUI for
- * visualizing Java package dependencies carried in the supplied catalog.
- *
- * The HTML file is an adaptation of D3.js Hierarchical Edge Bundling as
- * shown at http://bl.ocks.org/mbostock/7607999.
- *
- * @author Thomas Vachuska
- */
-public class DependencyViewer {
-
- private static final String JPD_EXT = ".db";
- private static final String HTML_EXT = ".html";
-
- private static final String INDEX = "index.html";
- private static final String D3JS = "d3.v3.min.js";
-
- private static final String TITLE_PLACEHOLDER = "TITLE_PLACEHOLDER";
- private static final String D3JS_PLACEHOLDER = "D3JS_PLACEHOLDER";
- private static final String DATA_PLACEHOLDER = "DATA_PLACEHOLDER";
-
- private final Catalog catalog;
-
- /**
- * Creates a Java package dependency viewer.
- *
- * @param catalog dependency catalog
- */
- public DependencyViewer(Catalog catalog) {
- this.catalog = catalog;
- }
-
- /**
- * Main program entry point.
- *
- * @param args command line arguments
- */
- public static void main(String[] args) {
- Catalog cat = new Catalog();
- DependencyViewer viewer = new DependencyViewer(cat);
- try {
- String path = args[0];
- cat.load(path + JPD_EXT);
- cat.analyze();
-
- System.err.println(cat);
- viewer.dumpLongestCycle(cat);
- viewer.writeHTMLFile(path);
- } catch (IOException e) {
- System.err.println("Unable to process catalog: " + e.getMessage());
- }
- }
-
- /**
- * Prints out the longest cycle; just for kicks.
- * @param cat catalog
- */
- private void dumpLongestCycle(Catalog cat) {
- DependencyCycle longest = null;
- for (DependencyCycle cycle : cat.getCycles()) {
- if (longest == null || longest.getCycleSegments().size() < cycle.getCycleSegments().size()) {
- longest = cycle;
- }
- }
-
- if (longest != null) {
- for (Dependency dependency : longest.getCycleSegments()) {
- System.out.println(dependency);
- }
- }
- }
-
- /**
- * Writes the HTML catalog file for the given viewer.
- *
- * @param path base file path
- * @throws IOException if issues encountered writing the HTML file
- */
- public void writeHTMLFile(String path) throws IOException {
- String index = slurp(getClass().getResourceAsStream(INDEX));
- String d3js = slurp(getClass().getResourceAsStream(D3JS));
-
- FileWriter fw = new FileWriter(path + HTML_EXT);
- ObjectWriter writer = new ObjectMapper().writer(); // .writerWithDefaultPrettyPrinter();
- fw.write(index.replace(TITLE_PLACEHOLDER, path)
- .replace(D3JS_PLACEHOLDER, d3js)
- .replace(DATA_PLACEHOLDER, writer.writeValueAsString(toJson())));
- fw.close();
- }
-
- /**
- * Slurps the specified input stream into a string.
- *
- * @param stream input stream to be read
- * @return string containing the contents of the input stream
- * @throws IOException if issues encountered reading from the stream
- */
- static String slurp(InputStream stream) throws IOException {
- StringBuilder sb = new StringBuilder();
- BufferedReader br = new BufferedReader(new InputStreamReader(stream));
- String line;
- while ((line = br.readLine()) != null) {
- sb.append(line).append(System.lineSeparator());
- }
- br.close();
- return sb.toString();
- }
-
- // Produces a JSON structure designed to drive the hierarchical visual
- // representation of Java package dependencies and any dependency cycles
- private JsonNode toJson() {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode root = mapper.createObjectNode();
- root.put("packages", jsonPackages(mapper));
- root.put("cycleSegments", jsonCycleSegments(mapper, catalog.getCycleSegments()));
- root.put("summary", jsonSummary(mapper));
- return root;
- }
-
- // Produces a JSON summary of dependencies
- private JsonNode jsonSummary(ObjectMapper mapper) {
- ObjectNode summary = mapper.createObjectNode();
- summary.put("packages", catalog.getPackages().size());
- summary.put("sources", catalog.getSources().size());
- summary.put("cycles", catalog.getCycles().size());
- summary.put("cycleSegments", catalog.getCycleSegments().size());
- return summary;
- }
-
- // Produces a JSON structure with package dependency data
- private JsonNode jsonPackages(ObjectMapper mapper) {
- ArrayNode packages = mapper.createArrayNode();
- for (JavaPackage javaPackage : catalog.getPackages()) {
- packages.add(json(mapper, javaPackage));
- }
- return packages;
- }
-
- // Produces a JSON structure with all cyclic segments
- private JsonNode jsonCycleSegments(ObjectMapper mapper,
- Set<Dependency> segments) {
- ObjectNode cyclicSegments = mapper.createObjectNode();
- for (Dependency dependency : segments) {
- String s = dependency.getSource().name();
- String t = dependency.getTarget().name();
- cyclicSegments.put(t + "-" + s,
- mapper.createObjectNode().put("s", s).put("t", t));
- }
- return cyclicSegments;
- }
-
- // Produces a JSON object structure describing the specified Java package.
- private JsonNode json(ObjectMapper mapper, JavaPackage javaPackage) {
- ObjectNode node = mapper.createObjectNode();
-
- ArrayNode imports = mapper.createArrayNode();
- for (JavaPackage dependency : javaPackage.getDependencies()) {
- imports.add(dependency.name());
- }
-
- Set<DependencyCycle> packageCycles = catalog.getPackageCycles(javaPackage);
- Set<Dependency> packageCycleSegments = catalog.getPackageCycleSegments(javaPackage);
-
- node.put("name", javaPackage.name());
- node.put("size", javaPackage.getSources().size());
- node.put("imports", imports);
- node.put("cycleSegments", jsonCycleSegments(mapper, packageCycleSegments));
- node.put("cycleCount", packageCycles.size());
- node.put("cycleSegmentCount", packageCycleSegments.size());
- return node;
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java
deleted file mode 100644
index e74bdc60..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaEntity.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import java.util.Objects;
-
-/**
- * Abstraction of a Java source entity.
- */
-public abstract class JavaEntity {
-
- private final String name;
-
- /**
- * Creates a new Java source entity with the given name.
- *
- * @param name source entity name
- */
- JavaEntity(String name) {
- this.name = name;
- }
-
- /**
- * Returns the Java source entity name.
- *
- * @return source entity name
- */
- public String name() {
- return name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof JavaEntity) {
- JavaEntity that = (JavaEntity) o;
- return getClass().equals(that.getClass()) &&
- Objects.equals(name, that.name);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(name);
- }
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java
deleted file mode 100644
index a15cb4d3..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaPackage.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Simple abstraction of a Java package for the purpose of tracking
- * dependencies and requirements.
- *
- * @author Thomas Vachuska
- */
-public class JavaPackage extends JavaEntity {
-
- private final Set<JavaSource> sources = new HashSet<>();
- private Set<JavaPackage> dependencies;
-
- /**
- * Creates a new Java package.
- *
- * @param name java package file name
- */
- JavaPackage(String name) {
- super(name);
- }
-
- /**
- * Returns the set of sources contained in this Java package.
- *
- * @return set of Java sources
- */
- public Set<JavaSource> getSources() {
- return Collections.unmodifiableSet(sources);
- }
-
- /**
- * Adds the specified Java source to the package. Only possible if the
- * Java package of the source is the same as this Java package.
- *
- * @param source Java source to be added
- */
- void addSource(JavaSource source) {
- if (source.getPackage().equals(this)) {
- sources.add(source);
- }
- }
-
- /**
- * Returns the set of packages directly required by this package.
- *
- * @return set of Java package dependencies
- */
- Set<JavaPackage> getDependencies() {
- return dependencies;
- }
-
- /**
- * Sets the set of resolved Java packages on which this package dependens.
- *
- * @param dependencies set of resolved Java packages
- */
- void setDependencies(Set<JavaPackage> dependencies) {
- if (this.dependencies == null) {
- this.dependencies = Collections.unmodifiableSet(new HashSet<>(dependencies));
- }
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("name", name())
- .add("sources", sources.size())
- .add("dependencies", (dependencies != null ? dependencies.size() : 0))
- .toString();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java
deleted file mode 100644
index 1376cfee..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/JavaSource.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import java.util.*;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Simple abstraction of a Java source file for the purpose of tracking
- * dependencies and requirements.
- *
- * @author Thomas Vachuska
- */
-public class JavaSource extends JavaEntity {
-
- private String path;
- private JavaPackage javaPackage;
-
- private final Set<String> importNames = new HashSet<>();
- private Set<JavaEntity> imports;
-
- /**
- * Creates a new Java source entity.
- *
- * @param name java source file name
- * @param path source file path
- */
- JavaSource(String name, String path) {
- super(name);
- this.path = path;
- }
-
- /**
- * Returns the Java package for this Java source.
- *
- * @return Java package
- */
- public JavaPackage getPackage() {
- return javaPackage;
- }
-
- /**
- * Sets the Java package for this Java source.
- *
- * @param javaPackage Java package
- */
- void setPackage(JavaPackage javaPackage) {
- if (this.javaPackage == null) {
- this.javaPackage = javaPackage;
- }
- }
-
- /**
- * Returns the set of resolved imports for this Java source
- *
- * @return set of imports
- */
- public Set<JavaEntity> getImports() {
- return imports;
- }
-
- /**
- * Sets the set of resolved imported Java entities for this source.
- *
- * @param imports set of resolved Java entities imported by this source
- */
- void setImports(Set<JavaEntity> imports) {
- if (this.imports == null) {
- this.imports = Collections.unmodifiableSet(new HashSet<>(imports));
- }
- }
-
- /**
- * Adds a name of an imported, but unresolved, Java entity name.
- *
- * @param name name of an imported Java entity
- */
- void addImportName(String name) {
- importNames.add(name);
- }
-
- /**
- * Returns the set of imported, but unresolved, Java entity names.
- *
- * @return set of imported Java entity names
- */
- Set<String> getImportNames() {
- return importNames;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("name", name())
- .add("javaPackage", (javaPackage != null ? javaPackage.name() : ""))
- .add("importNames", importNames.size())
- .add("imports", (imports != null ? imports.size() : 0))
- .toString();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/package-info.java b/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/package-info.java
deleted file mode 100644
index 2f77ef24..00000000
--- a/framework/src/onos/utils/jdvue/src/main/java/org/onlab/jdvue/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utility to analyze Java package dependencies.
- */
-package org.onlab.jdvue; \ No newline at end of file
diff --git a/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/d3.v3.min.js b/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/d3.v3.min.js
deleted file mode 100644
index 4895e91b..00000000
--- a/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/d3.v3.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new o;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function y(){Zo.event.preventDefault()}function x(){for(var n,t=Zo.event;n=t.sourceEvent;)t=n;return t}function M(n){for(var t=new d,e=0,r=arguments.length;++e<r;)t[arguments[e]]=m(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Zo.event;u.target=n,Zo.event=u,t[u.type].apply(e,r)}finally{Zo.event=i}}},t}function _(n){return sa(n,pa),n}function b(n){return"function"==typeof n?n:function(){return la(n,this)}}function w(n){return"function"==typeof n?n:function(){return fa(n,this)}}function S(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Zo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function k(n){return n.trim().replace(/\s+/g," ")}function E(n){return new RegExp("(?:^|\\s+)"+Zo.requote(n)+"(?:\\s+|$)","g")}function A(n){return(n+"").trim().split(/^|\s+/)}function C(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=A(n).map(N);var u=n.length;return"function"==typeof t?r:e}function N(n){var t=E(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",k(u+" "+n))):e.setAttribute("class",k(u.replace(t," ")))}}function z(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function L(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function T(n){return"function"==typeof n?n:(n=Zo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function q(n){return{__data__:n}}function R(n){return function(){return ga(this,n)}}function D(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function P(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function H(){var n=this.__transition__;n&&++n.active}function F(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Xo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Zo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=O;a>0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Va=n,e}function zt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*ua(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=ec[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&nc!==Rt,o=new(i?Rt:nc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ot(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Yt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function It(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Vt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.y=$t(+r[0]),e+r[0].length):-1}function Xt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=-t,e+5):-1}function $t(n){return n+(n>68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ue(){}function ie(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function oe(n,t){n&&cc.hasOwnProperty(n.type)&&cc[n.type](n,t)}function ae(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ce(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)ae(n[e],t,1);t.polygonEnd()}function se(){function n(n,t){n*=Aa,t=t*Aa/2+ba/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])<ka&&ua(n[1]-t[1])<ka}function ye(n,t){n*=Aa;var e=Math.cos(t*=Aa);xe(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function xe(n,t,e){++hc,pc+=(n-pc)/hc,vc+=(t-vc)/hc,dc+=(e-dc)/hc}function Me(){function n(n,u){n*=Aa;var i=Math.cos(u*=Aa),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);gc+=s,mc+=s*(t+(t=o)),yc+=s*(e+(e=a)),xc+=s*(r+(r=c)),xe(t,e,r)}var t,e,r;wc.point=function(u,i){u*=Aa;var o=Math.cos(i*=Aa);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),wc.point=n,xe(t,e,r)}}function _e(){wc.point=ye}function be(){function n(n,t){n*=Aa;var e=Math.cos(t*=Aa),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-J(g)/h,v=Math.atan2(h,g);Mc+=p*s,_c+=p*l,bc+=p*f,gc+=v,mc+=v*(r+(r=o)),yc+=v*(u+(u=a)),xc+=v*(i+(i=c)),xe(r,u,i)}var t,e,r,u,i;wc.point=function(o,a){t=o,e=a,wc.point=n,o*=Aa;var c=Math.cos(a*=Aa);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),xe(r,u,i)},wc.lineEnd=function(){n(t,e),wc.lineEnd=_e,wc.point=ye}}function we(){return!0}function Se(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(me(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function Ee(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ae(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)<ka?(n.point(e,r=(r+o)/2>0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)<ka&&(e-=u*ka),ua(i-a)<ka&&(i-=a*ka),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return ua(o)>ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]<t[0]?ba:-ba;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function De(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)<ka,N=C||ka>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)<ka?k:E):k<=_[1]&&_[1]<=E:A>ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)<ka?u>0?0:3:ua(r[0]-e)<ka?u>0?2:1:ua(r[1]-t)<ka?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)<ka||ua(r-h)<ka?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;(T*T/M>i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16;
- return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)<ka?rr:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-B(u)*Math.sqrt(n*n+e*e)]},e)}function Mr(n,t){return[n,Math.log(Math.tan(ba/4+t/2))]}function _r(n){var t,e=nr(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=ba*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function br(n,t){return[Math.log(Math.tan(ba/4+t/2)),-n]}function wr(n){return n[0]}function Sr(n){return n[1]}function kr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)<ka&&ua(r-c.circle.cy)<ka;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Yr(c);for(var s=o;s.circle&&ua(e-s.circle.x)<ka&&ua(r-s.circle.cy)<ka;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Yr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)<ka&&p-u>ka?{x:f,y:ua(t-f)<ka?e:p}:ua(u-p)<ka&&h-r>ka?{x:ua(e-p)<ka?t:h,y:p}:ua(r-h)<ka&&u-g>ka?{x:h,y:ua(t-h)<ka?e:g}:ua(u-g)<ka&&r-f>ka?{x:ua(e-g)<ka?t:f,y:g}:null),i.site,null)),++c)}function Hr(n,t){return t.angle-n.angle}function Fr(){Gr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Or(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}$c.insert(y,m),y||(Xc=m)}}}}function Yr(n){var t=n.circle;t&&(t.P||(Xc=t.N),$c.remove(t),Wc.push(t),Gr(t),n.circle=null)}function Ir(n){for(var t,e=Ic,r=Pe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Zr(t,n)||!r(t)||ua(t.a.x-t.b.x)<ka&&ua(t.a.y-t.b.y)<ka)&&(t.a=t.b=null,e.splice(u,1))}function Zr(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Vr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Xr(n,t,e,r){var u=new Vr(n,t);return Ic.push(u),e&&Br(u,n,t,e),r&&Br(u,t,n,r),Zc[n.i].edges.push(new Wr(u,n,t)),Zc[t.i].edges.push(new Wr(u,t,n)),u}function $r(n,t,e){var r=new Vr(n,null);return r.a=t,r.b=e,Ic.push(r),r}function Br(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Wr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Jr(){this._=null}function Gr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Kr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Qr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function nu(n){for(;n.L;)n=n.L;return n}function tu(n,t){var e,r,u,i=n.sort(eu).pop();for(Ic=[],Zc=new Array(n.length),Vc=new Jr,$c=new Jr;;)if(u=Xc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Zc[i.i]=new Ur(i),Rr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Ir(t),jr(t));var o={cells:Zc,edges:Ic};return Vc=$c=Ic=Zc=null,o}function eu(n,t){return t.y-n.y||t.x-n.x}function ru(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function uu(n){return n.x}function iu(n){return n.y}function ou(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function au(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&au(n,c[0],e,r,o,a),c[1]&&au(n,c[1],o,r,u,a),c[2]&&au(n,c[2],e,a,o,i),c[3]&&au(n,c[3],o,a,u,i)}}function cu(n,t){n=Zo.rgb(n),t=Zo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+dt(Math.round(e+i*n))+dt(Math.round(r+o*n))+dt(Math.round(u+a*n))}}function su(n,t){var e,r={},u={};for(e in n)e in t?r[e]=hu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function lu(n,t){return t-=n=+n,function(e){return n+t*e}}function fu(n,t){var e,r,u,i=Gc.lastIndex=Kc.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=Gc.exec(n))&&(r=Kc.exec(t));)(u=r.index)>i&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return i<t.length&&(u=t.substring(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Ca,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ca:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Ru(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Du(n,t){var e,r=[],u=[],i=Zo.transform(n),o=Zo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:lu(a[0],c[0])},{i:3,x:lu(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function ju(n){for(var t=n.source,e=n.target,r=Fu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Hu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Fu(n,t){if(n===t)return n;for(var e=Hu(n),r=Hu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Ou(n){n.fixed|=2}function Yu(n){n.fixed&=-7}function Iu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Zu(n){n.fixed&=-5}function Vu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Vu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Xu(n,t){return Zo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Ku,n}function $u(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Wu(n){return n.children}function Ju(n){return n.value}function Gu(n,t){return t.value-n.value}function Ku(n){return Zo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Qu(n){return n.x}function ni(n){return n.y}function ti(n,t,e){n.y0=t,n.y=e}function ei(n){return Zo.range(n.length)}function ri(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ui(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?hi(r,u=a):hi(r=c,u),o--):(fi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)mi(u[i],t,e,r)}function yi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function xi(n,t){return n.parent==t.parent?1:2}function Mi(n){var t=n.children;return t.length?t[0]:n.t}function _i(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function bi(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function wi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Zo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ui(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++a<c;)u.has(i=r[a])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,a=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,o){arguments.length<2&&(o=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+o);return i=r(n.length<2?(c+s)/2:c+l*o/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-o+2*c);return i=r(l+h*c,h),s&&i.reverse(),a=h*(1-o),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-o+2*c)),g=f-l-(n.length-o)*h;return i=r(l+Math.round(g/2),h),s&&i.reverse(),a=Math.round(h*(1-o)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return Bi(n,t)},e.domain(n)}function Wi(e,r){function u(){var n=0,t=r.length;for(o=[];++n<t;)o[n-1]=Zo.quantile(e,n/t);return i}function i(n){return isNaN(n=+n)?void 0:r[Zo.bisect(o,n)]}var o;return i.domain=function(r){return arguments.length?(e=r.filter(t).sort(n),u()):e},i.range=function(n){return arguments.length?(r=n,u()):r},i.quantiles=function(){return o},i.invertExtent=function(n){return n=r.indexOf(n),0>n?[0/0,0/0]:[n>0?o[n-1]:e[0],n<o.length?o[n]:e[e.length-1]]},i.copy=function(){return Wi(e,r)},u()}function Ji(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=wr,r=Sr,u=we,i=uo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=xs.get(n)||uo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function uo(n){return n.join("L")}function io(n){return uo(n)+"Z"}function oo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function so(n,t){return n.length<4?uo(n):n[1]+ho(n.slice(1,n.length-1),go(n,t))}function lo(n,t){return n.length<3?uo(n):n[0]+ho((n.push(n[0]),n),go([n[n.length-2]].concat(n,[n[1]]),t))}function fo(n,t){return n.length<3?uo(n):n[0]+ho(n,go(n,t))}function ho(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return uo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function go(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function po(n){if(n.length<3)return uo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",xo(bs,o),",",xo(bs,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Mo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function vo(n){if(n.length<4)return uo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(xo(bs,i)+","+xo(bs,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Mo(e,i,o);return e.join("")}function mo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[xo(bs,o),",",xo(bs,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Mo(t,o,a);return t.join("")}function yo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return po(n)}function xo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Mo(n,t,e){n.push("C",xo(Ms,t),",",xo(Ms,e),",",xo(_s,t),",",xo(_s,e),",",xo(bs,t),",",xo(bs,e))}function _o(n,t){return(t[1]-n[1])/(t[0]-n[0])}function bo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=_o(u,i);++t<e;)r[t]=(o+(o=_o(u=i,i=n[t+1])))/2;return r[t]=o,r}function wo(n){for(var t,e,r,u,i=[],o=bo(n),a=-1,c=n.length-1;++a<c;)t=_o(n[a],n[a+1]),ua(t)<ka?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ms,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Eo(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=bt(e),_=bt(u),b=e===r?function(){return g}:bt(r),w=u===i?function(){return p}:bt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=wr,r=wr,u=0,i=Sr,o=we,a=uo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=xs.get(n)||uo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Ao(n){return n.radius}function Co(n){return[n.x,n.y]}function No(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ms;return[e*Math.cos(r),e*Math.sin(r)]}}function zo(){return 64}function Lo(){return"circle"}function To(n){var t=Math.sqrt(n/ba);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function qo(n,t){return sa(n,Cs),n.id=t,n}function Ro(n,t,e,r){var u=n.id;return P(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Do(n){return null==n&&(n=""),function(){this.textContent=n}}function Po(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var a=r.time;i=u[e]={tween:new o,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Zo.timer(function(r){function o(r){return u.active>e?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);
- return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]<Us[i]/u?i-1:i]:[Fs,Fi(n,e)[2]]}return r.invert=function(t){return Oo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Oo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Oo(+e+1),t).length}var i=r.domain(),o=Li(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Ri(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Zo.mean=function(n,e){var r,u=0,i=n.length,o=-1,a=i;if(1===arguments.length)for(;++o<i;)t(r=n[o])?u+=r:--a;else for(;++o<i;)t(r=e.call(n,n[o],o))?u+=r:--a;return a?u/a:void 0},Zo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Zo.median=function(e,r){return arguments.length>1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n<t;)for(var u,i=-1,o=e[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return e},Zo.transpose=function(n){return Zo.zip.apply(Zo,n)},Zo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Zo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Zo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Zo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)<t;)i.push(r/o);return i},Zo.map=function(n){var t=new o;if(n instanceof o)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},i(o,{has:a,get:function(n){return this[ia+n]},set:function(n,t){return this[ia+n]=t},remove:c,keys:s,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1),this[t])}});var ia="\x00",oa=ia.charCodeAt(0);Zo.nest=function(){function n(t,a,c){if(c>=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=g(n,t,t[e]);return n};var aa=["webkit","ms","moz","Moz","o","O"];Zo.dispatch=function(){for(var n=new d,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=m(n);return n},d.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return _(i)},pa.selectAll=function(n){var t,e,r=[];n=w(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Xo(n.call(e,e.__data__,a,u))),t.parentNode=e);return _(r)};var va={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Zo.ns={prefix:va,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!E(n[u]).test(t))return!1;return!0}for(t in n)this.each(C(t,n[t]));return this}return this.each(C(n,t))},pa.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++r<a;)d=t.call(u=n[r],u.__data__,r),m.has(d)?v[r]=u:m.set(d,u),x.push(d);for(r=-1;++r<f;)d=t.call(e,i=e[r],r),(u=m.get(d))?(g[r]=u,u.__data__=i):y.has(d)||(p[r]=q(i)),y.set(d,i),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=q(i);for(;f>r;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i<a;)(u=r[i])&&(n[i]=u.__data__);return n}var c=U([]),s=_([]),l=_([]);if("function"==typeof n)for(;++i<a;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<a;)e(r=this[i],n);return s.enter=function(){return c},s.exit=function(){return l},s},pa.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},pa.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},pa.each=function(n){return P(this,function(t,e,r){n.call(t,t.__data__,e,r)})},pa.call=function(n){var t=Xo(arguments);return n.apply(t[0]=this,t),this},pa.empty=function(){return!this.node()},pa.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return _(o)},da.insert=function(n,t){return arguments.length<2&&(t=j(this)),pa.insert.call(this,n,t)},pa.transition=function(){for(var n,t,e=Ss||++Ns,r=[],u=ks||{time:Date.now(),ease:xu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&Po(t,c,e,u),n.push(t)}return qo(r,e)},pa.interrupt=function(){return this.each(H)},Zo.select=function(n){var t=["string"==typeof n?la(n,$o):n];return t.parentNode=Bo,_([t])},Zo.selectAll=function(n){var t=Xo("string"==typeof n?fa(n,$o):n);return t.parentNode=Bo,_([t])};var ma=Zo.select(Bo);pa.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)oe(e[r].geometry,t)}},cc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){ae(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t,0)},Polygon:function(n,t){ce(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ce(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)oe(e[r],t)}};Zo.geo.area=function(n){return sc=0,Zo.geo.stream(n,fc),sc};var sc,lc=new ue,fc={sphere:function(){sc+=4*ba},point:v,lineStart:v,lineEnd:v,polygonStart:function(){lc.reset(),fc.lineStart=se},polygonEnd:function(){var n=2*lc;sc+=0>n?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,fc.polygonStart()},polygonEnd:function(){fc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>lc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);
- for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=wr,r=Sr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Zo.geom.polygon=function(n){return sa(n,Yc),n};var Yc=Zo.geom.polygon.prototype=[];Yc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Yc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Yc.clip=function(n){for(var t,e,r,u,i,o,a=Nr(n),c=-1,s=this.length-Nr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Ar(o,l,u)?(Ar(i,l,u)||n.push(Cr(i,o,l,u)),n.push(o)):Ar(i,l,u)&&n.push(Cr(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Ic,Zc,Vc,Xc,$c,Bc=[],Wc=[];Ur.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Hr),t.length},Wr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Jr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=nu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Qr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Qr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?nu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Qr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Kr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Qr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Kr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Qr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Zo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return tu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&ru(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=bt(r=n),t):r},t.y=function(n){return arguments.length?(o=bt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Jc:n,t):a===Jc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Jc?null:a&&a[1]},t)};var Jc=[[-1e6,-1e6],[1e6,1e6]];Zo.geom.delaunay=function(n){return Zo.geom.voronoi().triangles(n)},Zo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(ua(c-e)+ua(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=wr,c=Sr;return(o=arguments.length)?(a=uu,c=iu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Zo.interpolateRgb=cu,Zo.interpolateObject=su,Zo.interpolateNumber=lu,Zo.interpolateString=fu;var Gc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Kc=new RegExp(Gc.source,"g");Zo.interpolate=hu,Zo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ia.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cu:fu:t instanceof et?cu:Array.isArray(t)?gu:"object"===e&&isNaN(t)?su:lu)(n,t)}],Zo.interpolateArray=gu;var Qc=function(){return wt},ns=Zo.map({linear:Qc,poly:Mu,quad:function(){return mu},cubic:function(){return yu},sin:function(){return _u},exp:function(){return bu},circle:function(){return wu},elastic:Su,back:ku,bounce:function(){return Eu}}),ts=Zo.map({"in":wt,out:vu,"in-out":du,"out-in":function(n){return du(vu(n))}});Zo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(ju(n[e]));return t}},Zo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Zo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Zo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(wa-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Zo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Zo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Xu(e,r)},Zo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Zo.sum(o),s=Zo.range(i.length);null!=e&&s.sort(e===os?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=os,r=0,u=wa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var os={};Zo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Zo.permute(s,f),l=Zo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Zo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ni,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ni(t):zi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return zi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ni:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Xu(i,a)},Zo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);
- return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),Po(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return qo(i,u)},Cs.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=w(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&Po(u,g,o,i),t.push(u)}return qo(a,o)},Cs.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]<x[0])],z[1]=f[+(n[1]<x[1])]):x=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Ti(t),c=a[0],s=a[1],p=z[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}(); \ No newline at end of file
diff --git a/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/index.html b/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/index.html
deleted file mode 100644
index be0b581c..00000000
--- a/framework/src/onos/utils/jdvue/src/main/resources/org/onlab/jdvue/index.html
+++ /dev/null
@@ -1,371 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>TITLE_PLACEHOLDER</title>
- <style>
-
- .node {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- fill: #bbb;
- }
-
- .link {
- stroke: steelblue;
- stroke-opacity: .4;
- fill: none;
- pointer-events: none;
- }
-
- .node--focus {
- font-weight: 700;
- fill: #000;
- }
-
- .node:hover {
- fill: steelblue;
- }
-
- .node:hover,
- .node--source,
- .node--target {
- font-weight: 700;
- }
-
- .node--source {
- fill: #2ca02c;
- }
-
- .node--target {
- fill: #d59800;
- }
-
- .link--source,
- .link--target {
- stroke-opacity: 1;
- stroke-width: 3px;
- }
-
- .link--source {
- stroke: #d59800;
- }
-
- .link--target {
- stroke: #2ca02c;
- }
-
- .link--cycle {
- stroke: #ff0000;
- }
-
- .summary {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 32px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .details {
- display: none;
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 220px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .shown {
- display:block;
- }
-
- .stat {
- text-align: right;
- width: 64px;
- }
-
- .title {
- font-size: 16px;
- font-weight: bold;
- }
-
- #package {
- font-size: 14px;
- font-weight: bold;
- }
- </style>
-</head>
-<body>
- <div class="summary">
- <div class="title">Project TITLE_PLACEHOLDER</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="sourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Packages:</td>
- <td id="packageCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="segmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="cycleCount" class="stat"></td>
- </tr>
- </table>
- <div><hr size="1"></div>
- <div><input type="checkbox"> Highlight cycles</input></div>
- <div><input style="width: 95%" type="range" min="0" max="100" value="75"></div>
- </div>
- <div class="details">
- <div id="package">Package Details</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="psourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Dependents:</td>
- <td id="pdependentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="psegmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="pcycleCount" class="stat"></td>
- </tr>
- </table>
- </div>
-<script>
-D3JS_PLACEHOLDER
-
- var catalog =
-DATA_PLACEHOLDER
- ;
-
- var diameter = 1000,
- radius = diameter / 2,
- innerRadius = radius - 300;
-
- var cluster = d3.layout.cluster()
- .size([360, innerRadius])
- .sort(null)
- .value(function(d) { return d.size; });
-
- var bundle = d3.layout.bundle();
-
- var line = d3.svg.line.radial()
- .interpolate("bundle")
- .tension(.75)
- .radius(function(d) { return d.y; })
- .angle(function(d) { return d.x / 180 * Math.PI; });
-
- var svg = d3.select("body").append("svg")
- .attr("width", diameter)
- .attr("height", diameter)
- .append("g")
- .attr("transform", "translate(" + radius + "," + radius + ")");
-
- var link = svg.append("g").selectAll(".link"),
- node = svg.append("g").selectAll(".node"),
- cycles = {}, highlightCycles, selectedNode;
-
- function isCyclicLink(l) {
- return highlightCycles &&
- (cycles[l.source.key + "-" + l.target.key] || cycles[l.target.key + "-" + l.source.key]);
- }
-
- function isCyclicPackageLink(l, p) {
- var key = l.source.key + "-" + l.target.key,
- rKey = l.target.key + "-" + l.source.key;
- return isCyclicLink(l) && (p.cycleSegments[key] || p.cycleSegments[rKey]);
- }
-
- function refreshPaths() {
- svg.selectAll("path.link").classed("link--cycle", isCyclicLink);
- }
-
- function processCatalog() {
- var nodes = cluster.nodes(packageHierarchy(catalog.packages)),
- links = packageImports(nodes),
- splines = bundle(links);
- cycles = catalog.cycleSegments;
-
- d3.select("input[type=checkbox]").on("change", function() {
- highlightCycles = this.checked;
- refreshPaths();
- });
-
- link = link
- .data(splines)
- .enter().append("path")
- .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
- .attr("class", "link")
- .classed("link--cycle", isCyclicLink)
- .attr("d", function(d, i) { return line(splines[i]); });
-
-
- node = node
- .data(nodes.filter(function(n) { return !n.children; }))
- .enter().append("text")
- .attr("class", "node")
- .attr("dy", ".31em")
- .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
- .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
- .text(function(d) { return d.key; })
- .on("focus", processSelect)
- .on("blur", processSelect);
-
- d3.select("input[type=range]").on("change", function() {
- line.tension(this.value / 100);
- svg.selectAll("path.link")
- .data(splines)
- .attr("d", function(d, i) { return line(splines[i]); });
- });
-
- d3.select("#packageCount").text(catalog.summary.packages);
- d3.select("#sourceCount").text(catalog.summary.sources);
- d3.select("#segmentCount").text(catalog.summary.cycleSegments);
- d3.select("#cycleCount").text(catalog.summary.cycles);
- }
-
- function processSelect(d) {
- if (selectedNode === d) {
- deselected(d);
- selectedNode = null;
-
- } else if (selectedNode) {
- deselected(selectedNode);
- selectedNode = null;
- selected(d);
-
- } else {
- selected(d);
- selectedNode = d;
- }
- }
-
- function selected(d) {
- node
- .each(function(n) { n.target = n.source = false; })
- .classed("node--focus", function(n) { return n === d; });
-
- link
- .classed("link--cycle", function(l) { return isCyclicPackageLink(l, d); })
- .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
- .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
- .filter(function(l) { return l.target === d || l.source === d; })
- .each(function() { this.parentNode.appendChild(this); });
-
- node
- .classed("node--target", function(n) { return n.target; })
- .classed("node--source", function(n) { return n.source; });
-
- d3.select("#psourceCount").text(d.size);
- d3.select("#pdependentCount").text(d.imports.length);
- d3.select("#psegmentCount").text(d.cycleSegmentCount);
- d3.select("#pcycleCount").text(d.cycleCount);
- d3.select(".details").classed("shown", function() { return true; });
- }
-
- function deselected(d) {
- link
- .classed("link--cycle", isCyclicLink)
- .classed("link--target", false)
- .classed("link--source", false);
-
- node
- .classed("node--target", false)
- .classed("node--source", false)
- .classed("node--focus", false);
- d3.select(".details").classed("shown", function() { return false; });
- }
-
- d3.select(self.frameElement).style("height", diameter + "px");
-
- // Lazily construct the package hierarchy.
- function packageHierarchy(packages) {
- var map = {}, cnt = 0;
-
- // Builds the structure top-down to the specified leaf or until
- // another leaf in which case hook this leaf to the same parent
- function buildHierarchy(leaf, i) {
- var leafName = leaf.name,
- node, name, parent = map[""], start = 0;
- while (start < leafName.length) {
- name = parentName(leafName, start);
- node = map[name];
- if (!node) {
- node = map[name] = parentNode(name, parent);
- parent.children.push(node);
-
- } else if (node.imports) {
- leaf.parent = parent;
- parent.children.push(leaf);
- break;
- }
- parent = node;
- start = name.length + 1;
- }
- }
-
- function parentNode(name, parent) {
- return {name: name, parent: parent, key: name, children: []};
- }
-
- function parentName(leafName, start) {
- var i = leafName.indexOf(".", start);
- return i > 0 ? leafName.substring(0, i) : leafName;
- }
-
- // First populate all packages as leafs
- packages.forEach(function(d) {
- map[d.name] = d;
- d.key = d.name;
- });
-
- // Next synthesize the intermediate structure, by-passing any leafs
- map[""] = parentNode("", null);
- var i = 0;
- packages.forEach(function(d) {
- buildHierarchy(d, i++);
- });
-
- return map[""];
- }
-
- // Return a list of imports for the given array of nodes.
- function packageImports(nodes) {
- var map = {},
- imports = [];
-
- // Compute a map from name to node.
- nodes.forEach(function(d) {
- map[d.name] = d;
- });
-
- // For each import, construct a link from the source to target node.
- nodes.forEach(function(d) {
- if (d.imports) d.imports.forEach(function(i) {
- imports.push({source: map[d.name], target: map[i]});
- });
- });
-
- return imports;
- }
-
- processCatalog();
-</script>
-</body>
-</html>
diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java
deleted file mode 100644
index b792abcc..00000000
--- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/CatalogTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import org.junit.Test;
-import org.onlab.jdvue.Catalog;
-import org.onlab.jdvue.JavaPackage;
-import org.onlab.jdvue.JavaSource;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Unit test for the source catalog.
- *
- * @author Thomas Vachuska
- */
-public class CatalogTest {
-
- @Test
- public void basics() throws IOException {
- Catalog cat = new Catalog();
- cat.load("src/test/resources/catalog.db");
- cat.analyze();
-
- assertEquals("incorrect package count", 12, cat.getPackages().size());
- assertEquals("incorrect source count", 14, cat.getSources().size());
-
- JavaPackage pkg = cat.getPackage("k");
- assertNotNull("package should be found", pkg);
-
- JavaSource src = cat.getSource("k.K");
- assertNotNull("source should be found", src);
-
- assertEquals("incorrect package source count", 1, pkg.getSources().size());
- assertEquals("incorrect package dependency count", 1, pkg.getDependencies().size());
- assertEquals("incorrect package cycle count", 3, cat.getPackageCycles(pkg).size());
-
- assertEquals("incorrect segment count", 11, cat.getCycleSegments().size());
- assertEquals("incorrect cycle count", 5, cat.getCycles().size());
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java
deleted file mode 100644
index 895c713f..00000000
--- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyCycleTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import org.junit.Test;
-import org.onlab.jdvue.DependencyCycle;
-import org.onlab.jdvue.JavaPackage;
-
-import java.util.Arrays;
-
-import static org.junit.Assert.*;
-
-/**
- * Unit test for the dependency cycle entity.
- *
- * @author Thomas Vachuska
- */
-public class DependencyCycleTest {
-
- @Test
- public void normalize() {
- JavaPackage x = new JavaPackage("x");
- JavaPackage y = new JavaPackage("y");
- JavaPackage z = new JavaPackage("z");
-
- DependencyCycle a = new DependencyCycle(Arrays.asList(new JavaPackage[] {x, y, z}), x);
- DependencyCycle b = new DependencyCycle(Arrays.asList(new JavaPackage[] {y, z, x}), y);
- DependencyCycle c = new DependencyCycle(Arrays.asList(new JavaPackage[] {z, x, y}), z);
-
- assertEquals("incorrect normalization", a, b);
- assertEquals("incorrect normalization", a, c);
- }
-
- @Test
- public void testToString() {
- JavaPackage x = new JavaPackage("x");
- JavaPackage y = new JavaPackage("y");
- JavaPackage z = new JavaPackage("z");
-
- DependencyCycle a = new DependencyCycle(Arrays.asList(new JavaPackage[] {x, y, z}), x);
- assertEquals("incorrect toString", "[x, y, z]", a.toShortString());
- assertEquals("incorrect toString",
- "DependencyCycle{cycle=[" +
- "JavaPackage{name=x, sources=0, dependencies=0}, " +
- "JavaPackage{name=y, sources=0, dependencies=0}, " +
- "JavaPackage{name=z, sources=0, dependencies=0}]}",
- a.toString());
- }
-}
diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java
deleted file mode 100644
index 94740dae..00000000
--- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-import org.onlab.jdvue.Dependency;
-import org.onlab.jdvue.JavaPackage;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-/**
- * Unit test for the dependency entity.
- *
- * @author Thomas Vachuska
- */
-public class DependencyTest {
-
- @Test
- public void basics() {
- JavaPackage x = new JavaPackage("x");
- JavaPackage y = new JavaPackage("y");
-
- new EqualsTester()
- .addEqualityGroup(new Dependency(x, y), new Dependency(x, y))
- .addEqualityGroup(new Dependency(y, x), new Dependency(y, x))
- .testEquals();
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java b/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java
deleted file mode 100644
index 0937c068..00000000
--- a/framework/src/onos/utils/jdvue/src/test/java/org/onlab/jdvue/DependencyViewerTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.jdvue;
-
-import org.junit.Test;
-import org.onlab.jdvue.DependencyViewer;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.onlab.jdvue.DependencyViewer.slurp;
-
-/**
- * Unit test for the dependency viewer.
- *
- * @author Thomas Vachuska
- */
-public class DependencyViewerTest {
-
- @Test
- public void basics() throws IOException {
- DependencyViewer.main(new String[]{"src/test/resources/catalog"});
-
- String expected = slurp(new FileInputStream("src/test/resources/expected.html"));
- String actual = slurp(new FileInputStream("src/test/resources/catalog.html"));
-
- // FIXME: add more manageable assertions here
-// assertEquals("incorrect html", expected, actual);
- }
-
-}
diff --git a/framework/src/onos/utils/jdvue/src/test/resources/catalog.db b/framework/src/onos/utils/jdvue/src/test/resources/catalog.db
deleted file mode 100644
index 156eeec9..00000000
--- a/framework/src/onos/utils/jdvue/src/test/resources/catalog.db
+++ /dev/null
@@ -1,33 +0,0 @@
-src/main/java/a/A.java:package a;
-src/main/java/a/A.java:import b.B;
-src/main/java/a/A2.java:package a;
-src/main/java/a/A2.java:import c.C;
-src/main/java/b/B.java:package b;
-src/main/java/b/B.java:import c.C;
-src/main/java/c/C.java:package c;
-
-src/main/java/x/X.java:package x;
-src/main/java/x/X.java:import y.Y;
-src/main/java/y/Y.java:package y;
-src/main/java/y/Y.java:import z.Z;
-src/main/java/z/Z.java:package z;
-src/main/java/z/Z.java:import x.X;
-
-src/main/java/u/U.java:package u;
-src/main/java/u/U.java:import v.V;
-src/main/java/u/U2.java:package u;
-src/main/java/u/U2.java:import v.V;
-src/main/java/v/V.java:package v;
-src/main/java/v/V.java:import u.U;
-
-src/main/java/k/K.java:package k;
-src/main/java/k/K.java:import l.L;
-src/main/java/l/L.java:package l;
-src/main/java/l/L.java:import k.K;
-src/main/java/l/L.java:import m.M;
-src/main/java/l/L.java:import n.N;
-src/main/java/m/M.java:package m;
-src/main/java/m/M.java:import n.N;
-src/main/java/n/N.java:package n;
-src/main/java/n/N.java:import k.K;
-
diff --git a/framework/src/onos/utils/jdvue/src/test/resources/catalog.html b/framework/src/onos/utils/jdvue/src/test/resources/catalog.html
deleted file mode 100644
index f3813596..00000000
--- a/framework/src/onos/utils/jdvue/src/test/resources/catalog.html
+++ /dev/null
@@ -1,376 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>src/test/resources/catalog</title>
- <style>
-
- .node {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- fill: #bbb;
- }
-
- .link {
- stroke: steelblue;
- stroke-opacity: .4;
- fill: none;
- pointer-events: none;
- }
-
- .node--focus {
- font-weight: 700;
- fill: #000;
- }
-
- .node:hover {
- fill: steelblue;
- }
-
- .node:hover,
- .node--source,
- .node--target {
- font-weight: 700;
- }
-
- .node--source {
- fill: #2ca02c;
- }
-
- .node--target {
- fill: #d59800;
- }
-
- .link--source,
- .link--target {
- stroke-opacity: 1;
- stroke-width: 3px;
- }
-
- .link--source {
- stroke: #d59800;
- }
-
- .link--target {
- stroke: #2ca02c;
- }
-
- .link--cycle {
- stroke: #ff0000;
- }
-
- .summary {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 32px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .details {
- display: none;
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 220px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .shown {
- display:block;
- }
-
- .stat {
- text-align: right;
- width: 64px;
- }
-
- .title {
- font-size: 16px;
- font-weight: bold;
- }
-
- #package {
- font-size: 14px;
- font-weight: bold;
- }
- </style>
-</head>
-<body>
- <div class="summary">
- <div class="title">Project src/test/resources/catalog</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="sourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Packages:</td>
- <td id="packageCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="segmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="cycleCount" class="stat"></td>
- </tr>
- </table>
- <div><hr size="1"></div>
- <div><input type="checkbox"> Highlight cycles</input></div>
- <div><input style="width: 95%" type="range" min="0" max="100" value="75"></div>
- </div>
- <div class="details">
- <div id="package">Package Details</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="psourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Dependents:</td>
- <td id="pdependentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="psegmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="pcycleCount" class="stat"></td>
- </tr>
- </table>
- </div>
-<script>
-!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new o;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function y(){Zo.event.preventDefault()}function x(){for(var n,t=Zo.event;n=t.sourceEvent;)t=n;return t}function M(n){for(var t=new d,e=0,r=arguments.length;++e<r;)t[arguments[e]]=m(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Zo.event;u.target=n,Zo.event=u,t[u.type].apply(e,r)}finally{Zo.event=i}}},t}function _(n){return sa(n,pa),n}function b(n){return"function"==typeof n?n:function(){return la(n,this)}}function w(n){return"function"==typeof n?n:function(){return fa(n,this)}}function S(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Zo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function k(n){return n.trim().replace(/\s+/g," ")}function E(n){return new RegExp("(?:^|\\s+)"+Zo.requote(n)+"(?:\\s+|$)","g")}function A(n){return(n+"").trim().split(/^|\s+/)}function C(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=A(n).map(N);var u=n.length;return"function"==typeof t?r:e}function N(n){var t=E(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",k(u+" "+n))):e.setAttribute("class",k(u.replace(t," ")))}}function z(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function L(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function T(n){return"function"==typeof n?n:(n=Zo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function q(n){return{__data__:n}}function R(n){return function(){return ga(this,n)}}function D(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function P(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function H(){var n=this.__transition__;n&&++n.active}function F(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Xo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Zo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=O;a>0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Va=n,e}function zt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*ua(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=ec[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&nc!==Rt,o=new(i?Rt:nc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ot(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Yt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function It(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Vt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.y=$t(+r[0]),e+r[0].length):-1}function Xt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=-t,e+5):-1}function $t(n){return n+(n>68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ue(){}function ie(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function oe(n,t){n&&cc.hasOwnProperty(n.type)&&cc[n.type](n,t)}function ae(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ce(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)ae(n[e],t,1);t.polygonEnd()}function se(){function n(n,t){n*=Aa,t=t*Aa/2+ba/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])<ka&&ua(n[1]-t[1])<ka}function ye(n,t){n*=Aa;var e=Math.cos(t*=Aa);xe(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function xe(n,t,e){++hc,pc+=(n-pc)/hc,vc+=(t-vc)/hc,dc+=(e-dc)/hc}function Me(){function n(n,u){n*=Aa;var i=Math.cos(u*=Aa),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);gc+=s,mc+=s*(t+(t=o)),yc+=s*(e+(e=a)),xc+=s*(r+(r=c)),xe(t,e,r)}var t,e,r;wc.point=function(u,i){u*=Aa;var o=Math.cos(i*=Aa);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),wc.point=n,xe(t,e,r)}}function _e(){wc.point=ye}function be(){function n(n,t){n*=Aa;var e=Math.cos(t*=Aa),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-J(g)/h,v=Math.atan2(h,g);Mc+=p*s,_c+=p*l,bc+=p*f,gc+=v,mc+=v*(r+(r=o)),yc+=v*(u+(u=a)),xc+=v*(i+(i=c)),xe(r,u,i)}var t,e,r,u,i;wc.point=function(o,a){t=o,e=a,wc.point=n,o*=Aa;var c=Math.cos(a*=Aa);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),xe(r,u,i)},wc.lineEnd=function(){n(t,e),wc.lineEnd=_e,wc.point=ye}}function we(){return!0}function Se(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(me(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function Ee(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ae(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)<ka?(n.point(e,r=(r+o)/2>0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)<ka&&(e-=u*ka),ua(i-a)<ka&&(i-=a*ka),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return ua(o)>ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]<t[0]?ba:-ba;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function De(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)<ka,N=C||ka>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)<ka?k:E):k<=_[1]&&_[1]<=E:A>ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)<ka?u>0?0:3:ua(r[0]-e)<ka?u>0?2:1:ua(r[1]-t)<ka?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)<ka||ua(r-h)<ka?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;(T*T/M>i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16;
- return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)<ka?rr:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-B(u)*Math.sqrt(n*n+e*e)]},e)}function Mr(n,t){return[n,Math.log(Math.tan(ba/4+t/2))]}function _r(n){var t,e=nr(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=ba*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function br(n,t){return[Math.log(Math.tan(ba/4+t/2)),-n]}function wr(n){return n[0]}function Sr(n){return n[1]}function kr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)<ka&&ua(r-c.circle.cy)<ka;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Yr(c);for(var s=o;s.circle&&ua(e-s.circle.x)<ka&&ua(r-s.circle.cy)<ka;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Yr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)<ka&&p-u>ka?{x:f,y:ua(t-f)<ka?e:p}:ua(u-p)<ka&&h-r>ka?{x:ua(e-p)<ka?t:h,y:p}:ua(r-h)<ka&&u-g>ka?{x:h,y:ua(t-h)<ka?e:g}:ua(u-g)<ka&&r-f>ka?{x:ua(e-g)<ka?t:f,y:g}:null),i.site,null)),++c)}function Hr(n,t){return t.angle-n.angle}function Fr(){Gr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Or(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}$c.insert(y,m),y||(Xc=m)}}}}function Yr(n){var t=n.circle;t&&(t.P||(Xc=t.N),$c.remove(t),Wc.push(t),Gr(t),n.circle=null)}function Ir(n){for(var t,e=Ic,r=Pe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Zr(t,n)||!r(t)||ua(t.a.x-t.b.x)<ka&&ua(t.a.y-t.b.y)<ka)&&(t.a=t.b=null,e.splice(u,1))}function Zr(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Vr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Xr(n,t,e,r){var u=new Vr(n,t);return Ic.push(u),e&&Br(u,n,t,e),r&&Br(u,t,n,r),Zc[n.i].edges.push(new Wr(u,n,t)),Zc[t.i].edges.push(new Wr(u,t,n)),u}function $r(n,t,e){var r=new Vr(n,null);return r.a=t,r.b=e,Ic.push(r),r}function Br(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Wr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Jr(){this._=null}function Gr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Kr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Qr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function nu(n){for(;n.L;)n=n.L;return n}function tu(n,t){var e,r,u,i=n.sort(eu).pop();for(Ic=[],Zc=new Array(n.length),Vc=new Jr,$c=new Jr;;)if(u=Xc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Zc[i.i]=new Ur(i),Rr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Ir(t),jr(t));var o={cells:Zc,edges:Ic};return Vc=$c=Ic=Zc=null,o}function eu(n,t){return t.y-n.y||t.x-n.x}function ru(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function uu(n){return n.x}function iu(n){return n.y}function ou(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function au(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&au(n,c[0],e,r,o,a),c[1]&&au(n,c[1],o,r,u,a),c[2]&&au(n,c[2],e,a,o,i),c[3]&&au(n,c[3],o,a,u,i)}}function cu(n,t){n=Zo.rgb(n),t=Zo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+dt(Math.round(e+i*n))+dt(Math.round(r+o*n))+dt(Math.round(u+a*n))}}function su(n,t){var e,r={},u={};for(e in n)e in t?r[e]=hu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function lu(n,t){return t-=n=+n,function(e){return n+t*e}}function fu(n,t){var e,r,u,i=Gc.lastIndex=Kc.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=Gc.exec(n))&&(r=Kc.exec(t));)(u=r.index)>i&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return i<t.length&&(u=t.substring(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Ca,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ca:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Ru(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Du(n,t){var e,r=[],u=[],i=Zo.transform(n),o=Zo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:lu(a[0],c[0])},{i:3,x:lu(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function ju(n){for(var t=n.source,e=n.target,r=Fu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Hu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Fu(n,t){if(n===t)return n;for(var e=Hu(n),r=Hu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Ou(n){n.fixed|=2}function Yu(n){n.fixed&=-7}function Iu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Zu(n){n.fixed&=-5}function Vu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Vu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Xu(n,t){return Zo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Ku,n}function $u(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Wu(n){return n.children}function Ju(n){return n.value}function Gu(n,t){return t.value-n.value}function Ku(n){return Zo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Qu(n){return n.x}function ni(n){return n.y}function ti(n,t,e){n.y0=t,n.y=e}function ei(n){return Zo.range(n.length)}function ri(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ui(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?hi(r,u=a):hi(r=c,u),o--):(fi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)mi(u[i],t,e,r)}function yi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function xi(n,t){return n.parent==t.parent?1:2}function Mi(n){var t=n.children;return t.length?t[0]:n.t}function _i(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function bi(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function wi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Zo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ui(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++a<c;)u.has(i=r[a])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,a=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,o){arguments.length<2&&(o=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+o);return i=r(n.length<2?(c+s)/2:c+l*o/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-o+2*c);return i=r(l+h*c,h),s&&i.reverse(),a=h*(1-o),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-o+2*c)),g=f-l-(n.length-o)*h;return i=r(l+Math.round(g/2),h),s&&i.reverse(),a=Math.round(h*(1-o)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return Bi(n,t)},e.domain(n)}function Wi(e,r){function u(){var n=0,t=r.length;for(o=[];++n<t;)o[n-1]=Zo.quantile(e,n/t);return i}function i(n){return isNaN(n=+n)?void 0:r[Zo.bisect(o,n)]}var o;return i.domain=function(r){return arguments.length?(e=r.filter(t).sort(n),u()):e},i.range=function(n){return arguments.length?(r=n,u()):r},i.quantiles=function(){return o},i.invertExtent=function(n){return n=r.indexOf(n),0>n?[0/0,0/0]:[n>0?o[n-1]:e[0],n<o.length?o[n]:e[e.length-1]]},i.copy=function(){return Wi(e,r)},u()}function Ji(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=wr,r=Sr,u=we,i=uo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=xs.get(n)||uo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function uo(n){return n.join("L")}function io(n){return uo(n)+"Z"}function oo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function so(n,t){return n.length<4?uo(n):n[1]+ho(n.slice(1,n.length-1),go(n,t))}function lo(n,t){return n.length<3?uo(n):n[0]+ho((n.push(n[0]),n),go([n[n.length-2]].concat(n,[n[1]]),t))}function fo(n,t){return n.length<3?uo(n):n[0]+ho(n,go(n,t))}function ho(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return uo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function go(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function po(n){if(n.length<3)return uo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",xo(bs,o),",",xo(bs,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Mo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function vo(n){if(n.length<4)return uo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(xo(bs,i)+","+xo(bs,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Mo(e,i,o);return e.join("")}function mo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[xo(bs,o),",",xo(bs,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Mo(t,o,a);return t.join("")}function yo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return po(n)}function xo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Mo(n,t,e){n.push("C",xo(Ms,t),",",xo(Ms,e),",",xo(_s,t),",",xo(_s,e),",",xo(bs,t),",",xo(bs,e))}function _o(n,t){return(t[1]-n[1])/(t[0]-n[0])}function bo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=_o(u,i);++t<e;)r[t]=(o+(o=_o(u=i,i=n[t+1])))/2;return r[t]=o,r}function wo(n){for(var t,e,r,u,i=[],o=bo(n),a=-1,c=n.length-1;++a<c;)t=_o(n[a],n[a+1]),ua(t)<ka?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ms,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Eo(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=bt(e),_=bt(u),b=e===r?function(){return g}:bt(r),w=u===i?function(){return p}:bt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=wr,r=wr,u=0,i=Sr,o=we,a=uo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=xs.get(n)||uo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Ao(n){return n.radius}function Co(n){return[n.x,n.y]}function No(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ms;return[e*Math.cos(r),e*Math.sin(r)]}}function zo(){return 64}function Lo(){return"circle"}function To(n){var t=Math.sqrt(n/ba);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function qo(n,t){return sa(n,Cs),n.id=t,n}function Ro(n,t,e,r){var u=n.id;return P(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Do(n){return null==n&&(n=""),function(){this.textContent=n}}function Po(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var a=r.time;i=u[e]={tween:new o,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Zo.timer(function(r){function o(r){return u.active>e?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);
- return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]<Us[i]/u?i-1:i]:[Fs,Fi(n,e)[2]]}return r.invert=function(t){return Oo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Oo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Oo(+e+1),t).length}var i=r.domain(),o=Li(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Ri(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Zo.mean=function(n,e){var r,u=0,i=n.length,o=-1,a=i;if(1===arguments.length)for(;++o<i;)t(r=n[o])?u+=r:--a;else for(;++o<i;)t(r=e.call(n,n[o],o))?u+=r:--a;return a?u/a:void 0},Zo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Zo.median=function(e,r){return arguments.length>1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n<t;)for(var u,i=-1,o=e[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return e},Zo.transpose=function(n){return Zo.zip.apply(Zo,n)},Zo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Zo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Zo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Zo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)<t;)i.push(r/o);return i},Zo.map=function(n){var t=new o;if(n instanceof o)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},i(o,{has:a,get:function(n){return this[ia+n]},set:function(n,t){return this[ia+n]=t},remove:c,keys:s,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1),this[t])}});var ia="\x00",oa=ia.charCodeAt(0);Zo.nest=function(){function n(t,a,c){if(c>=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=g(n,t,t[e]);return n};var aa=["webkit","ms","moz","Moz","o","O"];Zo.dispatch=function(){for(var n=new d,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=m(n);return n},d.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return _(i)},pa.selectAll=function(n){var t,e,r=[];n=w(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Xo(n.call(e,e.__data__,a,u))),t.parentNode=e);return _(r)};var va={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Zo.ns={prefix:va,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!E(n[u]).test(t))return!1;return!0}for(t in n)this.each(C(t,n[t]));return this}return this.each(C(n,t))},pa.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++r<a;)d=t.call(u=n[r],u.__data__,r),m.has(d)?v[r]=u:m.set(d,u),x.push(d);for(r=-1;++r<f;)d=t.call(e,i=e[r],r),(u=m.get(d))?(g[r]=u,u.__data__=i):y.has(d)||(p[r]=q(i)),y.set(d,i),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=q(i);for(;f>r;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i<a;)(u=r[i])&&(n[i]=u.__data__);return n}var c=U([]),s=_([]),l=_([]);if("function"==typeof n)for(;++i<a;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<a;)e(r=this[i],n);return s.enter=function(){return c},s.exit=function(){return l},s},pa.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},pa.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},pa.each=function(n){return P(this,function(t,e,r){n.call(t,t.__data__,e,r)})},pa.call=function(n){var t=Xo(arguments);return n.apply(t[0]=this,t),this},pa.empty=function(){return!this.node()},pa.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return _(o)},da.insert=function(n,t){return arguments.length<2&&(t=j(this)),pa.insert.call(this,n,t)},pa.transition=function(){for(var n,t,e=Ss||++Ns,r=[],u=ks||{time:Date.now(),ease:xu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&Po(t,c,e,u),n.push(t)}return qo(r,e)},pa.interrupt=function(){return this.each(H)},Zo.select=function(n){var t=["string"==typeof n?la(n,$o):n];return t.parentNode=Bo,_([t])},Zo.selectAll=function(n){var t=Xo("string"==typeof n?fa(n,$o):n);return t.parentNode=Bo,_([t])};var ma=Zo.select(Bo);pa.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)oe(e[r].geometry,t)}},cc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){ae(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t,0)},Polygon:function(n,t){ce(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ce(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)oe(e[r],t)}};Zo.geo.area=function(n){return sc=0,Zo.geo.stream(n,fc),sc};var sc,lc=new ue,fc={sphere:function(){sc+=4*ba},point:v,lineStart:v,lineEnd:v,polygonStart:function(){lc.reset(),fc.lineStart=se},polygonEnd:function(){var n=2*lc;sc+=0>n?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,fc.polygonStart()},polygonEnd:function(){fc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>lc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);
- for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=wr,r=Sr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Zo.geom.polygon=function(n){return sa(n,Yc),n};var Yc=Zo.geom.polygon.prototype=[];Yc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Yc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Yc.clip=function(n){for(var t,e,r,u,i,o,a=Nr(n),c=-1,s=this.length-Nr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Ar(o,l,u)?(Ar(i,l,u)||n.push(Cr(i,o,l,u)),n.push(o)):Ar(i,l,u)&&n.push(Cr(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Ic,Zc,Vc,Xc,$c,Bc=[],Wc=[];Ur.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Hr),t.length},Wr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Jr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=nu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Qr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Qr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?nu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Qr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Kr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Qr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Kr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Qr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Zo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return tu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&ru(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=bt(r=n),t):r},t.y=function(n){return arguments.length?(o=bt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Jc:n,t):a===Jc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Jc?null:a&&a[1]},t)};var Jc=[[-1e6,-1e6],[1e6,1e6]];Zo.geom.delaunay=function(n){return Zo.geom.voronoi().triangles(n)},Zo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(ua(c-e)+ua(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=wr,c=Sr;return(o=arguments.length)?(a=uu,c=iu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Zo.interpolateRgb=cu,Zo.interpolateObject=su,Zo.interpolateNumber=lu,Zo.interpolateString=fu;var Gc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Kc=new RegExp(Gc.source,"g");Zo.interpolate=hu,Zo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ia.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cu:fu:t instanceof et?cu:Array.isArray(t)?gu:"object"===e&&isNaN(t)?su:lu)(n,t)}],Zo.interpolateArray=gu;var Qc=function(){return wt},ns=Zo.map({linear:Qc,poly:Mu,quad:function(){return mu},cubic:function(){return yu},sin:function(){return _u},exp:function(){return bu},circle:function(){return wu},elastic:Su,back:ku,bounce:function(){return Eu}}),ts=Zo.map({"in":wt,out:vu,"in-out":du,"out-in":function(n){return du(vu(n))}});Zo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(ju(n[e]));return t}},Zo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Zo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Zo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(wa-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Zo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Zo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Xu(e,r)},Zo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Zo.sum(o),s=Zo.range(i.length);null!=e&&s.sort(e===os?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=os,r=0,u=wa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var os={};Zo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Zo.permute(s,f),l=Zo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Zo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ni,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ni(t):zi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return zi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ni:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Xu(i,a)},Zo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);
- return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),Po(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return qo(i,u)},Cs.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=w(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&Po(u,g,o,i),t.push(u)}return qo(a,o)},Cs.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]<x[0])],z[1]=f[+(n[1]<x[1])]):x=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Ti(t),c=a[0],s=a[1],p=z[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}();
-
-
- var catalog =
-{"packages":[{"name":"a","size":2,"imports":["b","c"],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"b","size":1,"imports":["c"],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"c","size":1,"imports":[],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"u","size":2,"imports":["v"],"cycleSegments":{"u-v":{"s":"v","t":"u"},"v-u":{"s":"u","t":"v"}},"cycleCount":1,"cycleSegmentCount":2},{"name":"v","size":1,"imports":["u"],"cycleSegments":{"u-v":{"s":"v","t":"u"},"v-u":{"s":"u","t":"v"}},"cycleCount":1,"cycleSegmentCount":2},{"name":"x","size":1,"imports":["y"],"cycleSegments":{"y-x":{"s":"x","t":"y"},"z-y":{"s":"y","t":"z"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3},{"name":"y","size":1,"imports":["z"],"cycleSegments":{"y-x":{"s":"x","t":"y"},"z-y":{"s":"y","t":"z"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3},{"name":"z","size":1,"imports":["x"],"cycleSegments":{"y-x":{"s":"x","t":"y"},"z-y":{"s":"y","t":"z"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3},{"name":"k","size":1,"imports":["l"],"cycleSegments":{"k-l":{"s":"l","t":"k"},"l-k":{"s":"k","t":"l"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"n-l":{"s":"l","t":"n"},"k-n":{"s":"n","t":"k"}},"cycleCount":3,"cycleSegmentCount":6},{"name":"l","size":1,"imports":["k","m","n"],"cycleSegments":{"k-l":{"s":"l","t":"k"},"l-k":{"s":"k","t":"l"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"n-l":{"s":"l","t":"n"},"k-n":{"s":"n","t":"k"}},"cycleCount":3,"cycleSegmentCount":6},{"name":"m","size":1,"imports":["n"],"cycleSegments":{"l-k":{"s":"k","t":"l"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"k-n":{"s":"n","t":"k"}},"cycleCount":1,"cycleSegmentCount":4},{"name":"n","size":1,"imports":["k"],"cycleSegments":{"l-k":{"s":"k","t":"l"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"n-l":{"s":"l","t":"n"},"k-n":{"s":"n","t":"k"}},"cycleCount":2,"cycleSegmentCount":5}],"cycleSegments":{"u-v":{"s":"v","t":"u"},"k-l":{"s":"l","t":"k"},"v-u":{"s":"u","t":"v"},"l-k":{"s":"k","t":"l"},"y-x":{"s":"x","t":"y"},"z-y":{"s":"y","t":"z"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"n-l":{"s":"l","t":"n"},"k-n":{"s":"n","t":"k"},"x-z":{"s":"z","t":"x"}},"summary":{"packages":12,"sources":14,"cycles":5,"cycleSegments":11}}
- ;
-
- var diameter = 1000,
- radius = diameter / 2,
- innerRadius = radius - 300;
-
- var cluster = d3.layout.cluster()
- .size([360, innerRadius])
- .sort(null)
- .value(function(d) { return d.size; });
-
- var bundle = d3.layout.bundle();
-
- var line = d3.svg.line.radial()
- .interpolate("bundle")
- .tension(.75)
- .radius(function(d) { return d.y; })
- .angle(function(d) { return d.x / 180 * Math.PI; });
-
- var svg = d3.select("body").append("svg")
- .attr("width", diameter)
- .attr("height", diameter)
- .append("g")
- .attr("transform", "translate(" + radius + "," + radius + ")");
-
- var link = svg.append("g").selectAll(".link"),
- node = svg.append("g").selectAll(".node"),
- cycles = {}, highlightCycles, selectedNode;
-
- function isCyclicLink(l) {
- return highlightCycles &&
- (cycles[l.source.key + "-" + l.target.key] || cycles[l.target.key + "-" + l.source.key]);
- }
-
- function isCyclicPackageLink(l, p) {
- var key = l.source.key + "-" + l.target.key,
- rKey = l.target.key + "-" + l.source.key;
- return isCyclicLink(l) && (p.cycleSegments[key] || p.cycleSegments[rKey]);
- }
-
- function refreshPaths() {
- svg.selectAll("path.link").classed("link--cycle", isCyclicLink);
- }
-
- function processCatalog() {
- var nodes = cluster.nodes(packageHierarchy(catalog.packages)),
- links = packageImports(nodes),
- splines = bundle(links);
- cycles = catalog.cycleSegments;
-
- d3.select("input[type=checkbox]").on("change", function() {
- highlightCycles = this.checked;
- refreshPaths();
- });
-
- link = link
- .data(splines)
- .enter().append("path")
- .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
- .attr("class", "link")
- .classed("link--cycle", isCyclicLink)
- .attr("d", function(d, i) { return line(splines[i]); });
-
-
- node = node
- .data(nodes.filter(function(n) { return !n.children; }))
- .enter().append("text")
- .attr("class", "node")
- .attr("dy", ".31em")
- .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
- .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
- .text(function(d) { return d.key; })
- .on("focus", processSelect)
- .on("blur", processSelect);
-
- d3.select("input[type=range]").on("change", function() {
- line.tension(this.value / 100);
- svg.selectAll("path.link")
- .data(splines)
- .attr("d", function(d, i) { return line(splines[i]); });
- });
-
- d3.select("#packageCount").text(catalog.summary.packages);
- d3.select("#sourceCount").text(catalog.summary.sources);
- d3.select("#segmentCount").text(catalog.summary.cycleSegments);
- d3.select("#cycleCount").text(catalog.summary.cycles);
- }
-
- function processSelect(d) {
- if (selectedNode === d) {
- deselected(d);
- selectedNode = null;
-
- } else if (selectedNode) {
- deselected(selectedNode);
- selectedNode = null;
- selected(d);
-
- } else {
- selected(d);
- selectedNode = d;
- }
- }
-
- function selected(d) {
- node
- .each(function(n) { n.target = n.source = false; })
- .classed("node--focus", function(n) { return n === d; });
-
- link
- .classed("link--cycle", function(l) { return isCyclicPackageLink(l, d); })
- .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
- .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
- .filter(function(l) { return l.target === d || l.source === d; })
- .each(function() { this.parentNode.appendChild(this); });
-
- node
- .classed("node--target", function(n) { return n.target; })
- .classed("node--source", function(n) { return n.source; });
-
- d3.select("#psourceCount").text(d.size);
- d3.select("#pdependentCount").text(d.imports.length);
- d3.select("#psegmentCount").text(d.cycleSegmentCount);
- d3.select("#pcycleCount").text(d.cycleCount);
- d3.select(".details").classed("shown", function() { return true; });
- }
-
- function deselected(d) {
- link
- .classed("link--cycle", isCyclicLink)
- .classed("link--target", false)
- .classed("link--source", false);
-
- node
- .classed("node--target", false)
- .classed("node--source", false)
- .classed("node--focus", false);
- d3.select(".details").classed("shown", function() { return false; });
- }
-
- d3.select(self.frameElement).style("height", diameter + "px");
-
- // Lazily construct the package hierarchy.
- function packageHierarchy(packages) {
- var map = {}, cnt = 0;
-
- // Builds the structure top-down to the specified leaf or until
- // another leaf in which case hook this leaf to the same parent
- function buildHierarchy(leaf, i) {
- var leafName = leaf.name,
- node, name, parent = map[""], start = 0;
- while (start < leafName.length) {
- name = parentName(leafName, start);
- node = map[name];
- if (!node) {
- node = map[name] = parentNode(name, parent);
- parent.children.push(node);
-
- } else if (node.imports) {
- leaf.parent = parent;
- parent.children.push(leaf);
- break;
- }
- parent = node;
- start = name.length + 1;
- }
- }
-
- function parentNode(name, parent) {
- return {name: name, parent: parent, key: name, children: []};
- }
-
- function parentName(leafName, start) {
- var i = leafName.indexOf(".", start);
- return i > 0 ? leafName.substring(0, i) : leafName;
- }
-
- // First populate all packages as leafs
- packages.forEach(function(d) {
- map[d.name] = d;
- d.key = d.name;
- });
-
- // Next synthesize the intermediate structure, by-passing any leafs
- map[""] = parentNode("", null);
- var i = 0;
- packages.forEach(function(d) {
- buildHierarchy(d, i++);
- });
-
- return map[""];
- }
-
- // Return a list of imports for the given array of nodes.
- function packageImports(nodes) {
- var map = {},
- imports = [];
-
- // Compute a map from name to node.
- nodes.forEach(function(d) {
- map[d.name] = d;
- });
-
- // For each import, construct a link from the source to target node.
- nodes.forEach(function(d) {
- if (d.imports) d.imports.forEach(function(i) {
- imports.push({source: map[d.name], target: map[i]});
- });
- });
-
- return imports;
- }
-
- processCatalog();
-</script>
-</body>
-</html>
diff --git a/framework/src/onos/utils/jdvue/src/test/resources/expected.html b/framework/src/onos/utils/jdvue/src/test/resources/expected.html
deleted file mode 100644
index a98573e9..00000000
--- a/framework/src/onos/utils/jdvue/src/test/resources/expected.html
+++ /dev/null
@@ -1,376 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>src/test/resources/catalog</title>
- <style>
-
- .node {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- fill: #bbb;
- }
-
- .link {
- stroke: steelblue;
- stroke-opacity: .4;
- fill: none;
- pointer-events: none;
- }
-
- .node--focus {
- font-weight: 700;
- fill: #000;
- }
-
- .node:hover {
- fill: steelblue;
- }
-
- .node:hover,
- .node--source,
- .node--target {
- font-weight: 700;
- }
-
- .node--source {
- fill: #2ca02c;
- }
-
- .node--target {
- fill: #d59800;
- }
-
- .link--source,
- .link--target {
- stroke-opacity: 1;
- stroke-width: 3px;
- }
-
- .link--source {
- stroke: #d59800;
- }
-
- .link--target {
- stroke: #2ca02c;
- }
-
- .link--cycle {
- stroke: #ff0000;
- }
-
- .summary {
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 32px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .details {
- display: none;
- font: 300 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
- position: fixed;
- top: 220px;
- right: 32px;
- width: 192px;
- background-color: #ffffff;
- box-shadow: 2px 2px 4px 2px #777777;
- padding: 5px;
- }
-
- .shown {
- display:block;
- }
-
- .stat {
- text-align: right;
- width: 64px;
- }
-
- .title {
- font-size: 16px;
- font-weight: bold;
- }
-
- #package {
- font-size: 14px;
- font-weight: bold;
- }
- </style>
-</head>
-<body>
- <div class="summary">
- <div class="title">Project src/test/resources/catalog</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="sourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Packages:</td>
- <td id="packageCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="segmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="cycleCount" class="stat"></td>
- </tr>
- </table>
- <div><hr size="1"></div>
- <div><input type="checkbox"> Highlight cycles</input></div>
- <div><input style="width: 95%" type="range" min="0" max="100" value="75"></div>
- </div>
- <div class="details">
- <div id="package">Package Details</div>
- <table>
- <tr>
- <td>Sources:</td>
- <td id="psourceCount" class="stat"></td>
- </tr>
- <tr>
- <td>Dependents:</td>
- <td id="pdependentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cyclic Segments:</td>
- <td id="psegmentCount" class="stat"></td>
- </tr>
- <tr>
- <td>Cycles:</td>
- <td id="pcycleCount" class="stat"></td>
- </tr>
- </table>
- </div>
-<script>
-!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new o;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function y(){Zo.event.preventDefault()}function x(){for(var n,t=Zo.event;n=t.sourceEvent;)t=n;return t}function M(n){for(var t=new d,e=0,r=arguments.length;++e<r;)t[arguments[e]]=m(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Zo.event;u.target=n,Zo.event=u,t[u.type].apply(e,r)}finally{Zo.event=i}}},t}function _(n){return sa(n,pa),n}function b(n){return"function"==typeof n?n:function(){return la(n,this)}}function w(n){return"function"==typeof n?n:function(){return fa(n,this)}}function S(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Zo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function k(n){return n.trim().replace(/\s+/g," ")}function E(n){return new RegExp("(?:^|\\s+)"+Zo.requote(n)+"(?:\\s+|$)","g")}function A(n){return(n+"").trim().split(/^|\s+/)}function C(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=A(n).map(N);var u=n.length;return"function"==typeof t?r:e}function N(n){var t=E(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",k(u+" "+n))):e.setAttribute("class",k(u.replace(t," ")))}}function z(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function L(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function T(n){return"function"==typeof n?n:(n=Zo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function q(n){return{__data__:n}}function R(n){return function(){return ga(this,n)}}function D(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function P(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function H(){var n=this.__transition__;n&&++n.active}function F(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Xo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Zo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=O;a>0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Va=n,e}function zt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*ua(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=ec[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&nc!==Rt,o=new(i?Rt:nc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ot(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Yt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function It(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Vt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.y=$t(+r[0]),e+r[0].length):-1}function Xt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=-t,e+5):-1}function $t(n){return n+(n>68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ue(){}function ie(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function oe(n,t){n&&cc.hasOwnProperty(n.type)&&cc[n.type](n,t)}function ae(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ce(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)ae(n[e],t,1);t.polygonEnd()}function se(){function n(n,t){n*=Aa,t=t*Aa/2+ba/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])<ka&&ua(n[1]-t[1])<ka}function ye(n,t){n*=Aa;var e=Math.cos(t*=Aa);xe(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function xe(n,t,e){++hc,pc+=(n-pc)/hc,vc+=(t-vc)/hc,dc+=(e-dc)/hc}function Me(){function n(n,u){n*=Aa;var i=Math.cos(u*=Aa),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);gc+=s,mc+=s*(t+(t=o)),yc+=s*(e+(e=a)),xc+=s*(r+(r=c)),xe(t,e,r)}var t,e,r;wc.point=function(u,i){u*=Aa;var o=Math.cos(i*=Aa);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),wc.point=n,xe(t,e,r)}}function _e(){wc.point=ye}function be(){function n(n,t){n*=Aa;var e=Math.cos(t*=Aa),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-J(g)/h,v=Math.atan2(h,g);Mc+=p*s,_c+=p*l,bc+=p*f,gc+=v,mc+=v*(r+(r=o)),yc+=v*(u+(u=a)),xc+=v*(i+(i=c)),xe(r,u,i)}var t,e,r,u,i;wc.point=function(o,a){t=o,e=a,wc.point=n,o*=Aa;var c=Math.cos(a*=Aa);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),xe(r,u,i)},wc.lineEnd=function(){n(t,e),wc.lineEnd=_e,wc.point=ye}}function we(){return!0}function Se(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(me(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function Ee(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ae(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)<ka?(n.point(e,r=(r+o)/2>0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)<ka&&(e-=u*ka),ua(i-a)<ka&&(i-=a*ka),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return ua(o)>ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]<t[0]?ba:-ba;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function De(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)<ka,N=C||ka>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)<ka?k:E):k<=_[1]&&_[1]<=E:A>ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)<ka?u>0?0:3:ua(r[0]-e)<ka?u>0?2:1:ua(r[1]-t)<ka?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)<ka||ua(r-h)<ka?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;(T*T/M>i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16;
- return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)<ka?rr:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-B(u)*Math.sqrt(n*n+e*e)]},e)}function Mr(n,t){return[n,Math.log(Math.tan(ba/4+t/2))]}function _r(n){var t,e=nr(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=ba*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function br(n,t){return[Math.log(Math.tan(ba/4+t/2)),-n]}function wr(n){return n[0]}function Sr(n){return n[1]}function kr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)<ka&&ua(r-c.circle.cy)<ka;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Yr(c);for(var s=o;s.circle&&ua(e-s.circle.x)<ka&&ua(r-s.circle.cy)<ka;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Yr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)<ka&&p-u>ka?{x:f,y:ua(t-f)<ka?e:p}:ua(u-p)<ka&&h-r>ka?{x:ua(e-p)<ka?t:h,y:p}:ua(r-h)<ka&&u-g>ka?{x:h,y:ua(t-h)<ka?e:g}:ua(u-g)<ka&&r-f>ka?{x:ua(e-g)<ka?t:f,y:g}:null),i.site,null)),++c)}function Hr(n,t){return t.angle-n.angle}function Fr(){Gr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Or(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}$c.insert(y,m),y||(Xc=m)}}}}function Yr(n){var t=n.circle;t&&(t.P||(Xc=t.N),$c.remove(t),Wc.push(t),Gr(t),n.circle=null)}function Ir(n){for(var t,e=Ic,r=Pe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Zr(t,n)||!r(t)||ua(t.a.x-t.b.x)<ka&&ua(t.a.y-t.b.y)<ka)&&(t.a=t.b=null,e.splice(u,1))}function Zr(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Vr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Xr(n,t,e,r){var u=new Vr(n,t);return Ic.push(u),e&&Br(u,n,t,e),r&&Br(u,t,n,r),Zc[n.i].edges.push(new Wr(u,n,t)),Zc[t.i].edges.push(new Wr(u,t,n)),u}function $r(n,t,e){var r=new Vr(n,null);return r.a=t,r.b=e,Ic.push(r),r}function Br(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Wr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Jr(){this._=null}function Gr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Kr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Qr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function nu(n){for(;n.L;)n=n.L;return n}function tu(n,t){var e,r,u,i=n.sort(eu).pop();for(Ic=[],Zc=new Array(n.length),Vc=new Jr,$c=new Jr;;)if(u=Xc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Zc[i.i]=new Ur(i),Rr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Ir(t),jr(t));var o={cells:Zc,edges:Ic};return Vc=$c=Ic=Zc=null,o}function eu(n,t){return t.y-n.y||t.x-n.x}function ru(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function uu(n){return n.x}function iu(n){return n.y}function ou(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function au(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&au(n,c[0],e,r,o,a),c[1]&&au(n,c[1],o,r,u,a),c[2]&&au(n,c[2],e,a,o,i),c[3]&&au(n,c[3],o,a,u,i)}}function cu(n,t){n=Zo.rgb(n),t=Zo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+dt(Math.round(e+i*n))+dt(Math.round(r+o*n))+dt(Math.round(u+a*n))}}function su(n,t){var e,r={},u={};for(e in n)e in t?r[e]=hu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function lu(n,t){return t-=n=+n,function(e){return n+t*e}}function fu(n,t){var e,r,u,i=Gc.lastIndex=Kc.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=Gc.exec(n))&&(r=Kc.exec(t));)(u=r.index)>i&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return i<t.length&&(u=t.substring(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Ca,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ca:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Ru(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Du(n,t){var e,r=[],u=[],i=Zo.transform(n),o=Zo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:lu(a[0],c[0])},{i:3,x:lu(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function ju(n){for(var t=n.source,e=n.target,r=Fu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Hu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Fu(n,t){if(n===t)return n;for(var e=Hu(n),r=Hu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Ou(n){n.fixed|=2}function Yu(n){n.fixed&=-7}function Iu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Zu(n){n.fixed&=-5}function Vu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Vu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Xu(n,t){return Zo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Ku,n}function $u(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Wu(n){return n.children}function Ju(n){return n.value}function Gu(n,t){return t.value-n.value}function Ku(n){return Zo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Qu(n){return n.x}function ni(n){return n.y}function ti(n,t,e){n.y0=t,n.y=e}function ei(n){return Zo.range(n.length)}function ri(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ui(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?hi(r,u=a):hi(r=c,u),o--):(fi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)mi(u[i],t,e,r)}function yi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function xi(n,t){return n.parent==t.parent?1:2}function Mi(n){var t=n.children;return t.length?t[0]:n.t}function _i(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function bi(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function wi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Zo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ui(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++a<c;)u.has(i=r[a])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,a=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,o){arguments.length<2&&(o=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+o);return i=r(n.length<2?(c+s)/2:c+l*o/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-o+2*c);return i=r(l+h*c,h),s&&i.reverse(),a=h*(1-o),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-o+2*c)),g=f-l-(n.length-o)*h;return i=r(l+Math.round(g/2),h),s&&i.reverse(),a=Math.round(h*(1-o)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return Bi(n,t)},e.domain(n)}function Wi(e,r){function u(){var n=0,t=r.length;for(o=[];++n<t;)o[n-1]=Zo.quantile(e,n/t);return i}function i(n){return isNaN(n=+n)?void 0:r[Zo.bisect(o,n)]}var o;return i.domain=function(r){return arguments.length?(e=r.filter(t).sort(n),u()):e},i.range=function(n){return arguments.length?(r=n,u()):r},i.quantiles=function(){return o},i.invertExtent=function(n){return n=r.indexOf(n),0>n?[0/0,0/0]:[n>0?o[n-1]:e[0],n<o.length?o[n]:e[e.length-1]]},i.copy=function(){return Wi(e,r)},u()}function Ji(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=wr,r=Sr,u=we,i=uo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=xs.get(n)||uo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function uo(n){return n.join("L")}function io(n){return uo(n)+"Z"}function oo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function so(n,t){return n.length<4?uo(n):n[1]+ho(n.slice(1,n.length-1),go(n,t))}function lo(n,t){return n.length<3?uo(n):n[0]+ho((n.push(n[0]),n),go([n[n.length-2]].concat(n,[n[1]]),t))}function fo(n,t){return n.length<3?uo(n):n[0]+ho(n,go(n,t))}function ho(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return uo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function go(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function po(n){if(n.length<3)return uo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",xo(bs,o),",",xo(bs,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Mo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function vo(n){if(n.length<4)return uo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(xo(bs,i)+","+xo(bs,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Mo(e,i,o);return e.join("")}function mo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[xo(bs,o),",",xo(bs,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Mo(t,o,a);return t.join("")}function yo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return po(n)}function xo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Mo(n,t,e){n.push("C",xo(Ms,t),",",xo(Ms,e),",",xo(_s,t),",",xo(_s,e),",",xo(bs,t),",",xo(bs,e))}function _o(n,t){return(t[1]-n[1])/(t[0]-n[0])}function bo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=_o(u,i);++t<e;)r[t]=(o+(o=_o(u=i,i=n[t+1])))/2;return r[t]=o,r}function wo(n){for(var t,e,r,u,i=[],o=bo(n),a=-1,c=n.length-1;++a<c;)t=_o(n[a],n[a+1]),ua(t)<ka?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ms,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Eo(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=bt(e),_=bt(u),b=e===r?function(){return g}:bt(r),w=u===i?function(){return p}:bt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=wr,r=wr,u=0,i=Sr,o=we,a=uo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=xs.get(n)||uo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Ao(n){return n.radius}function Co(n){return[n.x,n.y]}function No(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ms;return[e*Math.cos(r),e*Math.sin(r)]}}function zo(){return 64}function Lo(){return"circle"}function To(n){var t=Math.sqrt(n/ba);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function qo(n,t){return sa(n,Cs),n.id=t,n}function Ro(n,t,e,r){var u=n.id;return P(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Do(n){return null==n&&(n=""),function(){this.textContent=n}}function Po(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var a=r.time;i=u[e]={tween:new o,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Zo.timer(function(r){function o(r){return u.active>e?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);
- return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]<Us[i]/u?i-1:i]:[Fs,Fi(n,e)[2]]}return r.invert=function(t){return Oo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Oo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Oo(+e+1),t).length}var i=r.domain(),o=Li(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Ri(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Zo.mean=function(n,e){var r,u=0,i=n.length,o=-1,a=i;if(1===arguments.length)for(;++o<i;)t(r=n[o])?u+=r:--a;else for(;++o<i;)t(r=e.call(n,n[o],o))?u+=r:--a;return a?u/a:void 0},Zo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Zo.median=function(e,r){return arguments.length>1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n<t;)for(var u,i=-1,o=e[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return e},Zo.transpose=function(n){return Zo.zip.apply(Zo,n)},Zo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Zo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Zo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Zo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)<t;)i.push(r/o);return i},Zo.map=function(n){var t=new o;if(n instanceof o)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},i(o,{has:a,get:function(n){return this[ia+n]},set:function(n,t){return this[ia+n]=t},remove:c,keys:s,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1),this[t])}});var ia="\x00",oa=ia.charCodeAt(0);Zo.nest=function(){function n(t,a,c){if(c>=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=g(n,t,t[e]);return n};var aa=["webkit","ms","moz","Moz","o","O"];Zo.dispatch=function(){for(var n=new d,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=m(n);return n},d.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return _(i)},pa.selectAll=function(n){var t,e,r=[];n=w(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Xo(n.call(e,e.__data__,a,u))),t.parentNode=e);return _(r)};var va={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Zo.ns={prefix:va,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!E(n[u]).test(t))return!1;return!0}for(t in n)this.each(C(t,n[t]));return this}return this.each(C(n,t))},pa.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++r<a;)d=t.call(u=n[r],u.__data__,r),m.has(d)?v[r]=u:m.set(d,u),x.push(d);for(r=-1;++r<f;)d=t.call(e,i=e[r],r),(u=m.get(d))?(g[r]=u,u.__data__=i):y.has(d)||(p[r]=q(i)),y.set(d,i),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=q(i);for(;f>r;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i<a;)(u=r[i])&&(n[i]=u.__data__);return n}var c=U([]),s=_([]),l=_([]);if("function"==typeof n)for(;++i<a;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<a;)e(r=this[i],n);return s.enter=function(){return c},s.exit=function(){return l},s},pa.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},pa.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},pa.each=function(n){return P(this,function(t,e,r){n.call(t,t.__data__,e,r)})},pa.call=function(n){var t=Xo(arguments);return n.apply(t[0]=this,t),this},pa.empty=function(){return!this.node()},pa.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return _(o)},da.insert=function(n,t){return arguments.length<2&&(t=j(this)),pa.insert.call(this,n,t)},pa.transition=function(){for(var n,t,e=Ss||++Ns,r=[],u=ks||{time:Date.now(),ease:xu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&Po(t,c,e,u),n.push(t)}return qo(r,e)},pa.interrupt=function(){return this.each(H)},Zo.select=function(n){var t=["string"==typeof n?la(n,$o):n];return t.parentNode=Bo,_([t])},Zo.selectAll=function(n){var t=Xo("string"==typeof n?fa(n,$o):n);return t.parentNode=Bo,_([t])};var ma=Zo.select(Bo);pa.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)oe(e[r].geometry,t)}},cc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){ae(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t,0)},Polygon:function(n,t){ce(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ce(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)oe(e[r],t)}};Zo.geo.area=function(n){return sc=0,Zo.geo.stream(n,fc),sc};var sc,lc=new ue,fc={sphere:function(){sc+=4*ba},point:v,lineStart:v,lineEnd:v,polygonStart:function(){lc.reset(),fc.lineStart=se},polygonEnd:function(){var n=2*lc;sc+=0>n?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,fc.polygonStart()},polygonEnd:function(){fc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>lc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);
- for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=wr,r=Sr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Zo.geom.polygon=function(n){return sa(n,Yc),n};var Yc=Zo.geom.polygon.prototype=[];Yc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Yc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Yc.clip=function(n){for(var t,e,r,u,i,o,a=Nr(n),c=-1,s=this.length-Nr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Ar(o,l,u)?(Ar(i,l,u)||n.push(Cr(i,o,l,u)),n.push(o)):Ar(i,l,u)&&n.push(Cr(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Ic,Zc,Vc,Xc,$c,Bc=[],Wc=[];Ur.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Hr),t.length},Wr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Jr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=nu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Qr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Qr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?nu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Qr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Kr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Qr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Kr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Qr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Zo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return tu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&ru(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=bt(r=n),t):r},t.y=function(n){return arguments.length?(o=bt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Jc:n,t):a===Jc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Jc?null:a&&a[1]},t)};var Jc=[[-1e6,-1e6],[1e6,1e6]];Zo.geom.delaunay=function(n){return Zo.geom.voronoi().triangles(n)},Zo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(ua(c-e)+ua(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=wr,c=Sr;return(o=arguments.length)?(a=uu,c=iu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Zo.interpolateRgb=cu,Zo.interpolateObject=su,Zo.interpolateNumber=lu,Zo.interpolateString=fu;var Gc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Kc=new RegExp(Gc.source,"g");Zo.interpolate=hu,Zo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ia.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cu:fu:t instanceof et?cu:Array.isArray(t)?gu:"object"===e&&isNaN(t)?su:lu)(n,t)}],Zo.interpolateArray=gu;var Qc=function(){return wt},ns=Zo.map({linear:Qc,poly:Mu,quad:function(){return mu},cubic:function(){return yu},sin:function(){return _u},exp:function(){return bu},circle:function(){return wu},elastic:Su,back:ku,bounce:function(){return Eu}}),ts=Zo.map({"in":wt,out:vu,"in-out":du,"out-in":function(n){return du(vu(n))}});Zo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(ju(n[e]));return t}},Zo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Zo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Zo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(wa-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Zo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Zo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Xu(e,r)},Zo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Zo.sum(o),s=Zo.range(i.length);null!=e&&s.sort(e===os?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=os,r=0,u=wa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var os={};Zo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Zo.permute(s,f),l=Zo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Zo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ni,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ni(t):zi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return zi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ni:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Xu(i,a)},Zo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);
- return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),Po(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return qo(i,u)},Cs.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=w(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&Po(u,g,o,i),t.push(u)}return qo(a,o)},Cs.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]<x[0])],z[1]=f[+(n[1]<x[1])]):x=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Ti(t),c=a[0],s=a[1],p=z[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}();
-
-
- var catalog =
-{"packages":[{"name":"v","size":1,"imports":["u"],"cycleSegments":{"u-v":{"s":"v","t":"u"},"v-u":{"s":"u","t":"v"}},"cycleCount":1,"cycleSegmentCount":2},{"name":"u","size":2,"imports":["v"],"cycleSegments":{"u-v":{"s":"v","t":"u"},"v-u":{"s":"u","t":"v"}},"cycleCount":1,"cycleSegmentCount":2},{"name":"b","size":1,"imports":["c"],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"c","size":1,"imports":[],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"a","size":2,"imports":["b","c"],"cycleSegments":{},"cycleCount":0,"cycleSegmentCount":0},{"name":"n","size":1,"imports":["k"],"cycleSegments":{"k-n":{"s":"n","t":"k"},"l-k":{"s":"k","t":"l"},"n-l":{"s":"l","t":"n"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"}},"cycleCount":2,"cycleSegmentCount":5},{"name":"l","size":1,"imports":["k","n","m"],"cycleSegments":{"k-n":{"s":"n","t":"k"},"k-l":{"s":"l","t":"k"},"l-k":{"s":"k","t":"l"},"n-l":{"s":"l","t":"n"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"}},"cycleCount":3,"cycleSegmentCount":6},{"name":"m","size":1,"imports":["n"],"cycleSegments":{"k-n":{"s":"n","t":"k"},"l-k":{"s":"k","t":"l"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"}},"cycleCount":1,"cycleSegmentCount":4},{"name":"k","size":1,"imports":["l"],"cycleSegments":{"k-n":{"s":"n","t":"k"},"k-l":{"s":"l","t":"k"},"l-k":{"s":"k","t":"l"},"n-l":{"s":"l","t":"n"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"}},"cycleCount":3,"cycleSegmentCount":6},{"name":"z","size":1,"imports":["x"],"cycleSegments":{"z-y":{"s":"y","t":"z"},"y-x":{"s":"x","t":"y"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3},{"name":"y","size":1,"imports":["z"],"cycleSegments":{"z-y":{"s":"y","t":"z"},"y-x":{"s":"x","t":"y"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3},{"name":"x","size":1,"imports":["y"],"cycleSegments":{"z-y":{"s":"y","t":"z"},"y-x":{"s":"x","t":"y"},"x-z":{"s":"z","t":"x"}},"cycleCount":1,"cycleSegmentCount":3}],"cycleSegments":{"k-n":{"s":"n","t":"k"},"z-y":{"s":"y","t":"z"},"y-x":{"s":"x","t":"y"},"k-l":{"s":"l","t":"k"},"l-k":{"s":"k","t":"l"},"n-l":{"s":"l","t":"n"},"u-v":{"s":"v","t":"u"},"v-u":{"s":"u","t":"v"},"m-l":{"s":"l","t":"m"},"n-m":{"s":"m","t":"n"},"x-z":{"s":"z","t":"x"}},"summary":{"packages":12,"sources":14,"cycles":5,"cycleSegments":11}}
- ;
-
- var diameter = 1000,
- radius = diameter / 2,
- innerRadius = radius - 300;
-
- var cluster = d3.layout.cluster()
- .size([360, innerRadius])
- .sort(null)
- .value(function(d) { return d.size; });
-
- var bundle = d3.layout.bundle();
-
- var line = d3.svg.line.radial()
- .interpolate("bundle")
- .tension(.75)
- .radius(function(d) { return d.y; })
- .angle(function(d) { return d.x / 180 * Math.PI; });
-
- var svg = d3.select("body").append("svg")
- .attr("width", diameter)
- .attr("height", diameter)
- .append("g")
- .attr("transform", "translate(" + radius + "," + radius + ")");
-
- var link = svg.append("g").selectAll(".link"),
- node = svg.append("g").selectAll(".node"),
- cycles = {}, highlightCycles, selectedNode;
-
- function isCyclicLink(l) {
- return highlightCycles &&
- (cycles[l.source.key + "-" + l.target.key] || cycles[l.target.key + "-" + l.source.key]);
- }
-
- function isCyclicPackageLink(l, p) {
- var key = l.source.key + "-" + l.target.key,
- rKey = l.target.key + "-" + l.source.key;
- return isCyclicLink(l) && (p.cycleSegments[key] || p.cycleSegments[rKey]);
- }
-
- function refreshPaths() {
- svg.selectAll("path.link").classed("link--cycle", isCyclicLink);
- }
-
- function processCatalog() {
- var nodes = cluster.nodes(packageHierarchy(catalog.packages)),
- links = packageImports(nodes),
- splines = bundle(links);
- cycles = catalog.cycleSegments;
-
- d3.select("input[type=checkbox]").on("change", function() {
- highlightCycles = this.checked;
- refreshPaths();
- });
-
- link = link
- .data(splines)
- .enter().append("path")
- .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
- .attr("class", "link")
- .classed("link--cycle", isCyclicLink)
- .attr("d", function(d, i) { return line(splines[i]); });
-
-
- node = node
- .data(nodes.filter(function(n) { return !n.children; }))
- .enter().append("text")
- .attr("class", "node")
- .attr("dy", ".31em")
- .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
- .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
- .text(function(d) { return d.key; })
- .on("focus", processSelect)
- .on("blur", processSelect);
-
- d3.select("input[type=range]").on("change", function() {
- line.tension(this.value / 100);
- svg.selectAll("path.link")
- .data(splines)
- .attr("d", function(d, i) { return line(splines[i]); });
- });
-
- d3.select("#packageCount").text(catalog.summary.packages);
- d3.select("#sourceCount").text(catalog.summary.sources);
- d3.select("#segmentCount").text(catalog.summary.cycleSegments);
- d3.select("#cycleCount").text(catalog.summary.cycles);
- }
-
- function processSelect(d) {
- if (selectedNode === d) {
- deselected(d);
- selectedNode = null;
-
- } else if (selectedNode) {
- deselected(selectedNode);
- selectedNode = null;
- selected(d);
-
- } else {
- selected(d);
- selectedNode = d;
- }
- }
-
- function selected(d) {
- node
- .each(function(n) { n.target = n.source = false; })
- .classed("node--focus", function(n) { return n === d; });
-
- link
- .classed("link--cycle", function(l) { return isCyclicPackageLink(l, d); })
- .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
- .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
- .filter(function(l) { return l.target === d || l.source === d; })
- .each(function() { this.parentNode.appendChild(this); });
-
- node
- .classed("node--target", function(n) { return n.target; })
- .classed("node--source", function(n) { return n.source; });
-
- d3.select("#psourceCount").text(d.size);
- d3.select("#pdependentCount").text(d.imports.length);
- d3.select("#psegmentCount").text(d.cycleSegmentCount);
- d3.select("#pcycleCount").text(d.cycleCount);
- d3.select(".details").classed("shown", function() { return true; });
- }
-
- function deselected(d) {
- link
- .classed("link--cycle", isCyclicLink)
- .classed("link--target", false)
- .classed("link--source", false);
-
- node
- .classed("node--target", false)
- .classed("node--source", false)
- .classed("node--focus", false);
- d3.select(".details").classed("shown", function() { return false; });
- }
-
- d3.select(self.frameElement).style("height", diameter + "px");
-
- // Lazily construct the package hierarchy.
- function packageHierarchy(packages) {
- var map = {}, cnt = 0;
-
- // Builds the structure top-down to the specified leaf or until
- // another leaf in which case hook this leaf to the same parent
- function buildHierarchy(leaf, i) {
- var leafName = leaf.name,
- node, name, parent = map[""], start = 0;
- while (start < leafName.length) {
- name = parentName(leafName, start);
- node = map[name];
- if (!node) {
- node = map[name] = parentNode(name, parent);
- parent.children.push(node);
-
- } else if (node.imports) {
- leaf.parent = parent;
- parent.children.push(leaf);
- break;
- }
- parent = node;
- start = name.length + 1;
- }
- }
-
- function parentNode(name, parent) {
- return {name: name, parent: parent, key: name, children: []};
- }
-
- function parentName(leafName, start) {
- var i = leafName.indexOf(".", start);
- return i > 0 ? leafName.substring(0, i) : leafName;
- }
-
- // First populate all packages as leafs
- packages.forEach(function(d) {
- map[d.name] = d;
- d.key = d.name;
- });
-
- // Next synthesize the intermediate structure, by-passing any leafs
- map[""] = parentNode("", null);
- var i = 0;
- packages.forEach(function(d) {
- buildHierarchy(d, i++);
- });
-
- return map[""];
- }
-
- // Return a list of imports for the given array of nodes.
- function packageImports(nodes) {
- var map = {},
- imports = [];
-
- // Compute a map from name to node.
- nodes.forEach(function(d) {
- map[d.name] = d;
- });
-
- // For each import, construct a link from the source to target node.
- nodes.forEach(function(d) {
- if (d.imports) d.imports.forEach(function(i) {
- imports.push({source: map[d.name], target: map[i]});
- });
- });
-
- return imports;
- }
-
- processCatalog();
-</script>
-</body>
-</html>
diff --git a/framework/src/onos/utils/jnc/pom.xml b/framework/src/onos/utils/jnc/pom.xml
deleted file mode 100644
index 3fd83b3d..00000000
--- a/framework/src/onos/utils/jnc/pom.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-jnc-osgi</artifactId>
- <packaging>bundle</packaging>
-
- <description>TailF JNC and Ganymed SSH2 packaged as OSGi bundle</description>
-
- <dependencies>
- <dependency>
- <groupId>ch.ethz.ganymed</groupId>
- <artifactId>ganymed-ssh2</artifactId>
- <version>262</version>
- </dependency>
-
- <dependency>
- <!-- TODO: change this appropriately when the official TailF JNC is available -->
- <groupId>org.onosproject</groupId>
- <artifactId>jnc</artifactId>
- <version>1.0</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <filters>
- <filter>
- <artifact>com.google.guava:guava</artifact>
- <excludes>
- <exclude>**</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- com.tailf.jnc,
- ch.ethz.ssh2,
- ch.ethz.ssh2.auth,
- ch.ethz.ssh2.channel,
- ch.ethz.ssh2.crypto,
- ch.ethz.ssh2.crypto.cipher,
- ch.ethz.ssh2.crypto.dh,
- ch.ethz.ssh2.crypto.digest,
- ch.ethz.ssh2.log,
- ch.ethz.ssh2.packets,
- ch.ethz.ssh2.server,
- ch.ethz.ssh2.sftp,
- ch.ethz.ssh2.signature,
- ch.ethz.ssh2.transport,
- ch.ethz.ssh2.util
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/utils/junit/pom.xml b/framework/src/onos/utils/junit/pom.xml
deleted file mode 100644
index da99f46d..00000000
--- a/framework/src/onos/utils/junit/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-junit</artifactId>
- <packaging>bundle</packaging>
-
- <description>ON.Lab JUnit test utilities</description>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-core</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-library</artifactId>
- <scope>compile</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ExceptionTest.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ExceptionTest.java
deleted file mode 100644
index 09b3fe37..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-/**
- * Base for exception tests.
- */
-public abstract class ExceptionTest {
-
- protected static final Throwable CAUSE = new RuntimeException("boom");
- protected static final String MESSAGE = "Uh oh.... boom";
-
- protected abstract Exception getDefault();
- protected abstract Exception getWithMessage();
- protected abstract Exception getWithMessageAndCause();
-
- @Test
- public void noMessageNoCause() {
- Exception e = getDefault();
- assertEquals("incorrect message", null, e.getMessage());
- assertEquals("incorrect cause", null, e.getCause());
- }
-
- @Test
- public void withMessage() {
- Exception e = getWithMessage();
- assertEquals("incorrect message", MESSAGE, e.getMessage());
- assertEquals("incorrect cause", null, e.getCause());
- }
-
- @Test
- public void withCause() {
- Exception e = getWithMessageAndCause();
- assertEquals("incorrect message", MESSAGE, e.getMessage());
- assertSame("incorrect cause", CAUSE, e.getCause());
- }
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ImmutableClassChecker.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ImmutableClassChecker.java
deleted file mode 100644
index 80aa2cb1..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/ImmutableClassChecker.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.hamcrest.Description;
-import org.hamcrest.StringDescription;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-/**
- * Hamcrest style class for verifying that a class follows the
- * accepted rules for immutable classes.
- *
- * The rules that are enforced for immutable classes:
- * - the class must be declared final
- * - all data members of the class must be declared private and final
- * - the class must not define any setter methods
- */
-
-public class ImmutableClassChecker {
-
- private String failureReason = "";
-
- /**
- * Method to determine if a given class is a properly specified
- * immutable class.
- *
- * @param clazz the class to check
- * @return true if the given class is a properly specified immutable class.
- */
- private boolean isImmutableClass(Class<?> clazz, boolean allowNonFinalClass) {
- // class must be declared final
- if (!allowNonFinalClass && !Modifier.isFinal(clazz.getModifiers())) {
- failureReason = "a class that is not final";
- return false;
- }
-
- // class must have only final and private data members
- for (final Field field : clazz.getDeclaredFields()) {
- if (field.getName().startsWith("_") ||
- field.getName().startsWith("$")) {
- // eclipse generated code may insert switch table - ignore
- // cobertura sticks these fields into classes - ignore them
- continue;
- }
- if (!Modifier.isFinal(field.getModifiers())) {
- failureReason = "a field named '" + field.getName() +
- "' that is not final";
- return false;
- }
- if (!Modifier.isPrivate(field.getModifiers())) {
- //
- // NOTE: We relax the recommended rules for defining immutable
- // objects and allow "static final" fields that are not
- // private. The "final" check was already done above so we
- // don't repeat it here.
- //
- if (!Modifier.isStatic(field.getModifiers())) {
- failureReason = "a field named '" + field.getName() +
- "' that is not private and is not static";
- return false;
- }
- }
- }
-
- // class must not define any setters
- for (final Method method : clazz.getMethods()) {
- if (method.getDeclaringClass().equals(clazz)) {
- if (method.getName().startsWith("set")) {
- failureReason = "a class with a setter named '" + method.getName() + "'";
- return false;
- }
- }
- }
-
- return true;
- }
-
- /**
- * Describe why an error was reported. Uses Hamcrest style Description
- * interfaces.
- *
- * @param description the Description object to use for reporting the
- * mismatch
- */
- public void describeMismatch(Description description) {
- description.appendText(failureReason);
- }
-
- /**
- * Describe the source object that caused an error, using a Hamcrest
- * Matcher style interface. In this case, it always returns
- * that we are looking for a properly defined utility class.
- *
- * @param description the Description object to use to report the "to"
- * object
- */
- public void describeTo(Description description) {
- description.appendText("a properly defined immutable class");
- }
-
- /**
- * Assert that the given class adheres to the immutable class rules.
- *
- * @param clazz the class to check
- *
- * @throws java.lang.AssertionError if the class is not an
- * immutable class
- */
- public static void assertThatClassIsImmutable(Class<?> clazz) {
- final ImmutableClassChecker checker = new ImmutableClassChecker();
- if (!checker.isImmutableClass(clazz, false)) {
- final Description toDescription = new StringDescription();
- final Description mismatchDescription = new StringDescription();
-
- checker.describeTo(toDescription);
- checker.describeMismatch(mismatchDescription);
- final String reason =
- "\n" +
- "Expected: is \"" + toDescription.toString() + "\"\n" +
- " but : was \"" + mismatchDescription.toString() + "\"";
-
- throw new AssertionError(reason);
- }
- }
-
- /**
- * Assert that the given class adheres to the immutable class rules, but
- * is not declared final. Classes that need to be inherited from cannot be
- * declared final.
- *
- * @param clazz the class to check
- *
- * @throws java.lang.AssertionError if the class is not an
- * immutable class
- */
- public static void assertThatClassIsImmutableBaseClass(Class<?> clazz) {
- final ImmutableClassChecker checker = new ImmutableClassChecker();
- if (!checker.isImmutableClass(clazz, true)) {
- final Description toDescription = new StringDescription();
- final Description mismatchDescription = new StringDescription();
-
- checker.describeTo(toDescription);
- checker.describeMismatch(mismatchDescription);
- final String reason =
- "\n" +
- "Expected: is \"" + toDescription.toString() + "\"\n" +
- " but : was \"" + mismatchDescription.toString() + "\"";
-
- throw new AssertionError(reason);
- }
- }
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/IntegrationTest.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/IntegrationTest.java
deleted file mode 100644
index a033802f..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/IntegrationTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-/**
- * Marker interface used to separate unit tests from integration tests. All
- * integration tests should be marked with:
- * {@literal @Category}(IntegrationTest.class)
- * so that they can be run separately.
- */
-public interface IntegrationTest {
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/NullScheduledExecutor.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/NullScheduledExecutor.java
deleted file mode 100644
index 6d959703..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/NullScheduledExecutor.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A scheduled executor service that does not do any of the work scheduled to it.
- * <p>
- * This is useful for testing when you want to disable a background scheduled
- * task.
- * </p>
- */
-public class NullScheduledExecutor implements ScheduledExecutorService {
- @Override
- public ScheduledFuture<?> schedule(Runnable command, long delay,
- TimeUnit unit) {
- return null;
- }
-
- @Override
- public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay,
- TimeUnit unit) {
- return null;
- }
-
- @Override
- public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
- long initialDelay,
- long period, TimeUnit unit) {
- return null;
- }
-
- @Override
- public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
- long initialDelay,
- long delay,
- TimeUnit unit) {
- return null;
- }
-
- @Override
- public void shutdown() {
-
- }
-
- @Override
- public List<Runnable> shutdownNow() {
- return null;
- }
-
- @Override
- public boolean isShutdown() {
- return false;
- }
-
- @Override
- public boolean isTerminated() {
- return false;
- }
-
- @Override
- public boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException {
- return false;
- }
-
- @Override
- public <T> Future<T> submit(Callable<T> task) {
- return null;
- }
-
- @Override
- public <T> Future<T> submit(Runnable task, T result) {
- return null;
- }
-
- @Override
- public Future<?> submit(Runnable task) {
- return null;
- }
-
- @Override
- public <T> List<Future<T>> invokeAll(
- Collection<? extends Callable<T>> tasks)
- throws InterruptedException {
- return null;
- }
-
- @Override
- public <T> List<Future<T>> invokeAll(
- Collection<? extends Callable<T>> tasks, long timeout,
- TimeUnit unit) throws InterruptedException {
- return null;
- }
-
- @Override
- public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
- throws InterruptedException, ExecutionException {
- return null;
- }
-
- @Override
- public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException {
- return null;
- }
-
- @Override
- public void execute(Runnable command) {
-
- }
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestTools.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestTools.java
deleted file mode 100644
index 40e8686c..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestTools.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.List;
-import java.util.Random;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.junit.Assert.fail;
-
-/**
- * Utilities to aid in producing JUnit tests.
- */
-public final class TestTools {
-
- private static final Random RANDOM = new Random();
-
- // Prohibit construction
- private TestTools() {
- }
-
- public static void print(String msg) {
- System.out.print(msg);
- }
-
- /**
- * Suspends the current thread for a specified number of millis.
- *
- * @param ms number of millis
- */
- public static void delay(int ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- fail("test interrupted");
- }
- }
-
- /**
- * Returns the current time in millis since epoch.
- *
- * @return current time
- */
- public static long now() {
- return System.currentTimeMillis();
- }
-
- /**
- * Runs the specified runnable until it completes successfully or until the
- * specified time expires. If the latter occurs, the first encountered
- * assertion on the last attempt will be re-thrown. Errors other than
- * assertion errors will be propagated immediately.
- * <p>
- * Assertions attempts will not be closer than 10 millis apart and no
- * further than 50 millis.
- * </p>
- *
- * @param delay number of millis to delay before the first attempt
- * @param duration number of milliseconds beyond the current time
- * @param assertions test assertions runnable
- */
- public static void assertAfter(int delay, int duration, Runnable assertions) {
- checkArgument(delay < duration, "delay >= duration");
- long start = now();
- int step = Math.max(Math.min((duration - delay) / 100, 50), 10);
-
- // Is there an initial delay?
- if (delay > 0) {
- delay(delay);
- }
-
- // Keep going until the assertions succeed or until time runs-out.
- while (true) {
- try {
- assertions.run();
- break;
- } catch (AssertionError e) {
- // If there was an error and time ran out, re-throw it.
- if (now() - start > duration) {
- throw e;
- }
- }
- delay(step);
- }
- }
-
- /**
- * Runs the specified runnable until it completes successfully or until the
- * specified time expires. If the latter occurs, the first encountered
- * assertion on the last attempt will be re-thrown. Errors other than
- * assertion errors will be propagated immediately.
- * <p>
- * Assertions attempts will not be closer than 10 millis apart and no
- * further than 50 millis.
- * </p>
- *
- * @param duration number of milliseconds beyond the current time
- * @param assertions test assertions runnable
- */
- public static void assertAfter(int duration, Runnable assertions) {
- assertAfter(0, duration, assertions);
- }
-
-
- /**
- * Creates a directory tree of test files. To signify creating a directory
- * file path should end with '/'.
- *
- * @param paths list of file paths
- * @return list of created files
- * @throws java.io.IOException if there is an issue
- */
- public static List<File> createTestFiles(List<String> paths) throws IOException {
- return createTestFiles(paths, 32, 1024);
- }
-
- /**
- * Creates a directory tree of test files. To signify creating a directory
- * file path should end with '/'.
- *
- * @param paths list of file paths
- * @param minSize minimum file size in bytes
- * @param maxSize maximum file size in bytes
- * @return list of created files
- * @throws java.io.IOException if there is an issue
- */
- public static List<File> createTestFiles(List<String> paths,
- int minSize, int maxSize) throws IOException {
- ImmutableList.Builder<File> files = ImmutableList.builder();
- for (String p : paths) {
- File f = new File(p);
- if (p.endsWith("/")) {
- if (f.mkdirs()) {
- files.add(f);
- }
- } else {
- Files.createParentDirs(f);
- if (f.createNewFile()) {
- writeRandomFile(f, minSize, maxSize);
- files.add(f);
- }
- }
- }
- return files.build();
- }
-
- /**
- * Writes random binary content into the specified file. The number of
- * bytes will be random between the given minimum and maximum.
- *
- * @param file file to write data to
- * @param minSize minimum number of bytes to write
- * @param maxSize maximum number of bytes to write
- * @throws IOException if there is an issue
- */
- public static void writeRandomFile(File file, int minSize, int maxSize) throws IOException {
- int size = minSize + (minSize == maxSize ? 0 : RANDOM.nextInt(maxSize - minSize));
- byte[] data = new byte[size];
- tweakBytes(RANDOM, data, size / 4);
- Files.write(data, file);
- }
-
-
- /**
- * Tweaks the given number of bytes in a byte array.
- *
- * @param random random number generator
- * @param data byte array to be tweaked
- * @param count number of bytes to tweak
- */
- public static void tweakBytes(Random random, byte[] data, int count) {
- tweakBytes(random, data, count, 0, data.length);
- }
-
- /**
- * Tweaks the given number of bytes in the specified range of a byte array.
- *
- * @param random random number generator
- * @param data byte array to be tweaked
- * @param count number of bytes to tweak
- * @param start index at beginning of range (inclusive)
- * @param end index at end of range (exclusive)
- */
- public static void tweakBytes(Random random, byte[] data, int count,
- int start, int end) {
- int len = end - start;
- for (int i = 0; i < count; i++) {
- data[start + random.nextInt(len)] = (byte) random.nextInt();
- }
- }
-
- /*
- * Finds an available port that a test can bind to.
- */
- public static int findAvailablePort(int defaultPort) {
- try {
- ServerSocket socket = new ServerSocket(0);
- socket.setReuseAddress(true);
- int port = socket.getLocalPort();
- socket.close();
- return port;
- } catch (IOException ex) {
- return defaultPort;
- }
- }
-
-
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestUtils.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestUtils.java
deleted file mode 100644
index 686a9a59..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestUtils.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-
-/**
- * Utilities for testing.
- */
-public final class TestUtils {
-
- /**
- * Sets the field, bypassing scope restriction.
- *
- * @param subject Object where the field belongs
- * @param fieldName name of the field to set
- * @param value value to set to the field.
- * @param <T> subject type
- * @param <U> value type
- * @throws TestUtilsException if there are reflection errors while setting
- * the field
- */
- public static <T, U> void setField(T subject, String fieldName, U value)
- throws TestUtilsException {
- @SuppressWarnings("unchecked")
- Class clazz = subject.getClass();
- try {
- while (clazz != null) {
- try {
- Field field = clazz.getDeclaredField(fieldName);
- field.setAccessible(true);
- field.set(subject, value);
- break;
- } catch (NoSuchFieldException ex) {
- if (clazz == clazz.getSuperclass()) {
- break;
- }
- clazz = clazz.getSuperclass();
- }
- }
- } catch (SecurityException | IllegalArgumentException |
- IllegalAccessException e) {
- throw new TestUtilsException("setField failed", e);
- }
- }
-
- /**
- * Gets the field, bypassing scope restriction.
- *
- * @param subject Object where the field belongs
- * @param fieldName name of the field to get
- * @param <T> subject type
- * @param <U> fieldO value type
- * @return value of the field.
- * @throws TestUtilsException if there are reflection errors while getting
- * the field
- */
- public static <T, U> U getField(T subject, String fieldName)
- throws TestUtilsException {
- try {
- NoSuchFieldException exception = null;
- @SuppressWarnings("unchecked")
- Class clazz = subject.getClass();
- while (clazz != null) {
- try {
- Field field = clazz.getDeclaredField(fieldName);
- field.setAccessible(true);
-
- @SuppressWarnings("unchecked")
- U result = (U) field.get(subject);
- return result;
- } catch (NoSuchFieldException e) {
- exception = e;
- if (clazz == clazz.getSuperclass()) {
- break;
- }
- clazz = clazz.getSuperclass();
- }
- }
- throw new TestUtilsException("Field not found. " + fieldName, exception);
-
- } catch (SecurityException |
- IllegalArgumentException | IllegalAccessException e) {
- throw new TestUtilsException("getField failed", e);
- }
- }
-
- /**
- * Calls the method, bypassing scope restriction.
- *
- * @param subject Object where the method belongs
- * @param methodName name of the method to call
- * @param paramTypes formal parameter type array
- * @param args arguments
- * @return return value or null if void
- * @param <T> subject type
- * @param <U> return value type
- * @throws TestUtilsException if there are reflection errors while calling
- * the method
- */
- public static <T, U> U callMethod(T subject, String methodName,
- Class<?>[] paramTypes, Object...args) throws TestUtilsException {
-
- try {
- @SuppressWarnings("unchecked")
- Class<T> clazz = (Class<T>) subject.getClass();
- final Method method;
- if (paramTypes == null || paramTypes.length == 0) {
- method = clazz.getDeclaredMethod(methodName);
- } else {
- method = clazz.getDeclaredMethod(methodName, paramTypes);
- }
- method.setAccessible(true);
-
- @SuppressWarnings("unchecked")
- U result = (U) method.invoke(subject, args);
- return result;
- } catch (NoSuchMethodException | SecurityException |
- IllegalAccessException | IllegalArgumentException |
- InvocationTargetException e) {
- throw new TestUtilsException("callMethod failed", e);
- }
- }
-
- /**
- * Calls the method, bypassing scope restriction.
- *
- * @param subject Object where the method belongs
- * @param methodName name of the method to call
- * @param paramType formal parameter type
- * @param arg argument
- * @return return value or null if void
- * @param <T> subject type
- * @param <U> return value type
- * @throws TestUtilsException if there are reflection errors while calling
- * the method
- */
- public static <T, U> U callMethod(T subject, String methodName,
- Class<?> paramType, Object arg) throws TestUtilsException {
- return callMethod(subject, methodName, new Class<?>[]{paramType}, arg);
- }
-
- /**
- * Triggers an allocation of an object of type T and forces a call to
- * the private constructor.
- *
- * @param constructor Constructor to call
- * @param <T> type of the object to create
- * @return created object of type T
- * @throws TestUtilsException if there are reflection errors while calling
- * the constructor
- */
- public static <T> T callConstructor(Constructor<T> constructor)
- throws TestUtilsException {
- try {
- constructor.setAccessible(true);
- return constructor.newInstance();
- } catch (InstantiationException | IllegalAccessException |
- InvocationTargetException error) {
- throw new TestUtilsException("callConstructor failed", error);
- }
- }
-
- /**
- * Avoid instantiation.
- */
- private TestUtils() {}
-
- /**
- * Exception that can be thrown if problems are encountered while executing
- * the utility method. These are usually problems accessing fields/methods
- * through reflection. The original exception can be found by examining the
- * cause.
- */
- public static class TestUtilsException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructs a new exception with the specified detail message and
- * cause.
- *
- * @param message the detail message
- * @param cause the original cause of this exception
- */
- public TestUtilsException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
deleted file mode 100644
index 9c623cee..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.hamcrest.Description;
-import org.hamcrest.StringDescription;
-import org.onlab.junit.TestUtils.TestUtilsException;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-
-/**
- * Hamcrest style class for verifying that a class follows the
- * accepted rules for utility classes.
- *
- * The rules that are enforced for utility classes:
- * - the class must be declared final
- * - the class must have only one constructor
- * - the constructor must be private and inaccessible to callers
- * - the class must have only static methods
- */
-
-public class UtilityClassChecker {
-
- private String failureReason = "";
-
- /**
- * Method to determine if a given class is a properly specified
- * utility class. In addition to checking that the class meets the criteria
- * for utility classes, an object of the class type is allocated to force
- * test code coverage onto the class constructor.
- *
- * @param clazz the class to check
- * @return true if the given class is a properly specified utility class.
- */
- private boolean isProperlyDefinedUtilityClass(Class<?> clazz) {
- // class must be declared final
- if (!Modifier.isFinal(clazz.getModifiers())) {
- failureReason = "a class that is not final";
- return false;
- }
-
- // class must have only one constructor
- final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
- if (constructors.length != 1) {
- failureReason = "a class with more than one constructor";
- return false;
- }
-
- // constructor must not be accessible outside of the class
- final Constructor<?> constructor = constructors[0];
- if (constructor.isAccessible()) {
- failureReason = "a class with an accessible default constructor";
- return false;
- }
-
- // constructor must be private
- if (!Modifier.isPrivate(constructor.getModifiers())) {
- failureReason = "a class with a default constructor that is not private";
- return false;
- }
-
- // class must have only static methods
- for (final Method method : clazz.getMethods()) {
- if (method.getDeclaringClass().equals(clazz)) {
- if (!Modifier.isStatic(method.getModifiers())) {
- failureReason = "a class with one or more non-static methods";
- return false;
- }
- }
-
- }
-
- try {
- final Object newObject = TestUtils.callConstructor(constructor);
- if (newObject == null) {
- failureReason = "could not instantiate a new object";
- return false;
- }
- } catch (TestUtilsException e) {
- failureReason = "could not instantiate a new object";
- return false;
- }
- return true;
- }
-
- /**
- * Describe why an error was reported. Uses Hamcrest style Description
- * interfaces.
- *
- * @param description the Description object to use for reporting the
- * mismatch
- */
- public void describeMismatch(Description description) {
- description.appendText(failureReason);
- }
-
- /**
- * Describe the source object that caused an error, using a Hamcrest
- * Matcher style interface. In this case, it always returns
- * that we are looking for a properly defined utility class.
- *
- * @param description the Description object to use to report the "to"
- * object
- */
- public void describeTo(Description description) {
- description.appendText("a properly defined utility class");
- }
-
- /**
- * Assert that the given class adheres to the utility class rules.
- *
- * @param clazz the class to check
- *
- * @throws java.lang.AssertionError if the class is not a valid
- * utility class
- */
- public static void assertThatClassIsUtility(Class<?> clazz) {
- final UtilityClassChecker checker = new UtilityClassChecker();
- if (!checker.isProperlyDefinedUtilityClass(clazz)) {
- final Description toDescription = new StringDescription();
- final Description mismatchDescription = new StringDescription();
-
- checker.describeTo(toDescription);
- checker.describeMismatch(mismatchDescription);
- final String reason =
- "\n" +
- "Expected: is \"" + toDescription.toString() + "\"\n" +
- " but : was \"" + mismatchDescription.toString() + "\"";
-
- throw new AssertionError(reason);
- }
- }
-}
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/package-info.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/package-info.java
deleted file mode 100644
index 379e4a04..00000000
--- a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utilities to assist in developing JUnit tests.
- */
-package org.onlab.junit;
diff --git a/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks b/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks
deleted file mode 100644
index ba750519..00000000
--- a/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks
+++ /dev/null
Binary files differ
diff --git a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/ImmutableClassCheckerTest.java b/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/ImmutableClassCheckerTest.java
deleted file mode 100644
index cd5a8c1a..00000000
--- a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/ImmutableClassCheckerTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.junit.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * Set of unit tests to check the implementation of the immutable class
- * checker.
- */
-public class ImmutableClassCheckerTest {
- /**
- * Test class for non final class check.
- */
- // CHECKSTYLE IGNORE FinalClass FOR NEXT 1 LINES
- static class NonFinal {
- private NonFinal() { }
- }
-
- /**
- * Check that a non final class correctly produces an error.
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testNonFinalClass() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsImmutable(NonFinal.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("is not final"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class for non private member class check.
- */
- static final class FinalProtectedMember {
- protected final int x = 0;
- }
-
- /**
- * Check that a final class with a non-private member is properly detected.
- *
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testFinalProtectedMember() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsImmutable(FinalProtectedMember.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("a field named 'x' that is not private"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class for non private member class check.
- */
- static final class NotFinalPrivateMember {
- private int x = 0;
- }
-
- /**
- * Check that a final class with a non-final private
- * member is properly detected.
- *
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testNotFinalPrivateMember() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsImmutable(NotFinalPrivateMember.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("a field named 'x' that is not final"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class for non private member class check.
- */
- static final class ClassWithSetter {
- private final int x = 0;
- public void setX(int newX) {
- }
- }
-
- /**
- * Check that a final class with a final private
- * member that is modifyable by a setter is properly detected.
- *
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testClassWithSetter() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsImmutable(ClassWithSetter.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("a class with a setter named 'setX'"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
-}
-
diff --git a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestToolsTest.java b/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestToolsTest.java
deleted file mode 100644
index d11cea0b..00000000
--- a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestToolsTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-import static org.onlab.junit.TestTools.assertAfter;
-
-public class TestToolsTest {
-
- @Test
- public void testSuccess() {
- assertAfter(10, 100, new Runnable() {
- int count = 0;
- @Override
- public void run() {
- if (count++ < 3) {
- assertTrue(false);
- }
- }
- });
- }
-
- @Test(expected = AssertionError.class)
- public void testFailure() {
- assertAfter(100, new Runnable() {
- @Override
- public void run() {
- assertTrue(false);
- }
- });
- }
-}
diff --git a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java b/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java
deleted file mode 100644
index 68e407fc..00000000
--- a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils.TestUtilsException;
-
-/**
- * Test and usage examples for TestUtils.
- */
-public class TestUtilsTest {
-
- /**
- * Test data.
- */
- private static final class TestClass {
-
- @SuppressWarnings("unused")
- private int privateField = 42;
-
- @SuppressWarnings("unused")
- protected int protectedField = 2501; // CHECKSTYLE IGNORE THIS LINE
-
- /**
- * Protected method with multiple argument.
- *
- * @param x simply returns
- * @param y not used
- * @return x
- */
- @SuppressWarnings("unused")
- private int privateMethod(Number x, Long y) {
- return x.intValue();
- }
-
- /**
- * Protected method with no argument.
- *
- * @return int
- */
- @SuppressWarnings("unused")
- protected int protectedMethod() {
- return 42;
- }
-
- /**
- * Method returning array.
- *
- * @param ary random array
- * @return ary
- */
- @SuppressWarnings("unused")
- private int[] arrayReturnMethod(int[] ary) {
- return ary;
- }
-
- /**
- * Method without return value.
- *
- * @param s ignored
- */
- @SuppressWarnings("unused")
- private void voidMethod(String s) {
- System.out.println(s);
- }
- }
-
- private TestClass test;
-
- /**
- * Sets up the test fixture.
- */
- @Before
- public void setUp() {
- test = new TestClass();
- }
-
- /**
- * Example to access private field.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testSetGetPrivateField() throws TestUtilsException {
-
- assertEquals(42, (int) TestUtils.getField(test, "privateField"));
- TestUtils.setField(test, "privateField", 0xDEAD);
- assertEquals(0xDEAD, (int) TestUtils.getField(test, "privateField"));
- }
-
- /**
- * Example to access protected field.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testSetGetProtectedField() throws TestUtilsException {
-
- assertEquals(2501, (int) TestUtils.getField(test, "protectedField"));
- TestUtils.setField(test, "protectedField", 0xBEEF);
- assertEquals(0xBEEF, (int) TestUtils.getField(test, "protectedField"));
- }
-
- /**
- * Example to call private method and multiple parameters.
- * <p/>
- * It also illustrates that paramTypes must match declared type,
- * not the runtime types of arguments.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testCallPrivateMethod() throws TestUtilsException {
-
- int result = TestUtils.callMethod(test, "privateMethod",
- new Class<?>[] {Number.class, Long.class},
- Long.valueOf(42), Long.valueOf(32));
- assertEquals(42, result);
- }
-
- /**
- * Example to call protected method and no parameters.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testCallProtectedMethod() throws TestUtilsException {
-
- int result = TestUtils.callMethod(test, "protectedMethod",
- new Class<?>[] {});
- assertEquals(42, result);
- }
-
- /**
- * Example to call method returning array.
- * <p/>
- * Note: It is not required to receive as Object.
- * Following is just verifying it is not Boxed arrays.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testCallArrayReturnMethod() throws TestUtilsException {
-
- int[] array = {1, 2, 3};
- Object aryResult = TestUtils.callMethod(test, "arrayReturnMethod",
- new Class<?>[] {int[].class}, array);
- assertEquals(int[].class, aryResult.getClass());
- assertArrayEquals(array, (int[]) aryResult);
- }
-
-
- /**
- * Example to call void returning method.
- * <p/>
- * Note: Return value will be null for void methods.
- *
- * @throws TestUtilsException TestUtils error
- */
- @Test
- public void testCallVoidReturnMethod() throws TestUtilsException {
-
- Object voidResult = TestUtils.callMethod(test, "voidMethod",
- String.class, "foobar");
- assertNull(voidResult);
- }
-}
diff --git a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/UtilityClassCheckerTest.java b/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/UtilityClassCheckerTest.java
deleted file mode 100644
index 8c2c5532..00000000
--- a/framework/src/onos/utils/junit/src/test/java/org/onlab/junit/UtilityClassCheckerTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.junit;
-
-import org.junit.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.onlab.junit.UtilityClassChecker.assertThatClassIsUtility;
-
-/**
- * Set of unit tests to check the implementation of the utility class
- * checker.
- */
-public class UtilityClassCheckerTest {
-
- // CHECKSTYLE:OFF test data intentionally not final
- /**
- * Test class for non final class check.
- */
- static class NonFinal {
- private NonFinal() { }
- }
- // CHECKSTYLE:ON
-
- /**
- * Check that a non final class correctly produces an error.
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testNonFinalClass() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsUtility(NonFinal.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("is not final"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class for final no constructor class check.
- */
- static final class FinalNoConstructor {
- }
-
- /**
- * Check that a final class with no declared constructor correctly produces
- * an error. In this case, the compiler generates a default constructor
- * for you, but the constructor is 'protected' and will fail the check.
- *
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testFinalNoConstructorClass() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsUtility(FinalNoConstructor.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("class with a default constructor that " +
- "is not private"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class for class with more than one constructor check.
- */
- static final class TwoConstructors {
- private TwoConstructors() { }
- private TwoConstructors(int x) { }
- }
-
- /**
- * Check that a non static class correctly produces an error.
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testOnlyOneConstructor() throws Exception {
- boolean gotException = false;
- try {
- assertThatClassIsUtility(TwoConstructors.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("more than one constructor"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class with a non private constructor.
- */
- static final class NonPrivateConstructor {
- protected NonPrivateConstructor() { }
- }
-
- /**
- * Check that a class with a non private constructor correctly
- * produces an error.
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testNonPrivateConstructor() throws Exception {
-
- boolean gotException = false;
- try {
- assertThatClassIsUtility(NonPrivateConstructor.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("constructor that is not private"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-
- /**
- * Test class with a non static method.
- */
- static final class NonStaticMethod {
- private NonStaticMethod() { }
- public void aPublicMethod() { }
- }
-
- /**
- * Check that a class with a non static method correctly produces an error.
- * @throws Exception if any of the reflection lookups fail.
- */
- @Test
- public void testNonStaticMethod() throws Exception {
-
- boolean gotException = false;
- try {
- assertThatClassIsUtility(NonStaticMethod.class);
- } catch (AssertionError assertion) {
- assertThat(assertion.getMessage(),
- containsString("one or more non-static methods"));
- gotException = true;
- }
- assertThat(gotException, is(true));
- }
-}
diff --git a/framework/src/onos/utils/misc/pom.xml b/framework/src/onos/utils/misc/pom.xml
deleted file mode 100644
index 39171e95..00000000
--- a/framework/src/onos/utils/misc/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-misc</artifactId>
- <packaging>bundle</packaging>
-
- <description>Miscellaneous ON.Lab utilities</description>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
-
- <!-- TODO: do we still need this here? -->
- <dependency>
- <groupId>com.eclipsesource.minimal-json</groupId>
- <artifactId>minimal-json</artifactId>
- </dependency>
- <dependency>
- <groupId>com.esotericsoftware</groupId>
- <artifactId>kryo</artifactId>
- </dependency>
- <dependency>
- <groupId>io.dropwizard.metrics</groupId>
- <artifactId>metrics-core</artifactId>
- <version>3.1.0</version>
- </dependency>
- <dependency>
- <groupId>io.dropwizard.metrics</groupId>
- <artifactId>metrics-json</artifactId>
- <version>3.1.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java
deleted file mode 100644
index 3e8960e6..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Abstract graph edge implementation.
- */
-public abstract class AbstractEdge<V extends Vertex> implements Edge<V> {
-
- private final V src;
- private final V dst;
-
- /**
- * Creates a new edge between the specified source and destination vertexes.
- *
- * @param src source vertex
- * @param dst destination vertex
- */
- public AbstractEdge(V src, V dst) {
- this.src = checkNotNull(src, "Source vertex cannot be null");
- this.dst = checkNotNull(dst, "Destination vertex cannot be null");
- }
-
- @Override
- public V src() {
- return src;
- }
-
- @Override
- public V dst() {
- return dst;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(src, dst);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof AbstractEdge) {
- final AbstractEdge other = (AbstractEdge) obj;
- return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("src", src)
- .add("dst", dst)
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractGraphPathSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractGraphPathSearch.java
deleted file mode 100644
index e7e2c40d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AbstractGraphPathSearch.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Basis for various graph path search algorithm implementations.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public abstract class AbstractGraphPathSearch<V extends Vertex, E extends Edge<V>>
- implements GraphPathSearch<V, E> {
-
- private double samenessThreshold = Double.MIN_VALUE;
-
- /**
- * Sets a new sameness threshold for comparing cost values; default is
- * is {@link Double#MIN_VALUE}.
- *
- * @param threshold fractional double value
- */
- public void setSamenessThreshold(double threshold) {
- samenessThreshold = threshold;
- }
-
- /**
- * Returns the current sameness threshold for comparing cost values.
- *
- * @return current threshold
- */
- public double samenessThreshold() {
- return samenessThreshold;
- }
-
- /**
- * Default path search result that uses the DefaultPath to convey paths
- * in a graph.
- */
- protected class DefaultResult implements Result<V, E> {
-
- private final V src;
- private final V dst;
- protected final Set<Path<V, E>> paths = new HashSet<>();
- protected final Map<V, Double> costs = new HashMap<>();
- protected final Map<V, Set<E>> parents = new HashMap<>();
- protected final int maxPaths;
-
- /**
- * Creates the result of a single-path search.
- *
- * @param src path source
- * @param dst optional path destination
- */
- public DefaultResult(V src, V dst) {
- this(src, dst, 1);
- }
-
- /**
- * Creates the result of path search.
- *
- * @param src path source
- * @param dst optional path destination
- * @param maxPaths optional limit of number of paths;
- * {@link GraphPathSearch#ALL_PATHS} if no limit
- */
- public DefaultResult(V src, V dst, int maxPaths) {
- checkNotNull(src, "Source cannot be null");
- this.src = src;
- this.dst = dst;
- this.maxPaths = maxPaths;
- }
-
- @Override
- public V src() {
- return src;
- }
-
- @Override
- public V dst() {
- return dst;
- }
-
- @Override
- public Set<Path<V, E>> paths() {
- return paths;
- }
-
- @Override
- public Map<V, Double> costs() {
- return costs;
- }
-
- @Override
- public Map<V, Set<E>> parents() {
- return parents;
- }
-
- /**
- * Indicates whether or not the given vertex has a cost yet.
- *
- * @param v vertex to test
- * @return true if the vertex has cost already
- */
- boolean hasCost(V v) {
- return costs.get(v) != null;
- }
-
- /**
- * Returns the current cost to reach the specified vertex.
- *
- * @param v vertex to reach
- * @return cost to reach the vertex
- */
- double cost(V v) {
- Double c = costs.get(v);
- return c == null ? Double.MAX_VALUE : c;
- }
-
- /**
- * Updates the cost of the vertex using its existing cost plus the
- * cost to traverse the specified edge. If the search is in single
- * path mode, only one path will be accrued.
- *
- * @param vertex vertex to update
- * @param edge edge through which vertex is reached
- * @param cost current cost to reach the vertex from the source
- * @param replace true to indicate that any accrued edges are to be
- * cleared; false to indicate that the edge should be
- * added to the previously accrued edges as they yield
- * the same cost
- */
- void updateVertex(V vertex, E edge, double cost, boolean replace) {
- costs.put(vertex, cost);
- if (edge != null) {
- Set<E> edges = parents.get(vertex);
- if (edges == null) {
- edges = new HashSet<>();
- parents.put(vertex, edges);
- }
- if (replace) {
- edges.clear();
- }
- if (maxPaths == ALL_PATHS || edges.size() < maxPaths) {
- edges.add(edge);
- }
- }
- }
-
- /**
- * Removes the set of parent edges for the specified vertex.
- *
- * @param v vertex
- */
- void removeVertex(V v) {
- parents.remove(v);
- }
-
- /**
- * If possible, relax the specified edge using the supplied base cost
- * and edge-weight function.
- *
- * @param edge edge to be relaxed
- * @param cost base cost to reach the edge destination vertex
- * @param ew optional edge weight function
- * @param forbidNegatives if true negative values will forbid the link
- * @return true if the edge was relaxed; false otherwise
- */
- boolean relaxEdge(E edge, double cost, EdgeWeight<V, E> ew,
- boolean... forbidNegatives) {
- V v = edge.dst();
- double oldCost = cost(v);
- double hopCost = ew == null ? 1.0 : ew.weight(edge);
- if (hopCost < 0 && forbidNegatives.length == 1 && forbidNegatives[0]) {
- return false;
- }
-
- double newCost = cost + hopCost;
- boolean relaxed = newCost < oldCost;
- boolean same = Math.abs(newCost - oldCost) <= samenessThreshold;
- if (same || relaxed) {
- updateVertex(v, edge, newCost, !same);
- }
- return relaxed;
- }
-
- /**
- * Builds a set of paths for the specified src/dst vertex pair.
- */
- protected void buildPaths() {
- Set<V> destinations = new HashSet<>();
- if (dst == null) {
- destinations.addAll(costs.keySet());
- } else {
- destinations.add(dst);
- }
-
- // Build all paths between the source and all requested destinations.
- for (V v : destinations) {
- // Ignore the source, if it is among the destinations.
- if (!v.equals(src)) {
- buildAllPaths(this, src, v, maxPaths);
- }
- }
- }
-
- }
-
- /**
- * Builds a set of all paths between the source and destination using the
- * graph search result by applying breadth-first search through the parent
- * edges and vertex costs.
- *
- * @param result graph search result
- * @param src source vertex
- * @param dst destination vertex
- * @param maxPaths limit on the number of paths built;
- * {@link GraphPathSearch#ALL_PATHS} if no limit
- */
- private void buildAllPaths(DefaultResult result, V src, V dst, int maxPaths) {
- DefaultMutablePath<V, E> basePath = new DefaultMutablePath<>();
- basePath.setCost(result.cost(dst));
-
- Set<DefaultMutablePath<V, E>> pendingPaths = new HashSet<>();
- pendingPaths.add(basePath);
-
- while (!pendingPaths.isEmpty() &&
- (maxPaths == ALL_PATHS || result.paths.size() < maxPaths)) {
- Set<DefaultMutablePath<V, E>> frontier = new HashSet<>();
-
- for (DefaultMutablePath<V, E> path : pendingPaths) {
- // For each pending path, locate its first vertex since we
- // will be moving backwards from it.
- V firstVertex = firstVertex(path, dst);
-
- // If the first vertex is our expected source, we have reached
- // the beginning, so add the this path to the result paths.
- if (firstVertex.equals(src)) {
- path.setCost(result.cost(dst));
- result.paths.add(new DefaultPath<>(path.edges(), path.cost()));
-
- } else {
- // If we have not reached the beginning, i.e. the source,
- // fetch the set of edges leading to the first vertex of
- // this pending path; if there are none, abandon processing
- // this path for good.
- Set<E> firstVertexParents = result.parents.get(firstVertex);
- if (firstVertexParents == null || firstVertexParents.isEmpty()) {
- break;
- }
-
- // Now iterate over all the edges and for each of them
- // cloning the current path and then insert that edge to
- // the path and then add that path to the pending ones.
- // When processing the last edge, modify the current
- // pending path rather than cloning a new one.
- Iterator<E> edges = firstVertexParents.iterator();
- while (edges.hasNext()) {
- E edge = edges.next();
- boolean isLast = !edges.hasNext();
- DefaultMutablePath<V, E> pendingPath = isLast ? path : new DefaultMutablePath<>(path);
- pendingPath.insertEdge(edge);
- frontier.add(pendingPath);
- }
- }
- }
-
- // All pending paths have been scanned so promote the next frontier
- pendingPaths = frontier;
- }
- }
-
- // Returns the first vertex of the specified path. This is either the source
- // of the first edge or, if there are no edges yet, the given destination.
- private V firstVertex(Path<V, E> path, V dst) {
- return path.edges().isEmpty() ? dst : path.edges().get(0).src();
- }
-
- /**
- * Checks the specified path search arguments for validity.
- *
- * @param graph graph; must not be null
- * @param src source vertex; must not be null and belong to graph
- * @param dst optional target vertex; must belong to graph
- */
- protected void checkArguments(Graph<V, E> graph, V src, V dst) {
- checkNotNull(graph, "Graph cannot be null");
- checkNotNull(src, "Source cannot be null");
- Set<V> vertices = graph.getVertexes();
- checkArgument(vertices.contains(src), "Source not in the graph");
- checkArgument(dst == null || vertices.contains(dst),
- "Destination not in graph");
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java
deleted file mode 100644
index 3890dcf8..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable graph implemented using adjacency lists.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public class AdjacencyListsGraph<V extends Vertex, E extends Edge<V>>
- implements Graph<V, E> {
-
- private final Set<V> vertexes;
- private final Set<E> edges;
-
- private final ImmutableSetMultimap<V, E> sources;
- private final ImmutableSetMultimap<V, E> destinations;
-
- /**
- * Creates a graph comprising of the specified vertexes and edges.
- *
- * @param vertexes set of graph vertexes
- * @param edges set of graph edges
- */
- public AdjacencyListsGraph(Set<V> vertexes, Set<E> edges) {
- checkNotNull(vertexes, "Vertex set cannot be null");
- checkNotNull(edges, "Edge set cannot be null");
-
- // Record ingress/egress edges for each vertex.
- ImmutableSetMultimap.Builder<V, E> srcMap = ImmutableSetMultimap.builder();
- ImmutableSetMultimap.Builder<V, E> dstMap = ImmutableSetMultimap.builder();
-
- // Also make sure that all edge end-points are added as vertexes
- ImmutableSet.Builder<V> actualVertexes = ImmutableSet.builder();
- actualVertexes.addAll(vertexes);
-
- for (E edge : edges) {
- srcMap.put(edge.src(), edge);
- actualVertexes.add(edge.src());
- dstMap.put(edge.dst(), edge);
- actualVertexes.add(edge.dst());
- }
-
- // Make an immutable copy of the edge and vertex sets
- this.edges = ImmutableSet.copyOf(edges);
- this.vertexes = actualVertexes.build();
-
- // Build immutable copies of sources and destinations edge maps
- sources = srcMap.build();
- destinations = dstMap.build();
- }
-
- @Override
- public Set<V> getVertexes() {
- return vertexes;
- }
-
- @Override
- public Set<E> getEdges() {
- return edges;
- }
-
- @Override
- public Set<E> getEdgesFrom(V src) {
- return sources.get(src);
- }
-
- @Override
- public Set<E> getEdgesTo(V dst) {
- return destinations.get(dst);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof AdjacencyListsGraph) {
- AdjacencyListsGraph that = (AdjacencyListsGraph) obj;
- return this.getClass() == that.getClass() &&
- Objects.equals(this.vertexes, that.vertexes) &&
- Objects.equals(this.edges, that.edges);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(vertexes, edges);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("vertexes", vertexes)
- .add("edges", edges)
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BellmanFordGraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BellmanFordGraphSearch.java
deleted file mode 100644
index dc741f73..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BellmanFordGraphSearch.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Bellman-Ford graph search algorithm for locating shortest-paths in
- * directed graphs that may contain negative cycles.
- */
-public class BellmanFordGraphSearch<V extends Vertex, E extends Edge<V>>
- extends AbstractGraphPathSearch<V, E> {
-
- @Override
- public Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
- checkArguments(graph, src, dst);
-
- // Prepare the graph search result.
- DefaultResult result = new DefaultResult(src, dst, maxPaths);
-
- // The source vertex has cost 0, of course.
- result.updateVertex(src, null, 0.0, true);
-
- int max = graph.getVertexes().size() - 1;
- for (int i = 0; i < max; i++) {
- // Relax, if possible, all egress edges of the current vertex.
- for (E edge : graph.getEdges()) {
- if (result.hasCost(edge.src())) {
- result.relaxEdge(edge, result.cost(edge.src()), weight);
- }
- }
- }
-
- // Remove any vertexes reached by traversing edges with negative weights.
- for (E edge : graph.getEdges()) {
- if (result.hasCost(edge.src())) {
- if (result.relaxEdge(edge, result.cost(edge.src()), weight)) {
- result.removeVertex(edge.dst());
- }
- }
- }
-
- // Finally, but the paths on the search result and return.
- result.buildPaths();
- return result;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BreadthFirstSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BreadthFirstSearch.java
deleted file mode 100644
index 40c8735b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/BreadthFirstSearch.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Implementation of the BFS algorithm.
- */
-public class BreadthFirstSearch<V extends Vertex, E extends Edge<V>>
- extends AbstractGraphPathSearch<V, E> {
-
- @Override
- public Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
- checkArguments(graph, src, dst);
-
- // Prepare the graph result.
- DefaultResult result = new DefaultResult(src, dst, maxPaths);
-
- // Setup the starting frontier with the source as the sole vertex.
- Set<V> frontier = new HashSet<>();
- result.updateVertex(src, null, 0.0, true);
- frontier.add(src);
-
- boolean reachedEnd = false;
- while (!reachedEnd && !frontier.isEmpty()) {
- // Prepare the next frontier.
- Set<V> next = new HashSet<>();
-
- // Visit all vertexes in the current frontier.
- for (V vertex : frontier) {
- double cost = result.cost(vertex);
-
- // Visit all egress edges of the current frontier vertex.
- for (E edge : graph.getEdgesFrom(vertex)) {
- V nextVertex = edge.dst();
- if (!result.hasCost(nextVertex)) {
- // If this vertex has not been visited yet, update it.
- double newCost = cost + (weight == null ? 1.0 : weight.weight(edge));
- result.updateVertex(nextVertex, edge, newCost, true);
- // If we have reached our intended destination, bail.
- if (nextVertex.equals(dst)) {
- reachedEnd = true;
- break;
- }
- next.add(nextVertex);
- }
-
- if (reachedEnd) {
- break;
- }
- }
- }
-
- // Promote the next frontier.
- frontier = next;
- }
-
- // Finally, but the paths on the search result and return.
- result.buildPaths();
- return result;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java
deleted file mode 100644
index ad7e8402..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Simple concrete implementation of a directed graph path.
- */
-public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements MutablePath<V, E> {
-
- private final List<E> edges = new ArrayList<>();
- private double cost = 0.0;
-
- /**
- * Creates a new empty path.
- */
- public DefaultMutablePath() {
- }
-
- /**
- * Creates a new path as a copy of another path.
- *
- * @param path path to be copied
- */
- public DefaultMutablePath(Path<V, E> path) {
- checkNotNull(path, "Path cannot be null");
- this.cost = path.cost();
- edges.addAll(path.edges());
- }
-
- @Override
- public V src() {
- return edges.isEmpty() ? null : edges.get(0).src();
- }
-
- @Override
- public V dst() {
- return edges.isEmpty() ? null : edges.get(edges.size() - 1).dst();
- }
-
- @Override
- public double cost() {
- return cost;
- }
-
- @Override
- public List<E> edges() {
- return ImmutableList.copyOf(edges);
- }
-
- @Override
- public void setCost(double cost) {
- this.cost = cost;
- }
-
- @Override
- public Path<V, E> toImmutable() {
- return new DefaultPath<>(edges, cost);
- }
-
- @Override
- public void insertEdge(E edge) {
- checkNotNull(edge, "Edge cannot be null");
- checkArgument(edges.isEmpty() || src().equals(edge.dst()),
- "Edge destination must be the same as the current path source");
- edges.add(0, edge);
- }
-
- @Override
- public void appendEdge(E edge) {
- checkNotNull(edge, "Edge cannot be null");
- checkArgument(edges.isEmpty() || dst().equals(edge.src()),
- "Edge source must be the same as the current path destination");
- edges.add(edge);
- }
-
- @Override
- public void removeEdge(E edge) {
- checkArgument(edge.src().equals(edge.dst()) ||
- edges.indexOf(edge) == 0 ||
- edges.lastIndexOf(edge) == edges.size() - 1,
- "Edge must be at start or end of path, or it must be a cyclic edge");
- edges.remove(edge);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("src", src())
- .add("dst", dst())
- .add("cost", cost)
- .add("edges", edges)
- .toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(edges, cost);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof DefaultMutablePath) {
- final DefaultMutablePath other = (DefaultMutablePath) obj;
- return Objects.equals(this.cost, other.cost) &&
- Objects.equals(this.edges, other.edges);
- }
- return false;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java
deleted file mode 100644
index 816fb161..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Simple concrete implementation of a directed graph path.
- */
-public class DefaultPath<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
-
- private final V src;
- private final V dst;
- private final List<E> edges;
- private double cost = 0.0;
-
- /**
- * Creates a new path from the specified list of edges and cost.
- *
- * @param edges list of path edges
- * @param cost path cost as a unit-less number
- */
- public DefaultPath(List<E> edges, double cost) {
- checkNotNull(edges, "Edges list must not be null");
- checkArgument(!edges.isEmpty(), "There must be at least one edge");
- this.edges = ImmutableList.copyOf(edges);
- this.src = edges.get(0).src();
- this.dst = edges.get(edges.size() - 1).dst();
- this.cost = cost;
- }
-
- @Override
- public V src() {
- return src;
- }
-
- @Override
- public V dst() {
- return dst;
- }
-
- @Override
- public double cost() {
- return cost;
- }
-
- @Override
- public List<E> edges() {
- return Collections.unmodifiableList(edges);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("src", src)
- .add("dst", dst)
- .add("cost", cost)
- .add("edges", edges)
- .toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(src, dst, edges, cost);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof DefaultPath) {
- final DefaultPath other = (DefaultPath) obj;
- return Objects.equals(this.src, other.src) &&
- Objects.equals(this.dst, other.dst) &&
- Objects.equals(this.cost, other.cost) &&
- Objects.equals(this.edges, other.edges);
- }
- return false;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DepthFirstSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DepthFirstSearch.java
deleted file mode 100644
index 91b5108f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DepthFirstSearch.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * DFS graph search algorithm implemented via iteration rather than recursion.
- */
-public class DepthFirstSearch<V extends Vertex, E extends Edge<V>>
- extends AbstractGraphPathSearch<V, E> {
-
- /**
- * Graph edge types as classified by the DFS algorithm.
- */
- public static enum EdgeType {
- TREE_EDGE, FORWARD_EDGE, BACK_EDGE, CROSS_EDGE
- }
-
- @Override
- public SpanningTreeResult search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
- checkArguments(graph, src, dst);
-
- // Prepare the search result.
- SpanningTreeResult result = new SpanningTreeResult(src, dst, maxPaths);
-
- // The source vertex has cost 0, of course.
- result.updateVertex(src, null, 0.0, true);
-
- // Track finished vertexes and keep a stack of vertexes that have been
- // started; start this stack with the source on it.
- Set<V> finished = new HashSet<>();
- Stack<V> stack = new Stack<>();
- stack.push(src);
-
- while (!stack.isEmpty()) {
- V vertex = stack.peek();
- if (vertex.equals(dst)) {
- // If we have reached our destination, bail.
- break;
- }
-
- double cost = result.cost(vertex);
- boolean tangent = false;
-
- // Visit all egress edges of the current vertex.
- for (E edge : graph.getEdgesFrom(vertex)) {
- // If we have seen the edge already, skip it.
- if (result.isEdgeMarked(edge)) {
- continue;
- }
-
- // Examine the destination of the current edge.
- V nextVertex = edge.dst();
- if (!result.hasCost(nextVertex)) {
- // If this vertex have not finished this vertex yet,
- // not started it, then start it as a tree-edge.
- result.markEdge(edge, EdgeType.TREE_EDGE);
- double newCost = cost + (weight == null ? 1.0 : weight.weight(edge));
- result.updateVertex(nextVertex, edge, newCost, true);
- stack.push(nextVertex);
- tangent = true;
- break;
-
- } else if (!finished.contains(nextVertex)) {
- // We started the vertex, but did not yet finish it, so
- // it must be a back-edge.
- result.markEdge(edge, EdgeType.BACK_EDGE);
- } else {
- // The target has been finished already, so what we have
- // here is either a forward-edge or a cross-edge.
- result.markEdge(edge, isForwardEdge(result, edge) ?
- EdgeType.FORWARD_EDGE : EdgeType.CROSS_EDGE);
- }
- }
-
- // If we have not been sent on a tangent search and reached the
- // end of the current scan normally, mark the node as finished
- // and pop it off the vertex stack.
- if (!tangent) {
- finished.add(vertex);
- stack.pop();
- }
- }
-
- // Finally, but the paths on the search result and return.
- result.buildPaths();
- return result;
- }
-
- /**
- * Determines whether the specified edge is a forward edge using the
- * accumulated set of parent edges for each vertex.
- *
- * @param result search result
- * @param edge edge to be classified
- * @return true if the edge is a forward edge
- */
- protected boolean isForwardEdge(DefaultResult result, E edge) {
- // Follow the parent edges until we hit the edge source vertex
- V target = edge.src();
- V vertex = edge.dst();
- Set<E> parentEdges;
- while ((parentEdges = result.parents.get(vertex)) != null) {
- for (E parentEdge : parentEdges) {
- vertex = parentEdge.src();
- if (vertex.equals(target)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Graph search result which includes edge classification for building
- * a spanning tree.
- */
- public class SpanningTreeResult extends DefaultResult {
-
- protected final Map<E, EdgeType> edges = new HashMap<>();
-
- /**
- * Creates a new spanning tree result.
- *
- * @param src search source
- * @param dst optional search destination
- * @param maxPaths limit on the number of paths
- */
- public SpanningTreeResult(V src, V dst, int maxPaths) {
- super(src, dst, maxPaths);
- }
-
- /**
- * Returns the map of edge type.
- *
- * @return edge to edge type bindings
- */
- public Map<E, EdgeType> edges() {
- return edges;
- }
-
- /**
- * Indicates whether or not the edge has been marked with type.
- *
- * @param edge edge to test
- * @return true if the edge has been marked already
- */
- boolean isEdgeMarked(E edge) {
- return edges.containsKey(edge);
- }
-
- /**
- * Marks the edge with the specified type.
- *
- * @param edge edge to mark
- * @param type edge type
- */
- void markEdge(E edge, EdgeType type) {
- edges.put(edge, type);
- }
-
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DijkstraGraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DijkstraGraphSearch.java
deleted file mode 100644
index b1892ee1..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DijkstraGraphSearch.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Set;
-
-/**
- * Dijkstra shortest-path graph search algorithm capable of finding not just
- * one, but all shortest paths between the source and destinations.
- */
-public class DijkstraGraphSearch<V extends Vertex, E extends Edge<V>>
- extends AbstractGraphPathSearch<V, E> {
-
- @Override
- public Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
- checkArguments(graph, src, dst);
-
- // Use the default result to remember cumulative costs and parent
- // edges to each each respective vertex.
- DefaultResult result = new DefaultResult(src, dst, maxPaths);
-
- // Cost to reach the source vertex is 0 of course.
- result.updateVertex(src, null, 0.0, false);
-
- if (graph.getEdges().isEmpty()) {
- result.buildPaths();
- return result;
- }
-
- // Use the min priority queue to progressively find each nearest
- // vertex until we reach the desired destination, if one was given,
- // or until we reach all possible destinations.
- Heap<V> minQueue = createMinQueue(graph.getVertexes(),
- new PathCostComparator(result));
- while (!minQueue.isEmpty()) {
- // Get the nearest vertex
- V nearest = minQueue.extractExtreme();
- if (nearest.equals(dst)) {
- break;
- }
-
- // Find its cost and use it to determine if the vertex is reachable.
- double cost = result.cost(nearest);
- if (cost < Double.MAX_VALUE) {
- // If the vertex is reachable, relax all its egress edges.
- for (E e : graph.getEdgesFrom(nearest)) {
- result.relaxEdge(e, cost, weight, true);
- }
- }
-
- // Re-prioritize the min queue.
- minQueue.heapify();
- }
-
- // Now construct a set of paths from the results.
- result.buildPaths();
- return result;
- }
-
- // Compares path weights using their accrued costs; used for sorting the
- // min priority queue.
- private final class PathCostComparator implements Comparator<V> {
- private final DefaultResult result;
-
- private PathCostComparator(DefaultResult result) {
- this.result = result;
- }
-
- @Override
- public int compare(V v1, V v2) {
- double delta = result.cost(v2) - result.cost(v1);
- return delta < 0 ? -1 : (delta > 0 ? 1 : 0);
- }
- }
-
- // Creates a min priority queue from the specified vertexes and comparator.
- private Heap<V> createMinQueue(Set<V> vertexes, Comparator<V> comparator) {
- return new Heap<>(new ArrayList<>(vertexes), comparator);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java
deleted file mode 100644
index dfa150e3..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.onlab.graph;
-
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Pair of disjoint paths.
- *
- * @param <V> type of vertex
- * @param <E> type of edge
- */
-public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
-
- private final Path<V, E> primary, secondary;
- private boolean primaryActive = true;
-
- /**
- * Creates a disjoint path pair from two paths.
- *
- * @param primary primary path
- * @param secondary secondary path
- */
- public DisjointPathPair(Path<V, E> primary, Path<V, E> secondary) {
- this.primary = primary;
- this.secondary = secondary;
- }
-
- @Override
- public V src() {
- return primary.src();
- }
-
- @Override
- public V dst() {
- return primary.dst();
- }
-
- /**
- * Returns the primary path.
- *
- * @return primary path
- */
- public Path<V, E> primary() {
- return primary;
- }
-
- /**
- * Returns the secondary path.
- *
- * @return primary path
- */
- public Path<V, E> secondary() {
- return secondary;
- }
-
- @Override
- public double cost() {
- return hasBackup() ? primary.cost() + secondary.cost() : primary.cost();
- }
-
- @Override
- public List<E> edges() {
- return primaryActive || !hasBackup() ? primary.edges() : secondary.edges();
- }
-
- /**
- * Checks if this path pair contains a backup/secondary path.
- *
- * @return boolean representing whether it has backup
- */
- public boolean hasBackup() {
- return secondary != null;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("src", src())
- .add("dst", dst())
- .add("cost", cost())
- .add("edges", edges())
- .toString();
- }
-
- @Override
- public int hashCode() {
- // Note: DisjointPathPair with primary and secondary swapped
- // must result in same hashCode
- return hasBackup() ? primary.hashCode() + secondary.hashCode() :
- Objects.hash(primary);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof DisjointPathPair) {
- final DisjointPathPair other = (DisjointPathPair) obj;
- return Objects.equals(this.src(), other.src()) &&
- Objects.equals(this.dst(), other.dst()) &&
- (Objects.equals(this.primary, other.primary) &&
- Objects.equals(this.secondary, other.secondary)) ||
- (Objects.equals(this.primary, other.secondary) &&
- Objects.equals(this.secondary, other.primary));
- }
- return false;
- }
-
- /**
- * Returns number of paths inside this path pair object.
- *
- * @return number of paths
- */
- public int size() {
- return hasBackup() ? 2 : 1;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Edge.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Edge.java
deleted file mode 100644
index 1bbfbf99..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Edge.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Representation of a graph edge.
- *
- * @param <V> vertex type
- */
-public interface Edge<V extends Vertex> {
-
- /**
- * Returns the edge source vertex.
- *
- * @return source vertex
- */
- V src();
-
- /**
- * Returns the edge destination vertex.
- *
- * @return destination vertex
- */
- V dst();
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/EdgeWeight.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/EdgeWeight.java
deleted file mode 100644
index 975b59c7..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/EdgeWeight.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Abstraction of a graph edge weight function.
- */
-public interface EdgeWeight<V extends Vertex, E extends Edge<V>> {
-
- /**
- * Returns the weight of the given edge as a unit-less number.
- *
- * @param edge edge to be weighed
- * @return edge weight as a unit-less number
- */
- double weight(E edge);
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java
deleted file mode 100644
index a0e0570d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Interface representing an "organism": a specific solution
- * to a problem where solutions can be evaluated in terms
- * of fitness. These organisms can be used to represent any
- * class of problem that genetic algorithms can be run on.
- */
-interface GAOrganism {
- /**
- * A fitness function that determines how
- * optimal a given organism is.
- *
- * @return fitness of organism
- */
- double fitness();
-
- /**
- * A method that slightly mutates an organism.
- */
- void mutate();
-
- /**
- * Creates a new random organism.
- *
- * @return random GAOrganism
- */
- GAOrganism random();
-
- /**
- * Returns a child organism that is the result
- * of "crossing" this organism with another.
- *
- * @param other Other organism to cross with
- * @return child organism
- */
- GAOrganism crossWith(GAOrganism other);
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java
deleted file mode 100644
index c5fa9b45..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Represents a population of GAOrganisms. This class can be used
- * to run a genetic algorithm on the population and return the fittest solutions.
- */
-class GAPopulation<Organism extends GAOrganism> extends ArrayList<Organism> {
- Random r = new Random();
-
- /**
- * Steps the population through one generation. The 75% least fit
- * organisms are killed off and replaced with the children of the
- * 25% (as well as some "random" newcomers).
- */
- void step() {
- Collections.sort(this, (org1, org2) -> {
- double d = org1.fitness() - org2.fitness();
- if (d < 0) {
- return -1;
- } else if (d == 0) {
- return 0;
- }
- return 1;
- });
- int maxSize = size();
- for (int i = size() - 1; i > maxSize / 4; i--) {
- remove(i);
- }
- for (Organism org: this) {
- if (r.nextBoolean()) {
- org.mutate();
- }
- }
- while (size() < maxSize * 4 / 5) {
- Organism org1 = get(r.nextInt(size()));
- Organism org2 = get(r.nextInt(size()));
- add((Organism) org1.crossWith(org2));
- }
-
- while (size() < maxSize) {
- Organism org1 = get(r.nextInt(size()));
- add((Organism) org1.random());
- }
- }
-
- /**
- * Runs GA for the specified number of iterations, and returns
- * a sample of the resulting population of solutions.
- *
- * @param generations Number of generations to run GA for
- * @param populationSize Population size of GA
- * @param sample Number of solutions to ask for
- * @param template Template GAOrganism to seed the population with
- * @return ArrayList containing sample number of organisms
- */
- List<Organism> runGA(int generations, int populationSize, int sample, Organism template) {
- for (int i = 0; i < populationSize; i++) {
- add((Organism) template.random());
- }
-
- for (int i = 0; i < generations; i++) {
- step();
- }
- for (int i = size() - 1; i >= sample; i--) {
- remove(i);
- }
- return new ArrayList<>(this);
- }
-}
-
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Graph.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Graph.java
deleted file mode 100644
index bc7853ec..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Graph.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-
-import java.util.Set;
-
-/**
- * Abstraction of a directed graph structure.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public interface Graph<V extends Vertex, E extends Edge> {
-
- /**
- * Returns the set of vertexes comprising the graph.
- *
- * @return set of vertexes
- */
- Set<V> getVertexes();
-
- /**
- * Returns the set of edges comprising the graph.
- *
- * @return set of edges
- */
- Set<E> getEdges();
-
- /**
- * Returns all edges leading out from the specified source vertex.
- *
- * @param src source vertex
- * @return set of egress edges; empty if no such edges
- */
- Set<E> getEdgesFrom(V src);
-
- /**
- * Returns all edges leading towards the specified destination vertex.
- *
- * @param dst destination vertex
- * @return set of ingress vertexes; empty if no such edges
- */
- Set<E> getEdgesTo(V dst);
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphPathSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphPathSearch.java
deleted file mode 100644
index caebce47..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphPathSearch.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Representation of a graph path search algorithm.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public interface GraphPathSearch<V extends Vertex, E extends Edge<V>> {
-
- static int ALL_PATHS = -1;
-
- /**
- * Abstraction of a path search result.
- */
- interface Result<V extends Vertex, E extends Edge<V>> {
-
- /**
- * Returns the search source.
- *
- * @return search source
- */
- V src();
-
- /**
- * Returns the search destination, if was was given.
- *
- * @return optional search destination
- */
- V dst();
-
- /**
- * Returns the set of paths produced as a result of the graph search.
- *
- * @return set of paths
- */
- Set<Path<V, E>> paths();
-
- /**
- * Returns bindings of each vertex to its parent edges in the path.
- *
- * @return map of vertex to its parent edge bindings
- */
- Map<V, Set<E>> parents();
-
- /**
- * Return a bindings of each vertex to its cost in the path.
- *
- * @return map of vertex to path cost bindings
- */
- Map<V, Double> costs();
- }
-
- /**
- * Searches the specified graph for paths between vertices.
- *
- * @param graph graph to be searched
- * @param src optional source vertex
- * @param dst optional destination vertex; if null paths to all vertex
- * destinations will be searched
- * @param weight optional edge-weight; if null cost of each edge will be
- * assumed to be 1.0
- * @param maxPaths limit on number of paths; {@link GraphPathSearch#ALL_PATHS} if no limit
- * @return search results
- */
- Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths);
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphSearch.java
deleted file mode 100644
index ca369a7d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/GraphSearch.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Representation of a graph search algorithm and its outcome.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public interface GraphSearch<V extends Vertex, E extends Edge<V>> {
-
- /**
- * Notion of a graph search result.
- */
- interface Result<V extends Vertex, E extends Edge<V>> {
- }
-
- /**
- * Searches the specified graph.
- *
- * @param graph graph to be searched
- * @param weight optional edge-weight; if null cost of each edge will be
- * assumed to be 1.0
- *
- * @return search results
- */
- Result search(Graph<V, E> graph, EdgeWeight<V, E> weight);
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Heap.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Heap.java
deleted file mode 100644
index ebb1a60b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Heap.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Implementation of an array-backed heap structure whose sense of order is
- * imposed by the provided comparator.
- * <p>
- * While this provides similar functionality to {@link java.util.PriorityQueue}
- * data structure, one key difference is that external entities can control
- * when to restore the heap property, which is done through invocation of the
- * {@link #heapify} method.
- * </p>
- * <p>
- * This class is not thread-safe and care must be taken to prevent concurrent
- * modifications.
- * </p>
- *
- * @param <T> type of the items on the heap
- */
-public class Heap<T> {
-
- private final List<T> data;
- private final Comparator<T> comparator;
-
- /**
- * Creates a new heap backed by the specified list. In the interest of
- * efficiency, the list should be array-backed. Also, for the same reason,
- * the data is not copied and therefore, the caller must assure that the
- * backing data is not altered in any way.
- *
- * @param data backing data list
- * @param comparator comparator for ordering the heap items
- */
- public Heap(List<T> data, Comparator<T> comparator) {
- this.data = checkNotNull(data, "Data cannot be null");
- this.comparator = checkNotNull(comparator, "Comparator cannot be null");
- heapify();
- }
-
- /**
- * Restores the heap property by re-arranging the elements in the backing
- * array as necessary following any heap modifications.
- */
- public void heapify() {
- for (int i = data.size() / 2; i >= 0; i--) {
- heapify(i);
- }
- }
-
- /**
- * Returns the current size of the heap.
- *
- * @return number of items in the heap
- */
- public int size() {
- return data.size();
- }
-
- /**
- * Returns true if there are no items in the heap.
- *
- * @return true if heap is empty
- */
- public boolean isEmpty() {
- return data.isEmpty();
- }
-
- /**
- * Returns the most extreme item in the heap.
- *
- * @return heap extreme or null if the heap is empty
- */
- public T extreme() {
- return data.isEmpty() ? null : data.get(0);
- }
-
- /**
- * Extracts and returns the most extreme item from the heap.
- *
- * @return heap extreme or null if the heap is empty
- */
- public T extractExtreme() {
- if (!isEmpty()) {
- T extreme = extreme();
-
- data.set(0, data.get(data.size() - 1));
- data.remove(data.size() - 1);
- heapify();
- return extreme;
- }
- return null;
- }
-
- /**
- * Inserts the specified item into the heap and returns the modified heap.
- *
- * @param item item to be inserted
- * @return the heap self
- * @throws IllegalArgumentException if the heap is already full
- */
- public Heap<T> insert(T item) {
- data.add(item);
- bubbleUp();
- return this;
- }
-
- /**
- * Returns iterator to traverse the heap level-by-level. This iterator
- * does not permit removal of items.
- *
- * @return non-destructive heap iterator
- */
- public Iterator<T> iterator() {
- return ImmutableList.copyOf(data).iterator();
- }
-
- // Bubbles up the last item in the heap to its proper position to restore
- // the heap property.
- private void bubbleUp() {
- int child = data.size() - 1;
- while (child > 0) {
- int parent = child / 2;
- if (comparator.compare(data.get(child), data.get(parent)) < 0) {
- break;
- }
- swap(child, parent);
- child = parent;
- }
- }
-
- // Restores the heap property of the specified heap layer.
- private void heapify(int i) {
- int left = 2 * i + 1;
- int right = 2 * i;
- int extreme = i;
-
- if (left < data.size() &&
- comparator.compare(data.get(extreme), data.get(left)) < 0) {
- extreme = left;
- }
-
- if (right < data.size() &&
- comparator.compare(data.get(extreme), data.get(right)) < 0) {
- extreme = right;
- }
-
- if (extreme != i) {
- swap(i, extreme);
- heapify(extreme);
- }
- }
-
- // Swaps two heap items identified by their respective indexes.
- private void swap(int i, int k) {
- T aux = data.get(i);
- data.set(i, data.get(k));
- data.set(k, aux);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Heap) {
- Heap that = (Heap) obj;
- return this.getClass() == that.getClass() &&
- Objects.equals(this.comparator, that.comparator) &&
- Objects.deepEquals(this.data, that.data);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(comparator, data);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("data", data)
- .add("comparator", comparator)
- .toString();
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
deleted file mode 100644
index 820e912c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.ArrayList;
-//import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-//import java.util.Map;
-//import java.util.PriorityQueue;
-import java.util.Set;
-
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * K-shortest-path graph search algorithm capable of finding not just one,
- * but K shortest paths with ascending order between the source and destinations.
- */
-
-public class KshortestPathSearch<V extends Vertex, E extends Edge<V>> {
-
- // Define class variables.
- private Graph<V, E> immutableGraph;
- private MutableGraph<V, E> mutableGraph;
- private List<List<E>> pathResults = new ArrayList<List<E>>();
- private List<List<E>> pathCandidates = new ArrayList<List<E>>();
- private V source;
- private V sink;
- private int numK = 0;
- private EdgeWeight<V, E> weight = null;
- // private PriorityQueue<List<E>> pathCandidates = new PriorityQueue<List<E>>();
-
- // Initialize the graph.
- public KshortestPathSearch(Graph<V, E> graph) {
- immutableGraph = graph;
- mutableGraph = new MutableAdjacencyListsGraph<>(graph.getVertexes(),
- graph.getEdges());
- }
-
- public List<List<E>> search(V src,
- V dst,
- EdgeWeight<V, E> wei,
- int k) {
-
- weight = wei;
- source = src;
- sink = dst;
- numK = k;
- // pathCandidates = new PriorityQueue<List<E>>();
-
- pathResults.clear();
- pathCandidates.clear();
-
- // Double check the parameters
- checkArguments(immutableGraph, src, dst, numK);
-
- // DefaultResult result = new DefaultResult(src, dst);
-
- searchKShortestPaths();
-
- return pathResults;
- }
-
- private void checkArguments(Graph<V, E> graph, V src, V dst, int k) {
- if (graph == null) {
- throw new NullPointerException("graph is null");
- }
- if (!graph.getVertexes().contains(src)) {
- throw new NullPointerException("source node does not exist");
- }
- if (!graph.getVertexes().contains(dst)) {
- throw new NullPointerException("target node does not exist");
- }
- if (k <= 0) {
- throw new NullPointerException("K is negative or 0");
- }
- if (weight == null) {
- throw new NullPointerException("the cost matrix is null");
- }
- }
-
- private void searchKShortestPaths() {
- // Step 1: find the shortest path.
- List<E> shortestPath = searchShortestPath(immutableGraph, source, sink);
- // no path exists, exit.
- if (shortestPath == null) {
- return;
- }
-
- // Step 2: update the results.
- pathResults.add(shortestPath);
- // pathCandidates.add(shortestPath);
-
- // Step 3: find the other K-1 paths.
- while (/*pathCandidates.size() > 0 &&*/pathResults.size() < numK) {
- // 3.1 the spur node ranges from the first node to the last node in the previous k-shortest path.
- List<E> lastPath = pathResults.get(pathResults.size() - 1);
- for (int i = 0; i < lastPath.size(); i++) {
- // 3.1.1 convert the graph into mutable.
- convertGraph();
- // 3.1.2 transform the graph.
- List<E> rootPath = createSpurNode(lastPath, i);
- transformGraph(rootPath);
- // 3.1.3 find the deviation node.
- V devNode;
- devNode = getDevNode(rootPath);
- List<E> spurPath;
- // 3.1.4 find the shortest path in the transformed graph.
- spurPath = searchShortestPath(mutableGraph, devNode, sink);
- // 3.1.5 update the path candidates.
- if (spurPath != null) {
- // totalPath = rootPath + spurPath;
- rootPath.addAll(spurPath);
- pathCandidates.add(rootPath);
- }
- }
- // 3.2 if there is no spur path, exit.
- if (pathCandidates.size() == 0) {
- break;
- }
- // 3.3 add the path into the results.
- addPathResult();
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private List<E> searchShortestPath(Graph<V, E> graph, V src, V dst) {
- // Determine the shortest path from the source to the destination by using the Dijkstra algorithm.
- DijkstraGraphSearch dijkstraAlg = new DijkstraGraphSearch();
- Set<Path> paths = dijkstraAlg.search(graph, src, dst, weight, ALL_PATHS).paths();
- Iterator<Path> itr = paths.iterator();
- if (!itr.hasNext()) {
- return null;
- }
- // return the first shortest path only.
- return (List<E>) itr.next().edges();
- }
-
- private void convertGraph() {
- // clear the mutableGraph first
- if (mutableGraph != null) {
- ((MutableAdjacencyListsGraph) mutableGraph).clear();
- }
-
- // create a immutableGraph
- Set<E> copyEa = immutableGraph.getEdges();
- Set<V> copyVa = immutableGraph.getVertexes();
- for (V vertex : copyVa) {
- mutableGraph.addVertex(vertex);
- }
- for (E edge : copyEa) {
- mutableGraph.addEdge(edge);
- }
- }
-
- private V getDevNode(List<E> path) {
- V srcA;
- V dstB;
-
- if (path.size() == 0) {
- return source;
- }
-
- E temp1 = path.get(path.size() - 1);
- srcA = temp1.src();
- dstB = temp1.dst();
-
- if (path.size() == 1) {
- if (srcA.equals(source)) {
- return dstB;
- } else {
- return srcA;
- }
- } else {
- E temp2 = path.get(path.size() - 2);
- if (srcA.equals(temp2.src()) || srcA.equals(temp2.dst())) {
- return dstB;
- } else {
- return srcA;
- }
- }
- }
-
- private List<E> createSpurNode(List<E> path, int n) {
- List<E> root = new ArrayList<E>();
-
- for (int i = 0; i < n; i++) {
- root.add(path.get(i));
- }
- return root;
- }
-
- private void transformGraph(List<E> rootPath) {
- List<E> prePath;
- //remove edges
- for (int i = 0; i < pathResults.size(); i++) {
- prePath = pathResults.get(i);
- if (prePath.size() == 1) {
- mutableGraph.removeEdge(prePath.get(0));
- } else if (comparePath(rootPath, prePath)) {
- for (int j = 0; j <= rootPath.size(); j++) {
- mutableGraph.removeEdge(prePath.get(j));
- }
- }
- }
- for (int i = 0; i < pathCandidates.size(); i++) {
- prePath = pathCandidates.get(i);
- if (prePath.size() == 1) {
- mutableGraph.removeEdge(prePath.get(0));
- } else if (comparePath(rootPath, prePath)) {
- for (int j = 0; j <= rootPath.size(); j++) {
- mutableGraph.removeEdge(prePath.get(j));
- }
- }
- }
-
- if (rootPath.size() == 0) {
- return;
- }
-
- //remove nodes
- List<V> nodes = new ArrayList<V>();
- nodes.add(source);
- V pre = source;
- V srcA;
- V dstB;
- for (int i = 0; i < rootPath.size() - 1; i++) {
- E temp = rootPath.get(i);
- srcA = temp.src();
- dstB = temp.dst();
-
- if (srcA.equals(pre)) {
- nodes.add(dstB);
- pre = dstB;
- } else {
- nodes.add(srcA);
- pre = srcA;
- }
- }
- for (int i = 0; i < nodes.size(); i++) {
- mutableGraph.removeVertex(nodes.get(i));
- }
- }
-
- private boolean comparePath(List<E> path1, List<E> path2) {
- if (path1.size() > path2.size()) {
- return false;
- }
- if (path1.size() == 0) {
- return true;
- }
- for (int i = 0; i < path1.size(); i++) {
- if (path1.get(i) != path2.get(i)) {
- return false;
- }
- }
- return true;
- }
-
- private void addPathResult() {
- List<E> sp;
- sp = pathCandidates.get(0);
- for (int i = 1; i < pathCandidates.size(); i++) {
- if (sp.size() > pathCandidates.get(i).size()) {
- sp = pathCandidates.get(i);
- }
- }
- pathResults.add(sp);
- // Log.info(sp.toString());
- pathCandidates.remove(sp);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java
deleted file mode 100644
index 87571c4b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.SetMultimap;
-
-public class MutableAdjacencyListsGraph<V extends Vertex, E extends Edge<V>>
-implements MutableGraph<V, E> {
- private Set<V> vertexes = new HashSet<V>();
- private Set<E> edges = new HashSet<E>();
-
- private SetMultimap<V, E> sources = HashMultimap.create();
- private SetMultimap<V, E> destinations = HashMultimap.create();
-
- /**
- * Creates a graph comprising of the specified vertexes and edges.
- *
- * @param vertex set of graph vertexes
- * @param edge set of graph edges
- */
- public MutableAdjacencyListsGraph(Set<V> vertex, Set<E> edge) {
- vertexes.addAll(vertex);
- edges.addAll(edge);
- for (E e : edge) {
- sources.put(e.src(), e);
- vertexes.add(e.src());
- destinations.put(e.dst(), e);
- vertexes.add(e.dst());
- }
- }
-
- @Override
- public Set<V> getVertexes() {
- return vertexes;
- }
-
- @Override
- public Set<E> getEdges() {
- return edges;
- }
-
- @Override
- public Set<E> getEdgesFrom(V src) {
- return sources.get(src);
- }
-
- @Override
- public Set<E> getEdgesTo(V dst) {
- return destinations.get(dst);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof MutableAdjacencyListsGraph) {
- MutableAdjacencyListsGraph that = (MutableAdjacencyListsGraph) obj;
- return this.getClass() == that.getClass() &&
- Objects.equals(this.vertexes, that.vertexes) &&
- Objects.equals(this.edges, that.edges);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(vertexes, edges);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("vertexes", vertexes)
- .add("edges", edges)
- .toString();
- }
-
-
- @Override
- public void addVertex(V vertex) {
- if (vertexes != null) {
- if (!vertexes.contains(vertex)) {
- vertexes.add(vertex);
- }
- }
- }
-
- @Override
- public void removeVertex(V vertex) {
- if (vertexes != null && edges != null) {
- if (vertexes.contains(vertex)) {
- vertexes.remove(vertex);
- Set<E> srcEdgesList = sources.get(vertex);
- Set<E> dstEdgesList = destinations.get(vertex);
- edges.removeAll(srcEdgesList);
- edges.removeAll(dstEdgesList);
- sources.remove(vertex, srcEdgesList);
- sources.remove(vertex, dstEdgesList);
- }
- }
- }
-
- @Override
- public void addEdge(E edge) {
- if (edges != null) {
- if (!edges.contains(edge)) {
- edges.add(edge);
- sources.put(edge.src(), edge);
- destinations.put(edge.dst(), edge);
- }
- }
- }
-
- @Override
- public void removeEdge(E edge) {
- if (edges != null) {
- if (edges.contains(edge)) {
- edges.remove(edge);
- sources.remove(edge.src(), edge);
- destinations.remove(edge.dst(), edge);
- }
- }
- }
-
- @Override
- public Graph<V, E> toImmutable() {
- return null;
- }
-
- /**
- * Clear the graph.
- */
- public void clear() {
- edges.clear();
- vertexes.clear();
- sources.clear();
- destinations.clear();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableGraph.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableGraph.java
deleted file mode 100644
index bd2b600c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutableGraph.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Abstraction of a mutable graph that can be constructed gradually.
- */
-public interface MutableGraph<V extends Vertex, E extends Edge> extends Graph<V, E> {
-
- /**
- * Adds the specified vertex to this graph.
- *
- * @param vertex new vertex
- */
- void addVertex(V vertex);
-
- /**
- * Removes the specified vertex from the graph.
- *
- * @param vertex vertex to be removed
- */
- void removeVertex(V vertex);
-
- /**
- * Adds the specified edge to this graph. If the edge vertexes are not
- * already in the graph, they will be added as well.
- *
- * @param edge new edge
- */
- void addEdge(E edge);
-
- /**
- * Removes the specified edge from the graph.
- *
- * @param edge edge to be removed
- */
- void removeEdge(E edge);
-
- /**
- * Returns an immutable copy of this graph.
- *
- * @return immutable copy
- */
- Graph<V, E> toImmutable();
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutablePath.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutablePath.java
deleted file mode 100644
index 5cd8fd0e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/MutablePath.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Abstraction of a mutable path that allows gradual construction.
- */
-public interface MutablePath<V extends Vertex, E extends Edge<V>> extends Path<V, E> {
-
- /**
- * Inserts a new edge at the beginning of this path. The edge must be
- * adjacent to the prior start of the path.
- *
- * @param edge edge to be inserted
- */
- void insertEdge(E edge);
-
- /**
- * Appends a new edge at the end of the this path. The edge must be
- * adjacent to the prior end of the path.
- *
- * @param edge edge to be inserted
- */
- void appendEdge(E edge);
-
- /**
- * Removes the specified edge. This edge must be either at the start or
- * at the end of the path, or it must be a cyclic edge in order not to
- * violate the contiguous path property.
- *
- * @param edge edge to be removed
- */
- void removeEdge(E edge);
-
- /**
- * Sets the total path cost as a unit-less double.
- *
- * @param cost new path cost
- */
- void setCost(double cost);
-
- /**
- * Returns an immutable copy of this path.
- *
- * @return immutable copy
- */
- Path<V, E> toImmutable();
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Path.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Path.java
deleted file mode 100644
index ed9aa2c9..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Path.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.List;
-
-/**
- * Representation of a path in a graph as a sequence of edges. Paths are
- * assumed to be continuous, where adjacent edges must share a vertex.
- *
- * @param <V> vertex type
- * @param <E> edge type
- */
-public interface Path<V extends Vertex, E extends Edge<V>> extends Edge<V> {
-
- /**
- * Returns the list of edges comprising the path. Adjacent edges will
- * share the same vertex, meaning that a source of one edge, will be the
- * same as the destination of the prior edge.
- *
- * @return list of path edges
- */
- List<E> edges();
-
- /**
- * Returns the total cost of the path as a unit-less number.
- *
- * @return path cost as a unit-less number
- */
- double cost();
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SrlgGraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SrlgGraphSearch.java
deleted file mode 100644
index fa3d0ddf..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SrlgGraphSearch.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.onlab.graph;
-
-
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Random;
-
-
-/**
- * SRLG Graph Search finds a pair of paths with disjoint risk groups; i.e
- * if one path goes through an edge in risk group 1, the other path will go
- * through no edges in risk group 1.
- */
-public class SrlgGraphSearch<V extends Vertex, E extends Edge<V>>
- extends AbstractGraphPathSearch<V, E> {
-
- static final int ITERATIONS = 100;
- static final int POPSIZE = 50;
-
- boolean useSuurballe = false;
-
- static final double INF = 100000000.0;
-
- int numGroups;
- Map<E, Integer> riskGrouping;
-
- Graph<V, E> orig;
- V src, dst;
- EdgeWeight<V, E> weight;
-
- /**
- * Creates an SRLG graph search object with the given number
- * of groups and given risk mapping.
- *
- * @param groups the number of disjoint risk groups
- * @param grouping map linking edges to integral group assignments
- */
- public SrlgGraphSearch(int groups, Map<E, Integer> grouping) {
- numGroups = groups;
- riskGrouping = grouping;
- }
-
- /**
- * Creates an SRLG graph search object from a map, inferring
- * the number of groups and creating an integral mapping.
- *
- * @param grouping map linking edges to object group assignments,
- * with same-group status linked to equality
- */
- public SrlgGraphSearch(Map<E, Object> grouping) {
- if (grouping == null) {
- useSuurballe = true;
- return;
- }
- numGroups = 0;
- HashMap<Object, Integer> tmpMap = new HashMap<>();
- riskGrouping = new HashMap<>();
- for (E key: grouping.keySet()) {
- Object value = grouping.get(key);
- if (!tmpMap.containsKey(value)) {
- tmpMap.put(value, numGroups);
- numGroups++;
- }
- riskGrouping.put(key, tmpMap.get(value));
- }
- }
-
- @Override
- public Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
- if (maxPaths == ALL_PATHS) {
- maxPaths = POPSIZE;
- }
- if (useSuurballe) {
- return new SuurballeGraphSearch<V, E>().search(graph, src, dst, weight, ALL_PATHS);
- }
- if (weight == null) {
- weight = edge -> 1;
- }
- checkArguments(graph, src, dst);
- orig = graph;
- this.src = src;
- this.dst = dst;
- this.weight = weight;
- List<Subset> best = new GAPopulation<Subset>()
- .runGA(ITERATIONS, POPSIZE, maxPaths, new Subset(new boolean[numGroups]));
- Set<DisjointPathPair> dpps = new HashSet<DisjointPathPair>();
- for (Subset s: best) {
- dpps.addAll(s.buildPaths());
- }
- Result<V, E> firstDijkstra = new DijkstraGraphSearch<V, E>()
- .search(orig, src, dst, weight, 1);
- return new Result<V, E>() {
- final DefaultResult search = (DefaultResult) firstDijkstra;
-
- public V src() {
- return src;
- }
- public V dst() {
- return dst;
-
- }
- public Set<Path<V, E>> paths() {
- Set<Path<V, E>> pathsD = new HashSet<>();
- for (DisjointPathPair<V, E> path: dpps) {
- pathsD.add(path);
- }
- return pathsD;
- }
- public Map<V, Double> costs() {
- return search.costs();
-
- }
- public Map<V, Set<E>> parents() {
- return search.parents();
-
- }
- };
- }
-
- //finds the shortest path in the graph given a subset of edge types to use
- private Result<V, E> findShortestPathFromSubset(boolean[] subset) {
- Graph<V, E> graph = orig;
- EdgeWeight<V, E> modified = new EdgeWeight<V, E>() {
- final boolean[] subsetF = subset;
-
- @Override
- public double weight(E edge) {
- if (subsetF[riskGrouping.get(edge)]) {
- return weight.weight(edge);
- }
- return INF;
- }
- };
-
- Result<V, E> res = new DijkstraGraphSearch<V, E>().search(graph, src, dst, modified, 1);
- return res;
- }
- /**
- * A subset is a type of GA organism that represents a subset of allowed shortest
- * paths (and its complement). Its fitness is determined by the sum of the weights
- * of the first two shortest paths.
- */
- class Subset implements GAOrganism {
-
- boolean[] subset;
- boolean[] not;
- Random r = new Random();
-
- /**
- * Creates a Subset from the given subset array.
- *
- * @param sub subset array
- */
- public Subset(boolean[] sub) {
- subset = sub.clone();
- not = new boolean[subset.length];
- for (int i = 0; i < subset.length; i++) {
- not[i] = !subset[i];
- }
- }
-
- @Override
- public double fitness() {
- Set<Path<V, E>> paths1 = findShortestPathFromSubset(subset).paths();
- Set<Path<V, E>> paths2 = findShortestPathFromSubset(not).paths();
- if (paths1.size() == 0 || paths2.size() == 0) {
- return INF;
- }
- return paths1.iterator().next().cost() + paths2.iterator().next().cost();
- }
-
- @Override
- public void mutate() {
- int turns = r.nextInt((int) Math.sqrt(subset.length));
- while (turns > 0) {
- int choose = r.nextInt(subset.length);
- subset[choose] = !subset[choose];
- not[choose] = !not[choose];
- turns--;
- }
- }
-
- @Override
- public GAOrganism crossWith(GAOrganism org) {
- if (!(org.getClass().equals(getClass()))) {
- return this;
- }
- Subset other = (Subset) (org);
- boolean[] sub = new boolean[subset.length];
- for (int i = 0; i < subset.length; i++) {
- sub[i] = subset[i];
- if (r.nextBoolean()) {
- sub[i] = other.subset[i];
- }
- }
- return new Subset(sub);
- }
-
- @Override
- public GAOrganism random() {
- boolean[] sub = new boolean[subset.length];
- for (int i = 0; i < sub.length; i++) {
- sub[i] = r.nextBoolean();
- }
- return new Subset(sub);
- }
-
- /**
- * Builds the set of disjoint path pairs for a given subset
- * using Dijkstra's algorithm on both the subset and complement
- * and returning all pairs with one from each set.
- *
- * @return all shortest disjoint paths given this subset
- */
- public Set<DisjointPathPair> buildPaths() {
- Set<DisjointPathPair> dpps = new HashSet<>();
- for (Path<V, E> path1: findShortestPathFromSubset(subset).paths()) {
- if (path1.cost() >= INF) {
- continue;
- }
- for (Path<V, E> path2: findShortestPathFromSubset(not).paths()) {
- if (path2.cost() >= INF) {
- continue;
- }
- DisjointPathPair<V, E> dpp = new DisjointPathPair<>(path1, path2);
- dpps.add(dpp);
- }
- }
- return dpps;
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java
deleted file mode 100644
index 76591c82..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.graph;
-
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.stream.Collectors;
-
-/**
- * Suurballe shortest-path graph search algorithm capable of finding both
- * a shortest path, as well as a backup shortest path, between a source and a destination
- * such that the sum of the path lengths is minimized.
- */
-public class SuurballeGraphSearch<V extends Vertex, E extends Edge<V>> extends DijkstraGraphSearch<V, E> {
-
- @Override
- public Result<V, E> search(Graph<V, E> graph, V src, V dst,
- EdgeWeight<V, E> weight, int maxPaths) {
-
- if (weight == null) {
- weight = edge -> 1;
- }
-
- List<DisjointPathPair<V, E>> dpps = new ArrayList<>();
-
- final EdgeWeight weightf = weight;
- DefaultResult firstDijkstraS = (DefaultResult) super.search(graph, src, dst, weight, ALL_PATHS);
- DefaultResult firstDijkstra = (DefaultResult) super.search(graph, src, null, weight, ALL_PATHS);
-
- //choose an arbitrary shortest path to run Suurballe on
- Path<V, E> shortPath = null;
- if (firstDijkstraS.paths().size() == 0) {
- return firstDijkstraS;
- }
- for (Path p: firstDijkstraS.paths()) {
- shortPath = p;
- //transforms the graph so tree edges have 0 weight
- EdgeWeight<V, Edge<V>> modified = edge -> {
- if (classE().isInstance(edge)) {
- return weightf.weight((E) (edge)) + firstDijkstra.cost(edge.src())
- - firstDijkstra.cost(edge.dst());
- }
- return 0;
- };
- EdgeWeight<V, E> modified2 = edge ->
- weightf.weight(edge) + firstDijkstra.cost(edge.src()) - firstDijkstra.cost(edge.dst());
-
- //create a residual graph g' by removing all src vertices and reversing 0 length path edges
- MutableGraph<V, Edge<V>> gt = mutableCopy(graph);
-
- Map<Edge<V>, E> revToEdge = new HashMap<>();
- graph.getEdgesTo(src).forEach(gt::removeEdge);
- for (E edge: shortPath.edges()) {
- gt.removeEdge(edge);
- Edge<V> reverse = new Edge<V>() {
- final Edge<V> orig = edge;
- public V src() {
- return orig.dst();
- }
- public V dst() {
- return orig.src();
- }
- public String toString() {
- return "ReversedEdge " + "src=" + src() + " dst=" + dst();
- }
- };
- revToEdge.put(reverse, edge);
- gt.addEdge(reverse);
- }
-
- //rerun dijkstra on the temporary graph to get a second path
- Result<V, Edge<V>> secondDijkstra;
- secondDijkstra = new DijkstraGraphSearch<V, Edge<V>>().search(gt, src, dst, modified, ALL_PATHS);
-
- Path<V, Edge<V>> residualShortPath = null;
- if (secondDijkstra.paths().size() == 0) {
- dpps.add(new DisjointPathPair<V, E>(shortPath, null));
- continue;
- }
-
- for (Path p2: secondDijkstra.paths()) {
- residualShortPath = p2;
-
- MutableGraph<V, E> roundTrip = mutableCopy(graph);
-
- List<E> tmp = roundTrip.getEdges().stream().collect(Collectors.toList());
-
- tmp.forEach(roundTrip::removeEdge);
-
- shortPath.edges().forEach(roundTrip::addEdge);
-
- if (residualShortPath != null) {
- for (Edge<V> edge: residualShortPath.edges()) {
- if (classE().isInstance(edge)) {
- roundTrip.addEdge((E) edge);
- } else {
- roundTrip.removeEdge(revToEdge.get(edge));
- }
- }
- }
- //Actually build the final result
- DefaultResult lastSearch = (DefaultResult) super.search(roundTrip, src, dst, weight, ALL_PATHS);
- Path<V, E> path1 = lastSearch.paths().iterator().next();
- path1.edges().forEach(roundTrip::removeEdge);
-
- Set<Path<V, E>> bckpaths = super.search(roundTrip, src, dst, weight, ALL_PATHS).paths();
- Path<V, E> backup = null;
- if (bckpaths.size() != 0) {
- backup = bckpaths.iterator().next();
- }
-
- dpps.add(new DisjointPathPair<>(path1, backup));
- }
- }
-
- for (int i = dpps.size() - 1; i > 0; i--) {
- if (dpps.get(i).size() <= 1) {
- dpps.remove(i);
- }
- }
-
- return new Result<V, E>() {
- final DefaultResult search = firstDijkstra;
-
- public V src() {
- return src;
- }
- public V dst() {
- return dst;
- }
- public Set<Path<V, E>> paths() {
- Set<Path<V, E>> pathsD = new HashSet<>();
- int paths = 0;
- for (DisjointPathPair<V, E> path: dpps) {
- pathsD.add((Path<V, E>) path);
- paths++;
- if (paths == maxPaths) {
- break;
- }
- }
- return pathsD;
- }
- public Map<V, Double> costs() {
- return search.costs();
- }
- public Map<V, Set<E>> parents() {
- return search.parents();
- }
- };
- }
-
- private Class<?> clazzV;
-
- public Class<?> classV() {
- return clazzV;
- }
-
- private Class<?> clazzE;
-
- public Class<?> classE() {
- return clazzE;
- }
- /**
- * Creates a mutable copy of an immutable graph.
- *
- * @param graph immutable graph
- * @return mutable copy
- */
- public MutableGraph mutableCopy(Graph<V, E> graph) {
- clazzV = graph.getVertexes().iterator().next().getClass();
- clazzE = graph.getEdges().iterator().next().getClass();
- return new MutableAdjacencyListsGraph<V, E>(graph.getVertexes(), graph.getEdges());
- }
-}
-
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/TarjanGraphSearch.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/TarjanGraphSearch.java
deleted file mode 100644
index 1c436d94..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/TarjanGraphSearch.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tarjan algorithm for searching a graph and producing results describing
- * the graph SCC (strongly-connected components).
- */
-public class TarjanGraphSearch<V extends Vertex, E extends Edge<V>>
- implements GraphSearch<V, E> {
-
- /**
- * {@inheritDoc}
- * <p>
- * This implementation produces results augmented with information on
- * SCCs within the graph.
- * </p>
- * <p>
- * To prevent traversal of an edge, the {@link EdgeWeight#weight} should
- * return a negative value as an edge weight.
- * </p>
- */
- @Override
- public SccResult<V, E> search(Graph<V, E> graph, EdgeWeight<V, E> weight) {
- SccResult<V, E> result = new SccResult<>(graph);
- for (V vertex : graph.getVertexes()) {
- VertexData data = result.data(vertex);
- if (data == null) {
- connect(graph, vertex, weight, result);
- }
- }
- return result.build();
- }
-
- /**
- * Scans the specified graph, using recursion, and produces SCC results.
- *
- * @param graph graph to search
- * @param vertex current vertex to scan and connect
- * @param weight optional edge weight
- * @param result graph search result
- * @return augmentation vertexData for the current vertex
- */
- private VertexData<V> connect(Graph<V, E> graph, V vertex,
- EdgeWeight<V, E> weight,
- SccResult<V, E> result) {
- VertexData<V> data = result.addData(vertex);
-
- // Scan through all egress edges of the current vertex.
- for (E edge : graph.getEdgesFrom(vertex)) {
- V nextVertex = edge.dst();
-
- // If edge weight is negative, skip it.
- if (weight != null && weight.weight(edge) < 0) {
- continue;
- }
-
- // Attempt to get the augmentation vertexData for the next vertex.
- VertexData<V> nextData = result.data(nextVertex);
- if (nextData == null) {
- // Next vertex has not been visited yet, so do this now.
- nextData = connect(graph, nextVertex, weight, result);
- data.lowLink = Math.min(data.lowLink, nextData.lowLink);
-
- } else if (result.visited(nextData)) {
- // Next vertex has been visited, which means it is in the
- // same cluster as the current vertex.
- data.lowLink = Math.min(data.lowLink, nextData.index);
- }
- }
-
- if (data.lowLink == data.index) {
- result.addCluster(data);
- }
- return data;
- }
-
- /**
- * Graph search result augmented with SCC vertexData.
- */
- public static final class SccResult<V extends Vertex, E extends Edge<V>>
- implements Result {
-
- private final Graph<V, E> graph;
- private List<Set<V>> clusterVertexes = new ArrayList<>();
- private List<Set<E>> clusterEdges = new ArrayList<>();
-
- private int index = 0;
- private final Map<V, VertexData<V>> vertexData = new HashMap<>();
- private final List<VertexData<V>> visited = new ArrayList<>();
-
- private SccResult(Graph<V, E> graph) {
- this.graph = graph;
- }
-
- /**
- * Returns the number of SCC clusters in the graph.
- *
- * @return number of clusters
- */
- public int clusterCount() {
- return clusterEdges.size();
- }
-
- /**
- * Returns the list of strongly connected vertex clusters.
- *
- * @return list of strongly connected vertex sets
- */
- public List<Set<V>> clusterVertexes() {
- return clusterVertexes;
- }
-
- /**
- * Returns the list of edges linking strongly connected vertex clusters.
- *
- * @return list of strongly connected edge sets
- */
- public List<Set<E>> clusterEdges() {
- return clusterEdges;
- }
-
- // Gets the augmentation vertexData for the specified vertex
- private VertexData<V> data(V vertex) {
- return vertexData.get(vertex);
- }
-
- // Adds augmentation vertexData for the specified vertex
- private VertexData<V> addData(V vertex) {
- VertexData<V> d = new VertexData<>(vertex, index);
- vertexData.put(vertex, d);
- visited.add(0, d);
- index++;
- return d;
- }
-
- // Indicates whether the given vertex has been visited
- private boolean visited(VertexData data) {
- return visited.contains(data);
- }
-
- // Adds a new cluster for the specified vertex
- private void addCluster(VertexData data) {
- Set<V> vertexes = findClusterVertices(data);
- clusterVertexes.add(vertexes);
- clusterEdges.add(findClusterEdges(vertexes));
- }
-
- private Set<V> findClusterVertices(VertexData data) {
- VertexData<V> nextVertexData;
- Set<V> vertexes = new HashSet<>();
- do {
- nextVertexData = visited.remove(0);
- vertexes.add(nextVertexData.vertex);
- } while (data != nextVertexData);
- return Collections.unmodifiableSet(vertexes);
- }
-
- private Set<E> findClusterEdges(Set<V> vertexes) {
- Set<E> edges = new HashSet<>();
- for (V vertex : vertexes) {
- for (E edge : graph.getEdgesFrom(vertex)) {
- if (vertexes.contains((edge.dst()))) {
- edges.add(edge);
- }
- }
- }
- return Collections.unmodifiableSet(edges);
- }
-
- public SccResult<V, E> build() {
- clusterVertexes = Collections.unmodifiableList(clusterVertexes);
- clusterEdges = Collections.unmodifiableList(clusterEdges);
- return this;
- }
- }
-
- // Augments the vertex to assist in determining SCC clusters.
- private static final class VertexData<V extends Vertex> {
- final V vertex;
- int index;
- int lowLink;
-
- private VertexData(V vertex, int index) {
- this.vertex = vertex;
- this.index = index;
- this.lowLink = index;
- }
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Vertex.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Vertex.java
deleted file mode 100644
index 80e3e7df..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/Vertex.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-/**
- * Representation of a graph vertex.
- */
-public interface Vertex {
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/package-info.java
deleted file mode 100644
index 2ee949d2..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/graph/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Graph abstractions and graph path finding algorithms.
- */
-package org.onlab.graph;
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/EventMetric.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/EventMetric.java
deleted file mode 100644
index d20ca53f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/EventMetric.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Meter;
-
-/**
- * Metric measurements for events.
- */
-public class EventMetric {
- private static final String GAUGE_TIMESTAMP_NAME = "Timestamp.EpochMs";
- private static final String METER_RATE_NAME = "Rate";
-
- private final MetricsService metricsService;
- private final String componentName;
- private final String featureName;
-
- private MetricsComponent metricsComponent;
- private MetricsFeature metricsFeature;
-
- private volatile long lastEventTimestampEpochMs = 0;
- private Gauge<Long> lastEventTimestampGauge;
- private Meter eventRateMeter;
-
- /**
- * Constructor.
- *
- * @param metricsService the Metrics Service to use for Metrics
- * registration and deregistration
- * @param componentName the Metrics Component Name to use for Metrics
- * registration and deregistration
- * @param featureName the Metrics Feature Name to use for Metrics
- * registration and deregistration
- */
- public EventMetric(MetricsService metricsService, String componentName,
- String featureName) {
- this.metricsService = metricsService;
- this.componentName = componentName;
- this.featureName = featureName;
- }
-
- /**
- * Registers the metrics.
- */
- public void registerMetrics() {
- metricsComponent = metricsService.registerComponent(componentName);
- metricsFeature = metricsComponent.registerFeature(featureName);
-
- lastEventTimestampEpochMs = 0;
- lastEventTimestampGauge =
- metricsService.registerMetric(metricsComponent,
- metricsFeature,
- GAUGE_TIMESTAMP_NAME,
- new Gauge<Long>() {
- @Override
- public Long getValue() {
- return lastEventTimestampEpochMs;
- }
- });
-
- eventRateMeter = metricsService.createMeter(metricsComponent,
- metricsFeature,
- METER_RATE_NAME);
- }
-
- /**
- * Removes the metrics.
- */
- public void removeMetrics() {
- lastEventTimestampEpochMs = 0;
- metricsService.removeMetric(metricsComponent,
- metricsFeature,
- GAUGE_TIMESTAMP_NAME);
- metricsService.removeMetric(metricsComponent,
- metricsFeature,
- METER_RATE_NAME);
- }
-
- /**
- * Updates the metric measurements for a single event.
- */
- public void eventReceived() {
- lastEventTimestampEpochMs = System.currentTimeMillis();
- eventRateMeter.mark(1);
- }
-
- /**
- * Gets the last event timestamp Gauge (ms from the Epoch).
- *
- * @return the last event timestamp Gauge (ms from the Epoch)
- */
- public Gauge<Long> lastEventTimestampGauge() {
- return lastEventTimestampGauge;
- }
-
- /**
- * Gets the event rate meter.
- *
- * @return the event rate meter
- */
- public Meter eventRateMeter() {
- return eventRateMeter;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponent.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponent.java
deleted file mode 100644
index cc8fe83c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponent.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * Components to register for metrics.
- */
-public class MetricsComponent implements MetricsComponentRegistry {
- private final String name;
-
- /**
- * Registry to hold the Features defined in this Component.
- */
- private final ConcurrentMap<String, MetricsFeature> featuresRegistry =
- new ConcurrentHashMap<>();
-
- /**
- * Constructs a component from a name.
- *
- * @param newName name of the component
- */
- MetricsComponent(final String newName) {
- name = newName;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public MetricsFeature registerFeature(final String featureName) {
- MetricsFeature feature = featuresRegistry.get(featureName);
- if (feature == null) {
- final MetricsFeature createdFeature =
- new MetricsFeature(featureName);
- feature = featuresRegistry.putIfAbsent(featureName, createdFeature);
- if (feature == null) {
- feature = createdFeature;
- }
- }
- return feature;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponentRegistry.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponentRegistry.java
deleted file mode 100644
index 89f6ec5e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsComponentRegistry.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-/**
- * Registry Entry for Metrics Components.
- */
-public interface MetricsComponentRegistry {
- /**
- * Fetches the name of the Component.
- *
- * @return name of the Component
- */
- String getName();
-
- /**
- * Registers a Feature for this component.
- *
- * @param featureName name of the Feature to register
- * @return Feature object that can be used when creating Metrics
- */
- MetricsFeature registerFeature(String featureName);
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsFeature.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsFeature.java
deleted file mode 100644
index bc6753c9..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsFeature.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-/**
- * Features to tag metrics.
- */
-public class MetricsFeature {
- private final String name;
-
- /**
- * Constructs a Feature from a name.
- *
- * @param newName name of the Feature
- */
- public MetricsFeature(final String newName) {
- name = newName;
- }
-
- /**
- * Fetches the name of the Feature.
- *
- * @return name of the Feature
- */
- public String getName() {
- return name;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsManager.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsManager.java
deleted file mode 100644
index 6c9314ad..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsManager.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import com.codahale.metrics.Counter;
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.Meter;
-import com.codahale.metrics.Metric;
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.Timer;
-
-/**
- * This class holds the Metrics registry for ONOS.
- * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
- * string-based naming scheme: COMPONENT.FEATURE.NAME.
- * Example: "Topology.Counters.TopologyUpdates".
- * The COMPONENT and FEATURE names have to be registered in advance before
- * a metric can be created. Example:
- * <pre>
- * <code>
- * private final MetricsManager.MetricsComponent COMPONENT =
- * MetricsManager.registerComponent("Topology");
- * private final MetricsManager.MetricsFeature FEATURE =
- * COMPONENT.registerFeature("Counters");
- * private final Counter counterTopologyUpdates =
- * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
- * </code>
- * </pre>
- * Gauges are slightly different because they are not created directly in
- * this class, but are allocated by the caller and passed in for registration:
- * <pre>
- * <code>
- * private final Gauge&lt;Long&gt; gauge =
- * new {@literal Gauge&lt;Long&gt}() {
- * {@literal @}Override
- * public Long getValue() {
- * return gaugeValue;
- * }
- * };
- * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
- * </code>
- * </pre>
- */
-public class MetricsManager implements MetricsService {
-
- /**
- * Registry to hold the Components defined in the system.
- */
- private ConcurrentMap<String, MetricsComponent> componentsRegistry =
- new ConcurrentHashMap<>();
-
- /**
- * Registry for the Metrics objects created in the system.
- */
- private MetricRegistry metricsRegistry = new MetricRegistry();
-
- /**
- * Clears the internal state.
- */
- protected void clear() {
- this.componentsRegistry = new ConcurrentHashMap<>();
- this.metricsRegistry = new MetricRegistry();
- }
-
- /**
- * Registers a component.
- *
- * @param name name of the Component to register
- * @return MetricsComponent object that can be used to create Metrics.
- */
- @Override
- public MetricsComponent registerComponent(final String name) {
- MetricsComponent component = componentsRegistry.get(name);
- if (component == null) {
- final MetricsComponent createdComponent =
- new MetricsComponent(name);
- component = componentsRegistry.putIfAbsent(name, createdComponent);
- if (component == null) {
- component = createdComponent;
- }
- }
- return component;
- }
-
- /**
- * Generates a name for a Metric from its component and feature.
- *
- * @param component component the metric is defined in
- * @param feature feature the metric is defined in
- * @param metricName local name of the metric
- *
- * @return full name of the metric
- */
- private String generateName(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- return MetricRegistry.name(component.getName(),
- feature.getName(),
- metricName);
- }
-
- /**
- * Creates a Counter metric.
- *
- * @param component component the Counter is defined in
- * @param feature feature the Counter is defined in
- * @param metricName local name of the metric
- * @return the created Counter Meteric
- */
- @Override
- public Counter createCounter(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- final String name = generateName(component, feature, metricName);
- return metricsRegistry.counter(name);
- }
-
- /**
- * Creates a Histogram metric.
- *
- * @param component component the Histogram is defined in
- * @param feature feature the Histogram is defined in
- * @param metricName local name of the metric
- * @return the created Histogram Metric
- */
- @Override
- public Histogram createHistogram(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- final String name = generateName(component, feature, metricName);
- return metricsRegistry.histogram(name);
- }
-
- /**
- * Creates a Timer metric.
- *
- * @param component component the Timer is defined in
- * @param feature feature the Timer is defined in
- * @param metricName local name of the metric
- * @return the created Timer Metric
- */
- @Override
- public Timer createTimer(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- final String name = generateName(component, feature, metricName);
- return metricsRegistry.timer(name);
- }
-
- /**
- * Creates a Meter metric.
- *
- * @param component component the Meter is defined in
- * @param feature feature the Meter is defined in
- * @param metricName local name of the metric
- * @return the created Meter Metric
- */
- @Override
- public Meter createMeter(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- final String name = generateName(component, feature, metricName);
- return metricsRegistry.meter(name);
- }
-
- /**
- * Registers an already created Metric. This is used for situation where a
- * caller needs to allocate its own Metric, but still register it with the
- * system.
- *
- * @param <T> Metric type
- * @param component component the Metric is defined in
- * @param feature feature the Metric is defined in
- * @param metricName local name of the metric
- * @param metric Metric to register
- * @return the registered Metric
- */
- @Override
- public <T extends Metric> T registerMetric(
- final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName,
- final T metric) {
- final String name = generateName(component, feature, metricName);
- metricsRegistry.register(name, metric);
- return metric;
- }
-
- /**
- * Removes the metric with the given name.
- *
- * @param component component the Metric is defined in
- * @param feature feature the Metric is defined in
- * @param metricName local name of the metric
- * @return true if the metric existed and was removed, otherwise false
- */
- @Override
- public boolean removeMetric(final MetricsComponent component,
- final MetricsFeature feature,
- final String metricName) {
- final String name = generateName(component, feature, metricName);
- return metricsRegistry.remove(name);
- }
-
- /**
- * Fetches the existing Timers.
- *
- * @param filter filter to use to select Timers
- * @return a map of the Timers that match the filter, with the key as the
- * name String to the Timer.
- */
- @Override
- public Map<String, Timer> getTimers(final MetricFilter filter) {
- return metricsRegistry.getTimers(filter);
- }
-
- /**
- * Fetches the existing Gauges.
- *
- * @param filter filter to use to select Gauges
- * @return a map of the Gauges that match the filter, with the key as the
- * name String to the Gauge.
- */
- @Override
- public Map<String, Gauge> getGauges(final MetricFilter filter) {
- return metricsRegistry.getGauges(filter);
- }
-
- /**
- * Fetches the existing Counters.
- *
- * @param filter filter to use to select Counters
- * @return a map of the Counters that match the filter, with the key as the
- * name String to the Counter.
- */
- @Override
- public Map<String, Counter> getCounters(final MetricFilter filter) {
- return metricsRegistry.getCounters(filter);
- }
-
- /**
- * Fetches the existing Meters.
- *
- * @param filter filter to use to select Meters
- * @return a map of the Meters that match the filter, with the key as the
- * name String to the Meter.
- */
- @Override
- public Map<String, Meter> getMeters(final MetricFilter filter) {
- return metricsRegistry.getMeters(filter);
- }
-
- /**
- * Fetches the existing Histograms.
- *
- * @param filter filter to use to select Histograms
- * @return a map of the Histograms that match the filter, with the key as
- * the name String to the Histogram.
- */
- @Override
- public Map<String, Histogram> getHistograms(final MetricFilter filter) {
- return metricsRegistry.getHistograms(filter);
- }
-
- /**
- * Removes all Metrics that match a given filter.
- *
- * @param filter filter to use to select the Metrics to remove.
- */
- @Override
- public void removeMatching(final MetricFilter filter) {
- metricsRegistry.removeMatching(filter);
- }
-
- /**
- * Fetches the existing Meters.
- *
- *
- * @return a map of all metrics with the key as the
- * name String to the Meter.
- */
- public Map<String, Metric> getMetrics() {
- return metricsRegistry.getMetrics();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsService.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsService.java
deleted file mode 100644
index 4f0d67a8..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsService.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.metrics;
-
-import java.util.Map;
-
-import com.codahale.metrics.Counter;
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.Meter;
-import com.codahale.metrics.Metric;
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.Timer;
-
-/**
- * Metrics Service to collect metrics.
- */
-public interface MetricsService {
-
- /**
- * Registers a component.
- *
- * @param name name of the Component to register
- * @return MetricsComponent object that can be used to create Metrics.
- */
- MetricsComponent registerComponent(String name);
-
- /**
- * Creates a Counter metric.
- *
- * @param component component the Counter is defined in
- * @param feature feature the Counter is defined in
- * @param metricName local name of the metric
- * @return the created Counter Meteric
- */
- Counter createCounter(MetricsComponent component,
- MetricsFeature feature,
- String metricName);
-
- /**
- * Creates a Histogram metric.
- *
- * @param component component the Histogram is defined in
- * @param feature feature the Histogram is defined in
- * @param metricName local name of the metric
- * @return the created Histogram Metric
- */
- Histogram createHistogram(MetricsComponent component,
- MetricsFeature feature,
- String metricName);
-
- /**
- * Creates a Timer metric.
- *
- * @param component component the Timer is defined in
- * @param feature feature the Timer is defined in
- * @param metricName local name of the metric
- * @return the created Timer Metric
- */
- Timer createTimer(MetricsComponent component,
- MetricsFeature feature,
- String metricName);
-
- /**
- * Creates a Meter metric.
- *
- * @param component component the Meter is defined in
- * @param feature feature the Meter is defined in
- * @param metricName local name of the metric
- * @return the created Meter Metric
- */
- Meter createMeter(MetricsComponent component,
- MetricsFeature feature,
- String metricName);
-
- /**
- * Registers an already created Metric. This is used for situation where a
- * caller needs to allocate its own Metric, but still register it with the
- * system.
- *
- * @param <T> Metric type
- * @param component component the Metric is defined in
- * @param feature feature the Metric is defined in
- * @param metricName local name of the metric
- * @param metric Metric to register
- * @return the registered Metric
- */
- <T extends Metric> T registerMetric(
- MetricsComponent component,
- MetricsFeature feature,
- String metricName,
- T metric);
-
- /**
- * Removes the metric with the given name.
- *
- * @param component component the Metric is defined in
- * @param feature feature the Metric is defined in
- * @param metricName local name of the metric
- * @return true if the metric existed and was removed, otherwise false
- */
- boolean removeMetric(MetricsComponent component,
- MetricsFeature feature,
- String metricName);
-
- /**
- * Fetches the existing Timers.
- *
- * @param filter filter to use to select Timers
- * @return a map of the Timers that match the filter, with the key as the
- * name String to the Timer.
- */
- Map<String, Timer> getTimers(MetricFilter filter);
-
- /**
- * Fetches the existing Gauges.
- *
- * @param filter filter to use to select Gauges
- * @return a map of the Gauges that match the filter, with the key as the
- * name String to the Gauge.
- */
- Map<String, Gauge> getGauges(MetricFilter filter);
-
- /**
- * Fetches the existing Counters.
- *
- * @param filter filter to use to select Counters
- * @return a map of the Counters that match the filter, with the key as the
- * name String to the Counter.
- */
- Map<String, Counter> getCounters(MetricFilter filter);
-
- /**
- * Fetches the existing Meters.
- *
- * @param filter filter to use to select Meters
- * @return a map of the Meters that match the filter, with the key as the
- * name String to the Meter.
- */
- Map<String, Meter> getMeters(MetricFilter filter);
-
- /**
- * Fetches the existing Histograms.
- *
- * @param filter filter to use to select Histograms
- * @return a map of the Histograms that match the filter, with the key as
- * the name String to the Histogram.
- */
- Map<String, Histogram> getHistograms(MetricFilter filter);
-
- /**
- * Fetches the existing metrics.
- *
- * @return a map of the Metrics, with the key as
- * the name String to the Histogram.
- */
- Map<String, Metric> getMetrics();
-
- /**
- * Removes all Metrics that match a given filter.
- *
- * @param filter filter to use to select the Metrics to remove.
- */
- void removeMatching(MetricFilter filter);
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsUtil.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsUtil.java
deleted file mode 100644
index cab6c0ea..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/MetricsUtil.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.metrics;
-
-import com.codahale.metrics.Timer;
-import com.codahale.metrics.Timer.Context;
-
-public final class MetricsUtil {
-
- /**
- * Starts the Metric Timer.
- * <p>
- * If the given timer was null, it will silently return null.
- * </p>
- *
- * @param timer timer to start
- * @return timing context, if timer was not null
- */
- public static Context startTimer(Timer timer) {
- if (timer != null) {
- return timer.time();
- }
- return null;
- }
-
- /**
- * Stops the Metric Timer context.
- * <p>
- * If the given context was null, it will silently be ignored.
- * </p>
- *
- * @param context timing context to stop, if not null.
- */
- public static void stopTimer(Context context) {
- if (context != null) {
- context.stop();
- }
- }
-
- // avoid instantiation
- private MetricsUtil() {}
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/package-info.java
deleted file mode 100644
index 0a61f353..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/metrics/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Misc utils for various performance metrics.
- */
-package org.onlab.metrics;
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ARP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ARP.java
deleted file mode 100644
index dc3c07f1..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ARP.java
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- *
- *
- */
-public class ARP extends BasePacket {
- public static final short HW_TYPE_ETHERNET = 0x1;
-
- public static final short PROTO_TYPE_IP = 0x800;
-
- public static final short OP_REQUEST = 0x1;
- public static final short OP_REPLY = 0x2;
- public static final short OP_RARP_REQUEST = 0x3;
- public static final short OP_RARP_REPLY = 0x4;
-
- public static final short INITIAL_HEADER_LENGTH = 8;
-
- protected short hardwareType;
- protected short protocolType;
- protected byte hardwareAddressLength;
- protected byte protocolAddressLength;
- protected short opCode;
- protected byte[] senderHardwareAddress;
- protected byte[] senderProtocolAddress;
- protected byte[] targetHardwareAddress;
- protected byte[] targetProtocolAddress;
-
- /**
- * @return the hardwareType
- */
- public short getHardwareType() {
- return this.hardwareType;
- }
-
- /**
- * @param hwType
- * the hardwareType to set
- * @return this
- */
- public ARP setHardwareType(final short hwType) {
- this.hardwareType = hwType;
- return this;
- }
-
- /**
- * @return the protocolType
- */
- public short getProtocolType() {
- return this.protocolType;
- }
-
- /**
- * @param protoType
- * the protocolType to set
- * @return this
- */
- public ARP setProtocolType(final short protoType) {
- this.protocolType = protoType;
- return this;
- }
-
- /**
- * @return the hardwareAddressLength
- */
- public byte getHardwareAddressLength() {
- return this.hardwareAddressLength;
- }
-
- /**
- * @param hwAddressLength
- * the hardwareAddressLength to set
- * @return this
- */
- public ARP setHardwareAddressLength(final byte hwAddressLength) {
- this.hardwareAddressLength = hwAddressLength;
- return this;
- }
-
- /**
- * @return the protocolAddressLength
- */
- public byte getProtocolAddressLength() {
- return this.protocolAddressLength;
- }
-
- /**
- * @param protoAddressLength
- * the protocolAddressLength to set
- * @return this
- */
- public ARP setProtocolAddressLength(final byte protoAddressLength) {
- this.protocolAddressLength = protoAddressLength;
- return this;
- }
-
- /**
- * @return the opCode
- */
- public short getOpCode() {
- return this.opCode;
- }
-
- /**
- * @param op
- * the opCode to set
- * @return this
- */
- public ARP setOpCode(final short op) {
- this.opCode = op;
- return this;
- }
-
- /**
- * @return the senderHardwareAddress
- */
- public byte[] getSenderHardwareAddress() {
- return this.senderHardwareAddress;
- }
-
- /**
- * @param senderHWAddress
- * the senderHardwareAddress to set
- * @return this
- */
- public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
- this.senderHardwareAddress = senderHWAddress;
- return this;
- }
-
- /**
- * @return the senderProtocolAddress
- */
- public byte[] getSenderProtocolAddress() {
- return this.senderProtocolAddress;
- }
-
- /**
- * @param senderProtoAddress
- * the senderProtocolAddress to set
- * @return this
- */
- public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
- this.senderProtocolAddress = senderProtoAddress;
- return this;
- }
-
- public ARP setSenderProtocolAddress(final int address) {
- this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
- .array();
- return this;
- }
-
- /**
- * @return the targetHardwareAddress
- */
- public byte[] getTargetHardwareAddress() {
- return this.targetHardwareAddress;
- }
-
- /**
- * @param targetHWAddress
- * the targetHardwareAddress to set
- * @return this
- */
- public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
- this.targetHardwareAddress = targetHWAddress;
- return this;
- }
-
- /**
- * @return the targetProtocolAddress
- */
- public byte[] getTargetProtocolAddress() {
- return this.targetProtocolAddress;
- }
-
- /**
- * @return True if gratuitous ARP (SPA = TPA), false otherwise
- */
- public boolean isGratuitous() {
- assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;
-
- int indx = 0;
- while (indx < this.senderProtocolAddress.length) {
- if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
- return false;
- }
- indx++;
- }
-
- return true;
- }
-
- /**
- * @param targetProtoAddress
- * the targetProtocolAddress to set
- * @return this
- */
- public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
- this.targetProtocolAddress = targetProtoAddress;
- return this;
- }
-
- public ARP setTargetProtocolAddress(final int address) {
- this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
- .array();
- return this;
- }
-
- @Override
- public byte[] serialize() {
- final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
- * (0xff & this.protocolAddressLength);
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.putShort(this.hardwareType);
- bb.putShort(this.protocolType);
- bb.put(this.hardwareAddressLength);
- bb.put(this.protocolAddressLength);
- bb.putShort(this.opCode);
- bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
- bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
- bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
- bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.hardwareType = bb.getShort();
- this.protocolType = bb.getShort();
- this.hardwareAddressLength = bb.get();
- this.protocolAddressLength = bb.get();
- this.opCode = bb.getShort();
- this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
- bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
- this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
- bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
- this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
- bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
- this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
- bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 13121;
- int result = super.hashCode();
- result = prime * result + this.hardwareAddressLength;
- result = prime * result + this.hardwareType;
- result = prime * result + this.opCode;
- result = prime * result + this.protocolAddressLength;
- result = prime * result + this.protocolType;
- result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
- result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
- result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
- result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof ARP)) {
- return false;
- }
- final ARP other = (ARP) obj;
- if (this.hardwareAddressLength != other.hardwareAddressLength) {
- return false;
- }
- if (this.hardwareType != other.hardwareType) {
- return false;
- }
- if (this.opCode != other.opCode) {
- return false;
- }
- if (this.protocolAddressLength != other.protocolAddressLength) {
- return false;
- }
- if (this.protocolType != other.protocolType) {
- return false;
- }
- if (!Arrays.equals(this.senderHardwareAddress,
- other.senderHardwareAddress)) {
- return false;
- }
- if (!Arrays.equals(this.senderProtocolAddress,
- other.senderProtocolAddress)) {
- return false;
- }
- if (!Arrays.equals(this.targetHardwareAddress,
- other.targetHardwareAddress)) {
- return false;
- }
- if (!Arrays.equals(this.targetProtocolAddress,
- other.targetProtocolAddress)) {
- return false;
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "ARP [hardwareType=" + this.hardwareType + ", protocolType="
- + this.protocolType + ", hardwareAddressLength="
- + this.hardwareAddressLength + ", protocolAddressLength="
- + this.protocolAddressLength + ", opCode=" + this.opCode
- + ", senderHardwareAddress="
- + Arrays.toString(this.senderHardwareAddress)
- + ", senderProtocolAddress="
- + Arrays.toString(this.senderProtocolAddress)
- + ", targetHardwareAddress="
- + Arrays.toString(this.targetHardwareAddress)
- + ", targetProtocolAddress="
- + Arrays.toString(this.targetProtocolAddress) + "]";
- }
-
- /**
- * Builds an ARP reply based on a request.
- *
- * @param srcIp the IP address to use as the reply source
- * @param srcMac the MAC address to use as the reply source
- * @param request the ARP request we got
- * @return an Ethernet frame containing the ARP reply
- */
- public static Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
- Ethernet request) {
-
- Ethernet eth = new Ethernet();
- eth.setDestinationMACAddress(request.getSourceMAC());
- eth.setSourceMACAddress(srcMac);
- eth.setEtherType(Ethernet.TYPE_ARP);
- eth.setVlanID(request.getVlanID());
-
- ARP arp = new ARP();
- arp.setOpCode(ARP.OP_REPLY);
- arp.setProtocolType(ARP.PROTO_TYPE_IP);
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
-
- arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
- arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
- arp.setSenderHardwareAddress(srcMac.toBytes());
- arp.setTargetHardwareAddress(request.getSourceMACAddress());
-
- arp.setTargetProtocolAddress(((ARP) request.getPayload())
- .getSenderProtocolAddress());
- arp.setSenderProtocolAddress(srcIp.toInt());
-
- eth.setPayload(arp);
- return eth;
- }
-
- /**
- * Deserializer function for ARP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<ARP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, INITIAL_HEADER_LENGTH);
-
- ARP arp = new ARP();
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- arp.setHardwareType(bb.getShort());
- arp.setProtocolType(bb.getShort());
-
- byte hwAddressLength = bb.get();
- arp.setHardwareAddressLength(hwAddressLength);
-
- byte protocolAddressLength = bb.get();
- arp.setProtocolAddressLength(protocolAddressLength);
- arp.setOpCode(bb.getShort());
-
- // Check we have enough space for the addresses
- checkHeaderLength(length, INITIAL_HEADER_LENGTH +
- 2 * hwAddressLength +
- 2 * protocolAddressLength);
-
- arp.senderHardwareAddress = new byte[0xff & hwAddressLength];
- bb.get(arp.senderHardwareAddress, 0, arp.senderHardwareAddress.length);
- arp.senderProtocolAddress = new byte[0xff & protocolAddressLength];
- bb.get(arp.senderProtocolAddress, 0, arp.senderProtocolAddress.length);
- arp.targetHardwareAddress = new byte[0xff & hwAddressLength];
- bb.get(arp.targetHardwareAddress, 0, arp.targetHardwareAddress.length);
- arp.targetProtocolAddress = new byte[0xff & protocolAddressLength];
- bb.get(arp.targetProtocolAddress, 0, arp.targetProtocolAddress.length);
-
- return arp;
- };
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/BasePacket.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/BasePacket.java
deleted file mode 100644
index 4aece66f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/BasePacket.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-/**
- *
- *
- */
-public abstract class BasePacket implements IPacket {
- protected IPacket parent;
- protected IPacket payload;
-
- /**
- * @return the parent
- */
- @Override
- public IPacket getParent() {
- return this.parent;
- }
-
- /**
- * @param parent
- * the parent to set
- */
- @Override
- public IPacket setParent(final IPacket parent) {
- this.parent = parent;
- return this;
- }
-
- /**
- * @return the payload
- */
- @Override
- public IPacket getPayload() {
- return this.payload;
- }
-
- /**
- * @param payload
- * the payload to set
- */
- @Override
- public IPacket setPayload(final IPacket payload) {
- this.payload = payload;
- return this;
- }
-
- @Override
- public void resetChecksum() {
- if (this.parent != null) {
- this.parent.resetChecksum();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 6733;
- int result = 1;
- result = prime * result
- + (this.payload == null ? 0 : this.payload.hashCode());
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof BasePacket)) {
- return false;
- }
- final BasePacket other = (BasePacket) obj;
- if (this.payload == null) {
- if (other.payload != null) {
- return false;
- }
- } else if (!this.payload.equals(other.payload)) {
- return false;
- }
- return true;
- }
-
- @Override
- public Object clone() {
- IPacket pkt;
- try {
- pkt = this.getClass().newInstance();
- } catch (final Exception e) {
- throw new RuntimeException("Could not clone packet");
- }
-
- final byte[] data = this.serialize();
- pkt.deserialize(this.serialize(), 0, data.length);
- pkt.setParent(this.parent);
- return pkt;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ChassisId.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ChassisId.java
deleted file mode 100644
index 23c9859f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ChassisId.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-/**
- * The class representing a network device chassisId.
- * This class is immutable.
- */
-public final class ChassisId {
-
- private static final long UNKNOWN = 0;
- private final long value;
-
- /**
- * Default constructor.
- */
- public ChassisId() {
- this.value = ChassisId.UNKNOWN;
- }
-
- /**
- * Constructor from a long value.
- *
- * @param value the value to use.
- */
- public ChassisId(long value) {
- this.value = value;
- }
-
- /**
- * Constructor from a string.
- *
- * @param value the value to use.
- */
- public ChassisId(String value) {
- this.value = Long.parseLong(value, 16);
- }
-
- /**
- * Get the value of the chassis id.
- *
- * @return the value of the chassis id.
- */
- public long value() {
- return value;
- }
-
- /**
- * Convert the Chassis Id value to a ':' separated hexadecimal string.
- *
- * @return the Chassis Id value as a ':' separated hexadecimal string.
- */
- @Override
- public String toString() {
- return Long.toHexString(this.value);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof ChassisId)) {
- return false;
- }
-
- ChassisId otherChassisId = (ChassisId) other;
-
- return value == otherChassisId.value;
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(value);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java
deleted file mode 100644
index de5b43fa..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- *
- */
-public class DHCP extends BasePacket {
- /**
- * Dynamic Host Configuration Protocol packet.
- * ------------------------------------------ |op (1) | htype(1) | hlen(1) |
- * hops(1) | ------------------------------------------ | xid (4) |
- * ------------------------------------------ | secs (2) | flags (2) |
- * ------------------------------------------ | ciaddr (4) |
- * ------------------------------------------ | yiaddr (4) |
- * ------------------------------------------ | siaddr (4) |
- * ------------------------------------------ | giaddr (4) |
- * ------------------------------------------ | chaddr (16) |
- * ------------------------------------------ | sname (64) |
- * ------------------------------------------ | file (128) |
- * ------------------------------------------ | options (312) |
- * ------------------------------------------
- *
- */
- // Header + magic without options
- public static final int MIN_HEADER_LENGTH = 240;
- public static final byte OPCODE_REQUEST = 0x1;
- public static final byte OPCODE_REPLY = 0x2;
-
- public static final byte HWTYPE_ETHERNET = 0x1;
-
- public enum DHCPOptionCode {
- OptionCode_SubnetMask((byte) 1), OptionCode_RouterAddress((byte) 3), OptionCode_DomainServer((byte) 6),
- OptionCode_HostName((byte) 12), OptionCode_DomainName((byte) 15), OptionCode_BroadcastAddress((byte) 28),
- OptionCode_RequestedIP((byte) 50), OptionCode_LeaseTime((byte) 51), OptionCode_MessageType((byte) 53),
- OptionCode_DHCPServerIp((byte) 54), OptionCode_RequestedParameters((byte) 55),
- OptionCode_RenewalTime((byte) 58), OPtionCode_RebindingTime((byte) 59), OptionCode_ClientID((byte) 61),
- OptionCode_END((byte) 255);
-
- protected byte value;
-
- private DHCPOptionCode(final byte value) {
- this.value = value;
- }
-
- public byte getValue() {
- return this.value;
- }
- }
-
- protected byte opCode;
- protected byte hardwareType;
- protected byte hardwareAddressLength;
- protected byte hops;
- protected int transactionId;
- protected short seconds;
- protected short flags;
- protected int clientIPAddress;
- protected int yourIPAddress;
- protected int serverIPAddress;
- protected int gatewayIPAddress;
- protected byte[] clientHardwareAddress;
- protected String serverName;
- protected String bootFileName;
- protected List<DHCPOption> options = new ArrayList<DHCPOption>();
-
- /**
- * @return the opCode
- */
- public byte getOpCode() {
- return this.opCode;
- }
-
- /**
- * @param opCode
- * the opCode to set
- * @return this
- */
- public DHCP setOpCode(final byte opCode) {
- this.opCode = opCode;
- return this;
- }
-
- /**
- * @return the hardwareType
- */
- public byte getHardwareType() {
- return this.hardwareType;
- }
-
- /**
- * @param hardwareType
- * the hardwareType to set
- * @return this
- */
- public DHCP setHardwareType(final byte hardwareType) {
- this.hardwareType = hardwareType;
- return this;
- }
-
- /**
- * @return the hardwareAddressLength
- */
- public byte getHardwareAddressLength() {
- return this.hardwareAddressLength;
- }
-
- /**
- * @param hardwareAddressLength
- * the hardwareAddressLength to set
- * @return this
- */
- public DHCP setHardwareAddressLength(final byte hardwareAddressLength) {
- this.hardwareAddressLength = hardwareAddressLength;
- return this;
- }
-
- /**
- * @return the hops
- */
- public byte getHops() {
- return this.hops;
- }
-
- /**
- * @param hops
- * the hops to set
- * @return this
- */
- public DHCP setHops(final byte hops) {
- this.hops = hops;
- return this;
- }
-
- /**
- * @return the transactionId
- */
- public int getTransactionId() {
- return this.transactionId;
- }
-
- /**
- * @param transactionId
- * the transactionId to set
- * @return this
- */
- public DHCP setTransactionId(final int transactionId) {
- this.transactionId = transactionId;
- return this;
- }
-
- /**
- * @return the seconds
- */
- public short getSeconds() {
- return this.seconds;
- }
-
- /**
- * @param seconds
- * the seconds to set
- * @return this
- */
- public DHCP setSeconds(final short seconds) {
- this.seconds = seconds;
- return this;
- }
-
- /**
- * @return the flags
- */
- public short getFlags() {
- return this.flags;
- }
-
- /**
- * @param flags
- * the flags to set
- * @return this
- */
- public DHCP setFlags(final short flags) {
- this.flags = flags;
- return this;
- }
-
- /**
- * @return the clientIPAddress
- */
- public int getClientIPAddress() {
- return this.clientIPAddress;
- }
-
- /**
- * @param clientIPAddress
- * the clientIPAddress to set
- * @return this
- */
- public DHCP setClientIPAddress(final int clientIPAddress) {
- this.clientIPAddress = clientIPAddress;
- return this;
- }
-
- /**
- * @return the yourIPAddress
- */
- public int getYourIPAddress() {
- return this.yourIPAddress;
- }
-
- /**
- * @param yourIPAddress
- * the yourIPAddress to set
- * @return this
- */
- public DHCP setYourIPAddress(final int yourIPAddress) {
- this.yourIPAddress = yourIPAddress;
- return this;
- }
-
- /**
- * @return the serverIPAddress
- */
- public int getServerIPAddress() {
- return this.serverIPAddress;
- }
-
- /**
- * @param serverIPAddress
- * the serverIPAddress to set
- * @return this
- */
- public DHCP setServerIPAddress(final int serverIPAddress) {
- this.serverIPAddress = serverIPAddress;
- return this;
- }
-
- /**
- * @return the gatewayIPAddress
- */
- public int getGatewayIPAddress() {
- return this.gatewayIPAddress;
- }
-
- /**
- * @param gatewayIPAddress
- * the gatewayIPAddress to set
- * @return this
- */
- public DHCP setGatewayIPAddress(final int gatewayIPAddress) {
- this.gatewayIPAddress = gatewayIPAddress;
- return this;
- }
-
- /**
- * @return the clientHardwareAddress
- */
- public byte[] getClientHardwareAddress() {
- return this.clientHardwareAddress;
- }
-
- /**
- * @param clientHardwareAddress
- * the clientHardwareAddress to set
- * @return this
- */
- public DHCP setClientHardwareAddress(final byte[] clientHardwareAddress) {
- this.clientHardwareAddress = clientHardwareAddress;
- return this;
- }
-
- /**
- * Gets a specific DHCP option parameter.
- *
- * @param optionCode
- * The option code to get
- * @return The value of the option if it exists, null otherwise
- */
- public DHCPOption getOption(final DHCPOptionCode optionCode) {
- for (final DHCPOption opt : this.options) {
- if (opt.code == optionCode.value) {
- return opt;
- }
- }
- return null;
- }
-
- /**
- * @return the options
- */
- public List<DHCPOption> getOptions() {
- return this.options;
- }
-
- /**
- * @param options
- * the options to set
- * @return this
- */
- public DHCP setOptions(final List<DHCPOption> options) {
- this.options = options;
- return this;
- }
-
- /**
- * @return the packetType base on option 53
- */
- public DHCPPacketType getPacketType() {
- final ListIterator<DHCPOption> lit = this.options.listIterator();
- while (lit.hasNext()) {
- final DHCPOption option = lit.next();
- // only care option 53
- if (option.getCode() == 53) {
- return DHCPPacketType.getType(option.getData()[0]);
- }
- }
- return null;
- }
-
- /**
- * @return the serverName
- */
- public String getServerName() {
- return this.serverName;
- }
-
- /**
- * @param server
- * the serverName to set
- * @return this
- */
- public DHCP setServerName(final String server) {
- this.serverName = server;
- return this;
- }
-
- /**
- * @return the bootFileName
- */
- public String getBootFileName() {
- return this.bootFileName;
- }
-
- /**
- * @param bootFile
- * the bootFileName to set
- * @return this
- */
- public DHCP setBootFileName(final String bootFile) {
- this.bootFileName = bootFile;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- // not guaranteed to retain length/exact format
- this.resetChecksum();
-
- // minimum size 240 including magic cookie, options generally padded to
- // 300
- int optionsLength = 0;
- for (final DHCPOption option : this.options) {
- if (option.getCode() == 0 || option.getCode() == ((byte) 255)) {
- optionsLength += 1;
- } else {
- optionsLength += 2 + (0xff & option.getLength());
- }
- }
- int optionsPadLength = 0;
- if (optionsLength < 60) {
- optionsPadLength = 60 - optionsLength;
- }
-
- final byte[] data = new byte[240 + optionsLength + optionsPadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.opCode);
- bb.put(this.hardwareType);
- bb.put(this.hardwareAddressLength);
- bb.put(this.hops);
- bb.putInt(this.transactionId);
- bb.putShort(this.seconds);
- bb.putShort(this.flags);
- bb.putInt(this.clientIPAddress);
- bb.putInt(this.yourIPAddress);
- bb.putInt(this.serverIPAddress);
- bb.putInt(this.gatewayIPAddress);
- checkArgument(this.clientHardwareAddress.length <= 16,
- "Hardware address is too long (%s bytes)", this.clientHardwareAddress.length);
- bb.put(this.clientHardwareAddress);
- if (this.clientHardwareAddress.length < 16) {
- for (int i = 0; i < 16 - this.clientHardwareAddress.length; ++i) {
- bb.put((byte) 0x0);
- }
- }
- this.writeString(this.serverName, bb, 64);
- this.writeString(this.bootFileName, bb, 128);
- // magic cookie
- bb.put((byte) 0x63);
- bb.put((byte) 0x82);
- bb.put((byte) 0x53);
- bb.put((byte) 0x63);
- for (final DHCPOption option : this.options) {
- final int code = option.getCode() & 0xff;
- bb.put((byte) code);
- if (code != 0 && code != 255) {
- bb.put(option.getLength());
- bb.put(option.getData());
- }
- }
- // assume the rest is padded out with zeroes
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- if (bb.remaining() < DHCP.MIN_HEADER_LENGTH) {
- return this;
- }
-
- this.opCode = bb.get();
- this.hardwareType = bb.get();
- this.hardwareAddressLength = bb.get();
- this.hops = bb.get();
- this.transactionId = bb.getInt();
- this.seconds = bb.getShort();
- this.flags = bb.getShort();
- this.clientIPAddress = bb.getInt();
- this.yourIPAddress = bb.getInt();
- this.serverIPAddress = bb.getInt();
- this.gatewayIPAddress = bb.getInt();
- final int hardwareAddressLength = 0xff & this.hardwareAddressLength;
- this.clientHardwareAddress = new byte[hardwareAddressLength];
-
- bb.get(this.clientHardwareAddress);
- for (int i = hardwareAddressLength; i < 16; ++i) {
- bb.get();
- }
- this.serverName = this.readString(bb, 64);
- this.bootFileName = this.readString(bb, 128);
- // read the magic cookie
- // magic cookie
- bb.get();
- bb.get();
- bb.get();
- bb.get();
- // read options
- while (bb.hasRemaining()) {
- final DHCPOption option = new DHCPOption();
- int code = 0xff & bb.get(); // convert signed byte to int in range
- // [0,255]
- option.setCode((byte) code);
- if (code == 0) {
- // skip these
- continue;
- } else if (code != 255) {
- if (bb.hasRemaining()) {
- final int l = 0xff & bb.get(); // convert signed byte to
- // int in range [0,255]
- option.setLength((byte) l);
- if (bb.remaining() >= l) {
- final byte[] optionData = new byte[l];
- bb.get(optionData);
- option.setData(optionData);
- } else {
- // Skip the invalid option and set the END option
- code = 0xff;
- option.setCode((byte) code);
- option.setLength((byte) 0);
- }
- } else {
- // Skip the invalid option and set the END option
- code = 0xff;
- option.setCode((byte) code);
- option.setLength((byte) 0);
- }
- }
- this.options.add(option);
- if (code == 255) {
- // remaining bytes are supposed to be 0, but ignore them just in
- // case
- break;
- }
- }
-
- return this;
- }
-
- protected void writeString(final String string, final ByteBuffer bb,
- final int maxLength) {
- if (string == null) {
- for (int i = 0; i < maxLength; ++i) {
- bb.put((byte) 0x0);
- }
- } else {
- byte[] bytes = null;
- try {
- bytes = string.getBytes("ascii");
- } catch (final UnsupportedEncodingException e) {
- throw new RuntimeException("Failure encoding server name", e);
- }
- int writeLength = bytes.length;
- if (writeLength > maxLength) {
- writeLength = maxLength;
- }
- bb.put(bytes, 0, writeLength);
- for (int i = writeLength; i < maxLength; ++i) {
- bb.put((byte) 0x0);
- }
- }
- }
-
- private static String readString(final ByteBuffer bb, final int maxLength) {
- final byte[] bytes = new byte[maxLength];
- bb.get(bytes);
- String result = null;
- try {
- result = new String(bytes, "ascii").trim();
- } catch (final UnsupportedEncodingException e) {
- throw new RuntimeException("Failure decoding string", e);
- }
- return result;
- }
-
- /**
- * Deserializer function for DHCP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<DHCP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, MIN_HEADER_LENGTH);
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- DHCP dhcp = new DHCP();
-
- dhcp.opCode = bb.get();
- dhcp.hardwareType = bb.get();
- dhcp.hardwareAddressLength = bb.get();
- dhcp.hops = bb.get();
- dhcp.transactionId = bb.getInt();
- dhcp.seconds = bb.getShort();
- dhcp.flags = bb.getShort();
- dhcp.clientIPAddress = bb.getInt();
- dhcp.yourIPAddress = bb.getInt();
- dhcp.serverIPAddress = bb.getInt();
- dhcp.gatewayIPAddress = bb.getInt();
- final int hardwareAddressLength = 0xff & dhcp.hardwareAddressLength;
- dhcp.clientHardwareAddress = new byte[hardwareAddressLength];
-
- bb.get(dhcp.clientHardwareAddress);
- for (int i = hardwareAddressLength; i < 16; ++i) {
- bb.get();
- }
- dhcp.serverName = readString(bb, 64);
- dhcp.bootFileName = readString(bb, 128);
- // read the magic cookie
- // magic cookie
- bb.get();
- bb.get();
- bb.get();
- bb.get();
-
- // read options
- boolean foundEndOptionsMarker = false;
- while (bb.hasRemaining()) {
- final DHCPOption option = new DHCPOption();
- int code = 0xff & bb.get(); // convert signed byte to int in range
- // [0,255]
- option.setCode((byte) code);
- if (code == 0) {
- // skip these
- continue;
- } else if (code != 255) {
- if (bb.hasRemaining()) {
- final int l = 0xff & bb.get(); // convert signed byte to
- // int in range [0,255]
- option.setLength((byte) l);
- if (bb.remaining() >= l) {
- final byte[] optionData = new byte[l];
- bb.get(optionData);
- option.setData(optionData);
- dhcp.options.add(option);
- } else {
- throw new DeserializationException(
- "Buffer underflow while reading DHCP option");
- }
- }
- } else if (code == 255) {
- DHCPOption end = new DHCPOption();
- end.setCode((byte) 255);
- dhcp.options.add(end);
- // remaining bytes are supposed to be 0, but ignore them just in
- // case
- foundEndOptionsMarker = true;
- break;
- }
- }
-
- if (!foundEndOptionsMarker) {
- throw new DeserializationException("DHCP End options marker was missing");
- }
-
- return dhcp;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPOption.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPOption.java
deleted file mode 100644
index 1b6c670e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPOption.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.util.Arrays;
-
-/**
- *
- */
-public class DHCPOption {
- protected byte code;
- protected byte length;
- protected byte[] data;
-
- /**
- * @return the code
- */
- public byte getCode() {
- return this.code;
- }
-
- /**
- * @param code
- * the code to set
- * @return this
- */
- public DHCPOption setCode(final byte code) {
- this.code = code;
- return this;
- }
-
- /**
- * @return the length
- */
- public byte getLength() {
- return this.length;
- }
-
- /**
- * @param length
- * the length to set
- * @return this
- */
- public DHCPOption setLength(final byte length) {
- this.length = length;
- return this;
- }
-
- /**
- * @return the data
- */
- public byte[] getData() {
- return this.data;
- }
-
- /**
- * @param data
- * the data to set
- * @return this
- */
- public DHCPOption setData(final byte[] data) {
- this.data = data;
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + this.code;
- result = prime * result + Arrays.hashCode(this.data);
- result = prime * result + this.length;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof DHCPOption)) {
- return false;
- }
- final DHCPOption other = (DHCPOption) obj;
- if (this.code != other.code) {
- return false;
- }
- if (!Arrays.equals(this.data, other.data)) {
- return false;
- }
- if (this.length != other.length) {
- return false;
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "DHCPOption [code=" + this.code + ", length=" + this.length
- + ", data=" + Arrays.toString(this.data) + "]";
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPPacketType.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPPacketType.java
deleted file mode 100644
index 8254c770..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCPPacketType.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-public enum DHCPPacketType {
- // From RFC 1533
- DHCPDISCOVER(1), DHCPOFFER(2), DHCPREQUEST(3), DHCPDECLINE(4), DHCPACK(5), DHCPNAK(
- 6), DHCPRELEASE(7),
-
- // From RFC2132
- DHCPINFORM(8),
-
- // From RFC3203
- DHCPFORCERENEW(9),
-
- // From RFC4388
- DHCPLEASEQUERY(10), DHCPLEASEUNASSIGNED(11), DHCPLEASEUNKNOWN(12), DHCPLEASEACTIVE(
- 13);
-
- protected int value;
-
- private DHCPPacketType(final int value) {
- this.value = value;
- }
-
- public int getValue() {
- return this.value;
- }
-
- @Override
- public String toString() {
- switch (this.value) {
- case 1:
- return "DHCPDISCOVER";
- case 2:
- return "DHCPOFFER";
- case 3:
- return "DHCPREQUEST";
- case 4:
- return "DHCPDECLINE";
- case 5:
- return "DHCPACK";
- case 6:
- return "DHCPNAK";
- case 7:
- return "DHCPRELEASE";
- case 8:
- return "DHCPINFORM";
- case 9:
- return "DHCPFORCERENEW";
- case 10:
- return "DHCPLEASEQUERY";
- case 11:
- return "DHCPLEASEUNASSIGNED";
- case 12:
- return "DHCPLEASEUNKNOWN";
- case 13:
- return "DHCPLEASEACTIVE";
- default:
- break;
- }
-
- return null;
- }
-
- public static DHCPPacketType getType(final int value) {
- switch (value) {
- case 1:
- return DHCPDISCOVER;
- case 2:
- return DHCPOFFER;
- case 3:
- return DHCPREQUEST;
- case 4:
- return DHCPDECLINE;
- case 5:
- return DHCPACK;
- case 6:
- return DHCPNAK;
- case 7:
- return DHCPRELEASE;
- case 8:
- return DHCPINFORM;
- case 9:
- return DHCPFORCERENEW;
- case 10:
- return DHCPLEASEQUERY;
- case 11:
- return DHCPLEASEUNASSIGNED;
- case 12:
- return DHCPLEASEUNKNOWN;
- case 13:
- return DHCPLEASEACTIVE;
- default:
- break;
- }
-
- return null;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Data.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Data.java
deleted file mode 100644
index 79abcba1..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Data.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- *
- */
-public class Data extends BasePacket {
- protected byte[] data;
-
- /**
- *
- */
- public Data() {
- data = new byte[0];
- }
-
- /**
- * @param data the data
- */
- public Data(final byte[] data) {
- this.data = data;
- }
-
- /**
- * @return the data
- */
- public byte[] getData() {
- return this.data;
- }
-
- /**
- * @param data
- * the data to set
- * @return self
- */
- public Data setData(final byte[] data) {
- this.data = data;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- return this.data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- this.data = Arrays.copyOfRange(data, offset, data.length);
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 1571;
- int result = super.hashCode();
- result = prime * result + Arrays.hashCode(this.data);
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Data)) {
- return false;
- }
- final Data other = (Data) obj;
- if (!Arrays.equals(this.data, other.data)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for generic payload data.
- *
- * @return deserializer function
- */
- public static Deserializer<Data> deserializer() {
- return (data, offset, length) -> {
- // Allow zero-length data for now
- if (length == 0) {
- return new Data();
- }
-
- checkInput(data, offset, length, 1);
-
- Data dataObject = new Data();
-
- dataObject.data = Arrays.copyOfRange(data, offset, data.length);
-
- return dataObject;
- };
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DeserializationException.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DeserializationException.java
deleted file mode 100644
index 03a8aa35..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DeserializationException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-/**
- * Signals that an error occurred during deserialization of a packet.
- */
-public class DeserializationException extends Exception {
-
- /**
- * Creates a new deserialization exception with the given message.
- *
- * @param message exception message
- */
- public DeserializationException(String message) {
- super(message);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Deserializer.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Deserializer.java
deleted file mode 100644
index e0ef381b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Deserializer.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-/**
- * Function to deserialize a packet from a byte-based input stream.
- */
-@FunctionalInterface
-public interface Deserializer<U extends IPacket> {
-
- /**
- * Deserialize a packet object from a byte array.
- *
- * @param data input array to take packet bytes from
- * @param offset index where this packet header begins in the byte array
- * @param length length of the packet header
- * @return a deserialized packet object
- * @throws DeserializationException if the packet cannot be deserialized
- * from the input
- */
- U deserialize(byte[] data, int offset, int length) throws DeserializationException;
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAP.java
deleted file mode 100644
index 516938a4..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAP.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- *
- * * Copyright 2015 AT&T Foundry
- * *
- * * Licensed under the Apache License, Version 2.0 (the "License");
- * * you may not use this file except in compliance with the License.
- * * You may obtain a copy of the License at
- * *
- * * http://www.apache.org/licenses/LICENSE-2.0
- * *
- * * Unless required by applicable law or agreed to in writing, software
- * * distributed under the License is distributed on an "AS IS" BASIS,
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * * See the License for the specific language governing permissions and
- * * limitations under the License.
- *
- */
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * EAP (Extensible Authentication Protocol) packet.
- */
-public class EAP extends BasePacket {
- private static final int HEADER_LENGTH = 4;
-
- public static final short MIN_LEN = 0x4;
- public static final short EAP_HDR_LEN_REQ_RESP = 5;
- public static final short EAP_HDR_LEN_SUC_FAIL = 4;
-
- // EAP Code
- public static final byte REQUEST = 0x1;
- public static final byte RESPONSE = 0x2;
- public static final byte SUCCESS = 0x3;
- public static final byte FAILURE = 0x4;
-
- // EAP Attribute Type
- public static final byte ATTR_IDENTITY = 0x1;
- public static final byte ATTR_NOTIFICATION = 0x2;
- public static final byte ATTR_NAK = 0x3;
- public static final byte ATTR_MD5 = 0x4;
- public static final byte ATTR_OTP = 0x5;
- public static final byte ATTR_GTC = 0x6;
- public static final byte ATTR_TLS = 0xd;
-
- protected byte code;
- protected byte identifier;
- protected short length;
- protected byte type;
- protected byte[] data;
-
-
- /**
- * Gets the EAP code.
- *
- * @return EAP code
- */
- public byte getCode() {
- return this.code;
- }
-
-
- /**
- * Sets the EAP code.
- *
- * @param code EAP code
- * @return this
- */
- public EAP setCode(final byte code) {
- this.code = code;
- return this;
- }
-
- /**
- * Gets the EAP identifier.
- *
- * @return EAP identifier
- */
- public byte getIdentifier() {
- return this.identifier;
- }
-
- /**
- * Sets the EAP identifier.
- *
- * @param identifier EAP identifier
- * @return this
- */
- public EAP setIdentifier(final byte identifier) {
- this.identifier = identifier;
- return this;
- }
-
- /**
- * Gets the get packet length.
- *
- * @return packet length
- */
- public short getLength() {
- return this.length;
- }
-
- /**
- * Sets the packet length.
- *
- * @param length packet length
- * @return this
- */
- public EAP setLength(final short length) {
- this.length = length;
- return this;
- }
-
- /**
- * Gets the data type.
- *
- * @return data type
- */
- public byte getDataType() {
- return this.type;
- }
-
- /**
- * Sets the data type.
- *
- * @param type data type
- * @return this
- */
- public EAP setDataType(final byte type) {
- this.type = type;
- return this;
- }
-
- /**
- * Gets the EAP data.
- *
- * @return EAP data
- */
- public byte[] getData() {
- return this.data;
- }
-
- /**
- * Sets the EAP data.
- *
- * @param data EAP data to be set
- * @return this
- */
- public EAP setData(final byte[] data) {
- this.data = data;
- return this;
- }
-
- /**
- * Default EAP constructor that sets the EAP code to 0.
- */
- public EAP() {
- this.code = 0;
- }
-
- /**
- * EAP constructor that initially sets all fields.
- *
- * @param code EAP code
- * @param identifier EAP identifier
- * @param type packet type
- * @param data EAP data
- */
- public EAP(byte code, byte identifier, byte type, byte[] data) {
- this.code = code;
- this.identifier = identifier;
- if (this.code == REQUEST || this.code == RESPONSE) {
- this.length = (short) (5 + (data == null ? 0 : data.length));
- this.type = type;
- } else {
- this.length = (short) (4 + (data == null ? 0 : data.length));
- }
- this.data = data;
- }
-
- /**
- * Deserializer for EAP packets.
- *
- * @return deserializer
- */
- public static Deserializer<EAP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- EAP eap = new EAP();
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- eap.code = bb.get();
- eap.identifier = bb.get();
- eap.length = bb.getShort();
-
- checkHeaderLength(length, eap.length);
-
- int dataLength;
- if (eap.code == REQUEST || eap.code == RESPONSE) {
- eap.type = bb.get();
- dataLength = eap.length - 5;
- } else {
- dataLength = eap.length - 4;
- }
-
- eap.data = new byte[dataLength];
- bb.get(eap.data);
- return eap;
- };
- }
-
- @Override
- public byte[] serialize() {
- final byte[] data = new byte[this.length];
-
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.code);
- bb.put(this.identifier);
- bb.putShort(this.length);
- if (this.code == REQUEST || this.code == RESPONSE) {
- bb.put(this.type);
- }
- if (this.data != null) {
- bb.put(this.data);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.code = bb.get();
- this.identifier = bb.get();
- this.length = bb.getShort();
-
- int dataLength;
- if (this.code == REQUEST || this.code == RESPONSE) {
- this.type = bb.get();
- dataLength = this.length - 5;
- } else {
- dataLength = this.length - 4;
- }
- this.data = new byte[dataLength];
- bb.get(this.data);
- return this;
- }
-
- @Override
- public int hashCode() {
- final int prime = 3889;
- int result = super.hashCode();
- result = prime * result + this.code;
- result = prime * result + this.identifier;
- result = prime * result + this.length;
- result = prime * result + this.type;
- return result;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java
deleted file mode 100644
index 1820cc31..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *
- * * Copyright 2015 AT&T Foundry
- * *
- * * Licensed under the Apache License, Version 2.0 (the "License");
- * * you may not use this file except in compliance with the License.
- * * You may obtain a copy of the License at
- * *
- * * http://www.apache.org/licenses/LICENSE-2.0
- * *
- * * Unless required by applicable law or agreed to in writing, software
- * * distributed under the License is distributed on an "AS IS" BASIS,
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * * See the License for the specific language governing permissions and
- * * limitations under the License.
- *
- */
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * EAPOL (Extensible Authentication Protocol over LAN) header.
- */
-public class EAPOL extends BasePacket {
-
- private byte version = 0x01;
- private byte eapolType;
- private short packetLength;
-
- private static final int HEADER_LENGTH = 4;
-
- // EAPOL Packet Type
- public static final byte EAPOL_PACKET = 0x0;
- public static final byte EAPOL_START = 0x1;
- public static final byte EAPOL_LOGOFF = 0x2;
- public static final byte EAPOL_KEY = 0x3;
- public static final byte EAPOL_ASF = 0x4;
-
- public static final MacAddress PAE_GROUP_ADDR = MacAddress.valueOf(new byte[] {
- (byte) 0x01, (byte) 0x80, (byte) 0xc2, (byte) 0x00, (byte) 0x00, (byte) 0x03
- });
-
- /**
- * Gets the version.
- *
- * @return version
- */
- public byte getVersion() {
- return this.version;
- }
-
- /**
- * Sets the version.
- *
- * @param version EAPOL version
- * @return this
- */
- public EAPOL setVersion(final byte version) {
- this.version = version;
- return this;
- }
-
- /**
- * Gets the type.
- *
- * @return EAPOL type
- */
- public byte getEapolType() {
- return this.eapolType;
- }
-
- /**
- * Sets the EAPOL type.
- *
- * @param eapolType EAPOL type
- * @return this
- */
- public EAPOL setEapolType(final byte eapolType) {
- this.eapolType = eapolType;
- return this;
- }
-
- /**
- * Gets the packet length.
- *
- * @return packet length
- */
- public short getPacketLength() {
- return this.packetLength;
- }
-
- /**
- * Sets the packet length.
- *
- * @param packetLen packet length
- * @return this
- */
- public EAPOL setPacketLength(final short packetLen) {
- this.packetLength = packetLen;
- return this;
- }
-
- /**
- * Serializes the packet, based on the code/type using the payload
- * to compute its length.
- *
- * @return this
- */
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
-
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- // prepare the buffer to hold the version (1), packet type (1),
- // packet length (2) and the eap payload.
- // if there is no payload, packet length is 0
- byte[] data = new byte[4 + this.packetLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.version);
- bb.put(this.eapolType);
- bb.putShort(this.packetLength);
-
- // put the EAP payload
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- return data;
- }
-
- @Override
- public int hashCode() {
- final int prime = 3889;
- int result = super.hashCode();
- result = prime * result + this.version;
- result = prime * result + this.eapolType;
- result = prime * result + this.packetLength;
- return result;
- }
-
- /**
- * Deserializer for EAPOL packets.
- *
- * @return deserializer
- */
- public static Deserializer<EAPOL> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- EAPOL eapol = new EAPOL();
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- eapol.setVersion(bb.get());
- eapol.setEapolType(bb.get());
- eapol.setPacketLength(bb.getShort());
-
- if (eapol.packetLength > 0) {
- checkHeaderLength(length, HEADER_LENGTH + eapol.packetLength);
- // deserialize the EAP Payload
- eapol.payload = EAP.deserializer().deserialize(data,
- bb.position(), bb.limit() - bb.position());
-
- eapol.payload.setParent(eapol);
- }
-
- return eapol;
- };
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- // deserialize the EAPOL header
- this.version = bb.get();
- this.eapolType = bb.get();
- this.packetLength = bb.getShort();
-
- if (this.packetLength > 0) {
- // deserialize the EAP Payload
- this.payload = new EAP();
-
- this.payload = this.payload.deserialize(data, bb.position(), length - 4);
- this.payload.setParent(this);
- }
-
- return this;
- }
-}
-
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EthType.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EthType.java
deleted file mode 100644
index b3b79e2c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EthType.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-/**
- * Representation of an Ethertype.
- */
-public class EthType {
-
- /**
- * A list of known ethertypes. Adding a fully defined enum here will
- * associated the ethertype with a textual representation and a parsing
- * class.
- */
- public enum EtherType {
-
- ARP(0x806, "arp", org.onlab.packet.ARP.deserializer()),
- RARP(0x8035, "rarp", org.onlab.packet.ARP.deserializer()),
- IPV4(0x800, "ipv4", org.onlab.packet.IPv4.deserializer()),
- IPV6(0x86dd, "ipv6", org.onlab.packet.IPv6.deserializer()),
- LLDP(0x88cc, "lldp", org.onlab.packet.LLDP.deserializer()),
- VLAN(0x8100, "vlan", null),
- BDDP(0x8942, "bddp", org.onlab.packet.LLDP.deserializer()),
- MPLS_UNICAST(0x8847, "mpls_unicast", org.onlab.packet.MPLS.deserializer()),
- MPLS_MULTICAST(0x8848, "mpls_unicast", org.onlab.packet.MPLS.deserializer()),
- EAPOL(0x888e, "eapol", org.onlab.packet.EAPOL.deserializer()),
- UNKNOWN(0, "unknown", null);
-
-
- private final EthType etherType;
- private final String type;
- private final Deserializer<?> deserializer;
-
- /**
- * Constructs a new ethertype.
- *
- * @param ethType The actual ethertype
- * @param type it's textual representation
- * @param deserializer a parser for this ethertype
- */
- EtherType(int ethType, String type, Deserializer<?> deserializer) {
- this.etherType = new EthType(ethType);
- this.type = type;
- this.deserializer = deserializer;
- }
-
- public EthType ethType() {
- return etherType;
- }
-
- @Override
- public String toString() {
- return type;
- }
-
- public Deserializer<?> deserializer() {
- return deserializer;
- }
-
- public static EtherType lookup(short etherType) {
- for (EtherType ethType : EtherType.values()) {
- if (ethType.ethType().toShort() == etherType) {
- return ethType;
- }
- }
- return UNKNOWN;
- }
-
- }
-
-
- private final short etherType;
-
- /**
- * Builds the EthType.
- *
- * @param etherType an integer representing an ethtype
- */
- public EthType(int etherType) {
- this.etherType = (short) (etherType & 0xFFFF);
- }
-
- /**
- * Builds the EthType.
- *
- * @param etherType a short representing the ethtype
- */
- public EthType(short etherType) {
- this.etherType = etherType;
- }
-
- /**
- * Returns the short value for this ethtype.
- *
- * @return a short value
- */
- public short toShort() {
- return etherType;
- }
-
- /**
- * Looks up the ethertype by it's numerical representation
- * and returns it's textual format.
- *
- * @param etherType the short value of the ethertype
- * @return a textual representation
- */
- public EtherType lookup(short etherType) {
- for (EtherType ethType : EtherType.values()) {
- if (ethType.ethType().toShort() == etherType) {
- return ethType;
- }
- }
- return null;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- EthType ethType = (EthType) o;
-
- if (etherType != ethType.etherType) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return (int) etherType;
- }
-
- public String toString() {
- EtherType ethType = lookup(this.etherType);
- return (ethType == null ? String.format("0x%04x", etherType) :
- ethType.toString());
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ethernet.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
deleted file mode 100644
index 9ab5cab1..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.onlab.packet.ndp.NeighborAdvertisement;
-import org.onlab.packet.ndp.NeighborSolicitation;
-import org.onlab.packet.ndp.Redirect;
-import org.onlab.packet.ndp.RouterAdvertisement;
-import org.onlab.packet.ndp.RouterSolicitation;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- *
- */
-public class Ethernet extends BasePacket {
- private static final String HEXES = "0123456789ABCDEF";
-
- public static final short TYPE_ARP = EthType.EtherType.ARP.ethType().toShort();
- public static final short TYPE_RARP = EthType.EtherType.RARP.ethType().toShort();
- public static final short TYPE_IPV4 = EthType.EtherType.IPV4.ethType().toShort();
- public static final short TYPE_IPV6 = EthType.EtherType.IPV6.ethType().toShort();
- public static final short TYPE_LLDP = EthType.EtherType.LLDP.ethType().toShort();
- public static final short TYPE_VLAN = EthType.EtherType.VLAN.ethType().toShort();
- public static final short TYPE_BSN = EthType.EtherType.BDDP.ethType().toShort();
-
- public static final short MPLS_UNICAST = EthType.EtherType.MPLS_UNICAST.ethType().toShort();;
- public static final short MPLS_MULTICAST = EthType.EtherType.MPLS_MULTICAST.ethType().toShort();
-
-
- public static final short VLAN_UNTAGGED = (short) 0xffff;
-
- public static final short ETHERNET_HEADER_LENGTH = 14; // bytes
- public static final short VLAN_HEADER_LENGTH = 4; // bytes
-
- public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes
-
- private static final Map<Short, Deserializer<? extends IPacket>> ETHERTYPE_DESERIALIZER_MAP =
- new HashMap<>();
-
- static {
- for (EthType.EtherType ethType : EthType.EtherType.values()) {
- if (ethType.deserializer() != null) {
- ETHERTYPE_DESERIALIZER_MAP.put(ethType.ethType().toShort(), ethType.deserializer());
- }
- }
- }
-
- protected MacAddress destinationMACAddress;
- protected MacAddress sourceMACAddress;
- protected byte priorityCode;
- protected short vlanID;
- protected short etherType;
- protected boolean pad = false;
-
- /**
- * By default, set Ethernet to untagged.
- */
- public Ethernet() {
- super();
- this.vlanID = Ethernet.VLAN_UNTAGGED;
- }
-
- /**
- * Gets the destination MAC address.
- *
- * @return the destination MAC as a byte array
- */
- public byte[] getDestinationMACAddress() {
- return this.destinationMACAddress.toBytes();
- }
-
- /**
- * Gets the destination MAC address.
- *
- * @return the destination MAC
- */
- public MacAddress getDestinationMAC() {
- return this.destinationMACAddress;
- }
-
- /**
- * Sets the destination MAC address.
- *
- * @param destMac the destination MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setDestinationMACAddress(final MacAddress destMac) {
- this.destinationMACAddress = checkNotNull(destMac);
- return this;
- }
-
- /**
- * Sets the destination MAC address.
- *
- * @param destMac the destination MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setDestinationMACAddress(final byte[] destMac) {
- this.destinationMACAddress = MacAddress.valueOf(destMac);
- return this;
- }
-
- /**
- * Sets the destination MAC address.
- *
- * @param destMac the destination MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setDestinationMACAddress(final String destMac) {
- this.destinationMACAddress = MacAddress.valueOf(destMac);
- return this;
- }
-
- /**
- * Gets the source MAC address.
- *
- * @return the source MACAddress as a byte array
- */
- public byte[] getSourceMACAddress() {
- return this.sourceMACAddress.toBytes();
- }
-
- /**
- * Gets the source MAC address.
- *
- * @return the source MACAddress
- */
- public MacAddress getSourceMAC() {
- return this.sourceMACAddress;
- }
-
- /**
- * Sets the source MAC address.
- *
- * @param sourceMac the source MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setSourceMACAddress(final MacAddress sourceMac) {
- this.sourceMACAddress = checkNotNull(sourceMac);
- return this;
- }
-
- /**
- * Sets the source MAC address.
- *
- * @param sourceMac the source MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setSourceMACAddress(final byte[] sourceMac) {
- this.sourceMACAddress = MacAddress.valueOf(sourceMac);
- return this;
- }
-
- /**
- * Sets the source MAC address.
- *
- * @param sourceMac the source MAC to set
- * @return the Ethernet frame
- */
- public Ethernet setSourceMACAddress(final String sourceMac) {
- this.sourceMACAddress = MacAddress.valueOf(sourceMac);
- return this;
- }
-
- /**
- * Gets the priority code.
- *
- * @return the priorityCode
- */
- public byte getPriorityCode() {
- return this.priorityCode;
- }
-
- /**
- * Sets the priority code.
- *
- * @param priority the priorityCode to set
- * @return the Ethernet frame
- */
- public Ethernet setPriorityCode(final byte priority) {
- this.priorityCode = priority;
- return this;
- }
-
- /**
- * Gets the VLAN ID.
- *
- * @return the vlanID
- */
- public short getVlanID() {
- return this.vlanID;
- }
-
- /**
- * Sets the VLAN ID.
- *
- * @param vlan the vlanID to set
- * @return the Ethernet frame
- */
- public Ethernet setVlanID(final short vlan) {
- this.vlanID = vlan;
- return this;
- }
-
- /**
- * Gets the Ethernet type.
- *
- * @return the etherType
- */
- public short getEtherType() {
- return this.etherType;
- }
-
- /**
- * Sets the Ethernet type.
- *
- * @param ethType the etherType to set
- * @return the Ethernet frame
- */
- public Ethernet setEtherType(final short ethType) {
- this.etherType = ethType;
- return this;
- }
-
- /**
- * @return True if the Ethernet frame is broadcast, false otherwise
- */
- public boolean isBroadcast() {
- assert this.destinationMACAddress.length() == 6;
- return this.destinationMACAddress.isBroadcast();
- }
-
- /**
- * @return True is the Ethernet frame is multicast, False otherwise
- */
- public boolean isMulticast() {
- return this.destinationMACAddress.isMulticast();
- }
-
- /**
- * Pad this packet to 60 bytes minimum, filling with zeros?
- *
- * @return the pad
- */
- public boolean isPad() {
- return this.pad;
- }
-
- /**
- * Pad this packet to 60 bytes minimum, filling with zeros?
- *
- * @param pd
- * the pad to set
- * @return this
- */
- public Ethernet setPad(final boolean pd) {
- this.pad = pd;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
- int length = 14 + (this.vlanID == Ethernet.VLAN_UNTAGGED ? 0 : 4)
- + (payloadData == null ? 0 : payloadData.length);
- if (this.pad && length < 60) {
- length = 60;
- }
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.destinationMACAddress.toBytes());
- bb.put(this.sourceMACAddress.toBytes());
- if (this.vlanID != Ethernet.VLAN_UNTAGGED) {
- bb.putShort(TYPE_VLAN);
- bb.putShort((short) (this.priorityCode << 13 | this.vlanID & 0x0fff));
- }
- bb.putShort(this.etherType);
- if (payloadData != null) {
- bb.put(payloadData);
- }
- if (this.pad) {
- Arrays.fill(data, bb.position(), data.length, (byte) 0x0);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- if (length <= 0) {
- return null;
- }
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- if (this.destinationMACAddress == null) {
- this.destinationMACAddress = MacAddress.valueOf(new byte[6]);
- }
- final byte[] dstAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
- bb.get(dstAddr);
- this.destinationMACAddress = MacAddress.valueOf(dstAddr);
-
- if (this.sourceMACAddress == null) {
- this.sourceMACAddress = MacAddress.valueOf(new byte[6]);
- }
- final byte[] srcAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
- bb.get(srcAddr);
- this.sourceMACAddress = MacAddress.valueOf(srcAddr);
-
- short ethType = bb.getShort();
- if (ethType == TYPE_VLAN) {
- final short tci = bb.getShort();
- this.priorityCode = (byte) (tci >> 13 & 0x07);
- this.vlanID = (short) (tci & 0x0fff);
- ethType = bb.getShort();
- } else {
- this.vlanID = Ethernet.VLAN_UNTAGGED;
- }
- this.etherType = ethType;
-
- IPacket payload;
- Deserializer<? extends IPacket> deserializer;
- if (Ethernet.ETHERTYPE_DESERIALIZER_MAP.containsKey(ethType)) {
- deserializer = Ethernet.ETHERTYPE_DESERIALIZER_MAP.get(ethType);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
- return this;
- }
-
- /**
- * Checks to see if a string is a valid MAC address.
- *
- * @param macAddress string to test if it is a valid MAC
- * @return True if macAddress is a valid MAC, False otherwise
- */
- public static boolean isMACAddress(final String macAddress) {
- final String[] macBytes = macAddress.split(":");
- if (macBytes.length != 6) {
- return false;
- }
- for (int i = 0; i < 6; ++i) {
- if (Ethernet.HEXES.indexOf(macBytes[i].toUpperCase().charAt(0)) == -1
- || Ethernet.HEXES.indexOf(macBytes[i].toUpperCase().charAt(
- 1)) == -1) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Accepts a MAC address of the form 00:aa:11:bb:22:cc, case does not
- * matter, and returns a corresponding byte[].
- *
- * @param macAddress
- * The MAC address to convert into a byte array
- * @return The macAddress as a byte array
- */
- public static byte[] toMACAddress(final String macAddress) {
- return MacAddress.valueOf(macAddress).toBytes();
- }
-
- /**
- * Accepts a MAC address and returns the corresponding long, where the MAC
- * bytes are set on the lower order bytes of the long.
- *
- * @param macAddress MAC address as a byte array
- * @return a long containing the mac address bytes
- */
- public static long toLong(final byte[] macAddress) {
- return MacAddress.valueOf(macAddress).toLong();
- }
-
- /**
- * Converts a long MAC address to a byte array.
- *
- * @param macAddress MAC address set on the lower order bytes of the long
- * @return the bytes of the mac address
- */
- public static byte[] toByteArray(final long macAddress) {
- return MacAddress.valueOf(macAddress).toBytes();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 7867;
- int result = super.hashCode();
- result = prime * result + this.destinationMACAddress.hashCode();
- result = prime * result + this.etherType;
- result = prime * result + this.vlanID;
- result = prime * result + this.priorityCode;
- result = prime * result + (this.pad ? 1231 : 1237);
- result = prime * result + this.sourceMACAddress.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Ethernet)) {
- return false;
- }
- final Ethernet other = (Ethernet) obj;
- if (!this.destinationMACAddress.equals(other.destinationMACAddress)) {
- return false;
- }
- if (this.priorityCode != other.priorityCode) {
- return false;
- }
- if (this.vlanID != other.vlanID) {
- return false;
- }
- if (this.etherType != other.etherType) {
- return false;
- }
- if (this.pad != other.pad) {
- return false;
- }
- if (!this.sourceMACAddress.equals(other.sourceMACAddress)) {
- return false;
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString(java.lang.Object)
- */
- @Override
- public String toString() {
-
- final StringBuffer sb = new StringBuffer("\n");
-
- final IPacket pkt = this.getPayload();
-
- if (pkt instanceof ARP) {
- sb.append("arp");
- } else if (pkt instanceof LLDP) {
- sb.append("lldp");
- } else if (pkt instanceof ICMP) {
- sb.append("icmp");
- } else if (pkt instanceof IPv4) {
- sb.append("ip");
- } else if (pkt instanceof DHCP) {
- sb.append("dhcp");
- } else {
- sb.append(this.getEtherType());
- }
-
- sb.append("\ndl_vlan: ");
- if (this.getVlanID() == Ethernet.VLAN_UNTAGGED) {
- sb.append("untagged");
- } else {
- sb.append(this.getVlanID());
- }
- sb.append("\ndl_vlan_pcp: ");
- sb.append(this.getPriorityCode());
- sb.append("\ndl_src: ");
- sb.append(bytesToHex(this.getSourceMACAddress()));
- sb.append("\ndl_dst: ");
- sb.append(bytesToHex(this.getDestinationMACAddress()));
-
- if (pkt instanceof ARP) {
- final ARP p = (ARP) pkt;
- sb.append("\nnw_src: ");
- sb.append(IPv4.fromIPv4Address(IPv4.toIPv4Address(p
- .getSenderProtocolAddress())));
- sb.append("\nnw_dst: ");
- sb.append(IPv4.fromIPv4Address(IPv4.toIPv4Address(p
- .getTargetProtocolAddress())));
- } else if (pkt instanceof LLDP) {
- sb.append("lldp packet");
- } else if (pkt instanceof ICMP) {
- final ICMP icmp = (ICMP) pkt;
- sb.append("\nicmp_type: ");
- sb.append(icmp.getIcmpType());
- sb.append("\nicmp_code: ");
- sb.append(icmp.getIcmpCode());
- } else if (pkt instanceof IPv4) {
- final IPv4 p = (IPv4) pkt;
- sb.append("\nnw_src: ");
- sb.append(IPv4.fromIPv4Address(p.getSourceAddress()));
- sb.append("\nnw_dst: ");
- sb.append(IPv4.fromIPv4Address(p.getDestinationAddress()));
- sb.append("\nnw_tos: ");
- sb.append(p.getDiffServ());
- sb.append("\nnw_proto: ");
- sb.append(p.getProtocol());
-
- IPacket payload = pkt.getPayload();
- if (payload != null) {
- if (payload instanceof TCP) {
- sb.append("\ntp_src: ");
- sb.append(((TCP) payload).getSourcePort());
- sb.append("\ntp_dst: ");
- sb.append(((TCP) payload).getDestinationPort());
-
- } else if (payload instanceof UDP) {
- sb.append("\ntp_src: ");
- sb.append(((UDP) payload).getSourcePort());
- sb.append("\ntp_dst: ");
- sb.append(((UDP) payload).getDestinationPort());
- } else if (payload instanceof ICMP) {
- final ICMP icmp = (ICMP) payload;
- sb.append("\nicmp_type: ");
- sb.append(icmp.getIcmpType());
- sb.append("\nicmp_code: ");
- sb.append(icmp.getIcmpCode());
- }
- }
- } else if (pkt instanceof IPv6) {
- final IPv6 ipv6 = (IPv6) pkt;
- sb.append("\nipv6_src: ");
- sb.append(Ip6Address.valueOf(ipv6.getSourceAddress()).toString());
- sb.append("\nipv6_dst: ");
- sb.append(Ip6Address.valueOf(ipv6.getDestinationAddress()).toString());
- sb.append("\nipv6_proto: ");
- sb.append(ipv6.getNextHeader());
-
- IPacket payload = pkt.getPayload();
- if (payload != null && payload instanceof ICMP6) {
- final ICMP6 icmp6 = (ICMP6) payload;
- sb.append("\nicmp6_type: ");
- sb.append(icmp6.getIcmpType());
- sb.append("\nicmp6_code: ");
- sb.append(icmp6.getIcmpCode());
-
- payload = payload.getPayload();
- if (payload != null) {
- if (payload instanceof NeighborSolicitation) {
- final NeighborSolicitation ns = (NeighborSolicitation) payload;
- sb.append("\nns_target_addr: ");
- sb.append(Ip6Address.valueOf(ns.getTargetAddress()).toString());
- ns.getOptions().forEach(option -> {
- sb.append("\noption_type: ");
- sb.append(option.type());
- sb.append("\noption_data: ");
- sb.append(bytesToHex(option.data()));
- });
- } else if (payload instanceof NeighborAdvertisement) {
- final NeighborAdvertisement na = (NeighborAdvertisement) payload;
- sb.append("\nna_target_addr: ");
- sb.append(Ip6Address.valueOf(na.getTargetAddress()).toString());
- sb.append("\nna_solicited_flag: ");
- sb.append(na.getSolicitedFlag());
- sb.append("\nna_router_flag: ");
- sb.append(na.getRouterFlag());
- sb.append("\nna_override_flag: ");
- sb.append(na.getOverrideFlag());
- na.getOptions().forEach(option -> {
- sb.append("\noption_type: ");
- sb.append(option.type());
- sb.append("\noption_data: ");
- sb.append(bytesToHex(option.data()));
- });
- } else if (payload instanceof RouterSolicitation) {
- final RouterSolicitation rs = (RouterSolicitation) payload;
- sb.append("\nrs");
- rs.getOptions().forEach(option -> {
- sb.append("\noption_type: ");
- sb.append(option.type());
- sb.append("\noption_data: ");
- sb.append(bytesToHex(option.data()));
- });
- } else if (payload instanceof RouterAdvertisement) {
- final RouterAdvertisement ra = (RouterAdvertisement) payload;
- sb.append("\nra_hop_limit: ");
- sb.append(ra.getCurrentHopLimit());
- sb.append("\nra_mflag: ");
- sb.append(ra.getMFlag());
- sb.append("\nra_oflag: ");
- sb.append(ra.getOFlag());
- sb.append("\nra_reachable_time: ");
- sb.append(ra.getReachableTime());
- sb.append("\nra_retransmit_time: ");
- sb.append(ra.getRetransmitTimer());
- sb.append("\nra_router_lifetime: ");
- sb.append(ra.getRouterLifetime());
- ra.getOptions().forEach(option -> {
- sb.append("\noption_type: ");
- sb.append(option.type());
- sb.append("\noption_data: ");
- sb.append(bytesToHex(option.data()));
- });
- } else if (payload instanceof Redirect) {
- final Redirect rd = (Redirect) payload;
- sb.append("\nrd_target_addr: ");
- sb.append(Ip6Address.valueOf(rd.getTargetAddress()).toString());
- rd.getOptions().forEach(option -> {
- sb.append("\noption_type: ");
- sb.append(option.type());
- sb.append("\noption_data: ");
- sb.append(bytesToHex(option.data()));
- });
- }
- }
- }
- } else if (pkt instanceof DHCP) {
- sb.append("\ndhcp packet");
- } else if (pkt instanceof Data) {
- sb.append("\ndata packet");
- } else if (pkt instanceof LLC) {
- sb.append("\nllc packet");
- } else {
- sb.append("\nunknown packet");
- }
-
- return sb.toString();
- }
-
- public static String bytesToHex(byte[] in) {
- final StringBuilder builder = new StringBuilder();
- for (byte b : in) {
- builder.append(String.format("%02x", b));
- }
- return builder.toString();
- }
-
- /**
- * Deserializer function for Ethernet packets.
- *
- * @return deserializer function
- */
- public static Deserializer<Ethernet> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, ETHERNET_HEADER_LENGTH);
-
- byte[] addressBuffer = new byte[DATALAYER_ADDRESS_LENGTH];
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- Ethernet eth = new Ethernet();
- // Read destination MAC address into buffer
- bb.get(addressBuffer);
- eth.setDestinationMACAddress(addressBuffer);
-
- // Read source MAC address into buffer
- bb.get(addressBuffer);
- eth.setSourceMACAddress(addressBuffer);
-
- short ethType = bb.getShort();
- if (ethType == TYPE_VLAN) {
- checkHeaderLength(length, ETHERNET_HEADER_LENGTH + VLAN_HEADER_LENGTH);
- final short tci = bb.getShort();
- eth.setPriorityCode((byte) (tci >> 13 & 0x07));
- eth.setVlanID((short) (tci & 0x0fff));
- ethType = bb.getShort();
- } else {
- eth.setVlanID(Ethernet.VLAN_UNTAGGED);
- }
- eth.setEtherType(ethType);
-
- IPacket payload;
- Deserializer<? extends IPacket> deserializer;
- if (Ethernet.ETHERTYPE_DESERIALIZER_MAP.containsKey(ethType)) {
- deserializer = Ethernet.ETHERTYPE_DESERIALIZER_MAP.get(ethType);
- } else {
- deserializer = Data.deserializer();
- }
- payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- payload.setParent(eth);
- eth.setPayload(payload);
-
- return eth;
- };
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP.java
deleted file mode 100644
index d07a9ba4..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- * Implements ICMP packet format.
- *
- */
-public class ICMP extends BasePacket {
- protected byte icmpType;
- protected byte icmpCode;
- protected short checksum;
-
- public static final byte TYPE_ECHO_REQUEST = 0x08;
- public static final byte TYPE_ECHO_REPLY = 0x00;
- public static final byte SUBTYPE_ECHO_REPLY = 0x00;
-
- public static final short ICMP_HEADER_LENGTH = 4;
-
- /**
- * @return the icmpType
- */
- public byte getIcmpType() {
- return this.icmpType;
- }
-
- /**
- * @param icmpType
- * to set
- * @return this
- */
- public ICMP setIcmpType(final byte icmpType) {
- this.icmpType = icmpType;
- return this;
- }
-
- /**
- * @return the icmp code
- */
- public byte getIcmpCode() {
- return this.icmpCode;
- }
-
- /**
- * @param icmpCode
- * code to set
- * @return this
- */
- public ICMP setIcmpCode(final byte icmpCode) {
- this.icmpCode = icmpCode;
- return this;
- }
-
- /**
- * @return the checksum
- */
- public short getChecksum() {
- return this.checksum;
- }
-
- /**
- * @param checksum
- * the checksum to set
- * @return this
- */
- public ICMP setChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
- /**
- * Serializes the packet. Will compute and set the following fields if they
- * are set to specific values at the time serialize is called: -checksum : 0
- * -length : 0
- */
- @Override
- public byte[] serialize() {
- int length = 4;
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- length += payloadData.length;
- }
-
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.icmpType);
- bb.put(this.icmpCode);
- bb.putShort(this.checksum);
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IPv4) {
- ((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_ICMP);
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bb.rewind();
- int accumulation = 0;
-
- for (int i = 0; i < length / 2; ++i) {
- accumulation += 0xffff & bb.getShort();
- }
- // pad to an even number of shorts
- if (length % 2 > 0) {
- accumulation += (bb.get() & 0xff) << 8;
- }
-
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bb.putShort(2, this.checksum);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.icmpType = bb.get();
- this.icmpCode = bb.get();
- this.checksum = bb.getShort();
-
- this.payload = new Data();
- this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- - bb.position());
- this.payload.setParent(this);
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.icmpType;
- result = prime * result + this.icmpCode;
- result = prime * result + this.checksum;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof ICMP)) {
- return false;
- }
- final ICMP other = (ICMP) obj;
- if (this.icmpType != other.icmpType) {
- return false;
- }
- if (this.icmpCode != other.icmpCode) {
- return false;
- }
- if (this.checksum != other.checksum) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for ICMP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<ICMP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, ICMP_HEADER_LENGTH);
-
- ICMP icmp = new ICMP();
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- icmp.icmpType = bb.get();
- icmp.icmpCode = bb.get();
- icmp.checksum = bb.getShort();
-
- icmp.payload = Data.deserializer()
- .deserialize(data, bb.position(), bb.limit()
- - bb.position());
- icmp.payload.setParent(icmp);
- return icmp;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP6.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
deleted file mode 100644
index c8981302..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.onlab.packet.ipv6.IExtensionHeader;
-import org.onlab.packet.ndp.NeighborAdvertisement;
-import org.onlab.packet.ndp.NeighborSolicitation;
-import org.onlab.packet.ndp.Redirect;
-import org.onlab.packet.ndp.RouterAdvertisement;
-import org.onlab.packet.ndp.RouterSolicitation;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 packet format. (RFC 4443)
- */
-public class ICMP6 extends BasePacket {
- public static final byte HEADER_LENGTH = 4; // bytes
-
- // Type
- /** Destination Unreachable. */
- public static final byte DEST_UNREACH = (byte) 0x01;
- /** Packet Too Big. */
- public static final byte PKT_TOO_BIG = (byte) 0x02;
- /** Time Exceeded. */
- public static final byte TIME_EXCEED = (byte) 0x03;
- /** Parameter Problem. */
- public static final byte PARAM_ERR = (byte) 0x04;
- /** Echo Request. */
- public static final byte ECHO_REQUEST = (byte) 0x80;
- /** Echo Reply. */
- public static final byte ECHO_REPLY = (byte) 0x81;
- /** Multicast Listener Query. */
- public static final byte MCAST_QUERY = (byte) 0x82;
- /** Multicast Listener Report. */
- public static final byte MCAST_REPORT = (byte) 0x83;
- /** Multicast Listener Done. */
- public static final byte MCAST_DONE = (byte) 0x84;
- /** Router Solicitation. */
- public static final byte ROUTER_SOLICITATION = (byte) 0x85;
- /** Router Advertisement. */
- public static final byte ROUTER_ADVERTISEMENT = (byte) 0x86;
- /** Neighbor Solicitation. */
- public static final byte NEIGHBOR_SOLICITATION = (byte) 0x87;
- /** Neighbor Advertisement. */
- public static final byte NEIGHBOR_ADVERTISEMENT = (byte) 0x88;
- /** Redirect Message. */
- public static final byte REDIRECT = (byte) 0x89;
-
- // Code for DEST_UNREACH
- /** No route to destination. */
- public static final byte NO_ROUTE = (byte) 0x00;
- /** Communication with destination administratively prohibited. */
- public static final byte COMM_PROHIBIT = (byte) 0x01;
- /** Beyond scope of source address. */
- public static final byte BEYOND_SCOPE = (byte) 0x02;
- /** Address unreachable. */
- public static final byte ADDR_UNREACH = (byte) 0x03;
- /** Port unreachable. */
- public static final byte PORT_UNREACH = (byte) 0x04;
- /** Source address failed ingress/egress policy. */
- public static final byte FAIL_POLICY = (byte) 0x05;
- /** Reject route to destination. */
- public static final byte REJECT_ROUTE = (byte) 0x06;
- /** Error in Source Routing Header. */
- public static final byte SRC_ROUTING_HEADER_ERR = (byte) 0x07;
-
- // Code for TIME_EXCEED
- /** Hop limit exceeded in transit. */
- public static final byte HOP_LIMIT_EXCEED = (byte) 0x00;
- /** Fragment reassembly time exceeded. */
- public static final byte DEFRAG_TIME_EXCEED = (byte) 0x01;
-
- // Code for PARAM_ERR
- /** Erroneous header field encountered. */
- public static final byte HDR_FIELD_ERR = (byte) 0x00;
- /** Unrecognized Next Header type encountered. */
- public static final byte NEXT_HEADER_ERR = (byte) 0x01;
- /** Unrecognized IPv6 option encountered. */
- public static final byte IPV6_OPT_ERR = (byte) 0x01;
-
- public static final Map<Byte, Deserializer<? extends IPacket>> TYPE_DESERIALIZER_MAP =
- new HashMap<>();
-
- static {
- ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.ROUTER_SOLICITATION, RouterSolicitation.deserializer());
- ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.ROUTER_ADVERTISEMENT, RouterAdvertisement.deserializer());
- ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.NEIGHBOR_SOLICITATION, NeighborSolicitation.deserializer());
- ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.deserializer());
- ICMP6.TYPE_DESERIALIZER_MAP.put(ICMP6.REDIRECT, Redirect.deserializer());
- }
-
- protected byte icmpType;
- protected byte icmpCode;
- protected short checksum;
-
- private static final byte[] ZERO_ADDRESS = new byte[Ip6Address.BYTE_LENGTH];
-
- /**
- * Gets ICMP6 type.
- *
- * @return the ICMP6 type
- */
- public byte getIcmpType() {
- return this.icmpType;
- }
-
- /**
- * Sets ICMP6 type.
- *
- * @param icmpType the ICMP type to set
- * @return this
- */
- public ICMP6 setIcmpType(final byte icmpType) {
- this.icmpType = icmpType;
- return this;
- }
-
- /**
- * Gets ICMP6 code.
- *
- * @return the ICMP6 code
- */
- public byte getIcmpCode() {
- return this.icmpCode;
- }
-
- /**
- * Sets ICMP6 code.
- *
- * @param icmpCode the ICMP6 code to set
- * @return this
- */
- public ICMP6 setIcmpCode(final byte icmpCode) {
- this.icmpCode = icmpCode;
- return this;
- }
-
- /**
- * Gets checksum.
- *
- * @return the checksum
- */
- public short getChecksum() {
- return this.checksum;
- }
-
- /**
- * Sets checksum.
- *
- * @param checksum the checksum to set
- * @return this
- */
- public ICMP6 setChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + payloadLength];
- final ByteBuffer bbData = ByteBuffer.wrap(data);
-
- // Creating ByteBuffer for checksum calculation
- final byte[] checksumData =
- new byte[IPv6.FIXED_HEADER_LENGTH + HEADER_LENGTH + payloadLength];
- final ByteBuffer bbChecksum = ByteBuffer.wrap(checksumData);
-
- //
- // Creating IPv6 Pseudo Header for checksum calculation according
- // to RFC 4443 and RFC 2460
- //
- IPv6 ipv6Parent = null;
- for (IPacket p = this.parent; p != null; p = p.getParent()) {
- if (p instanceof IPv6) {
- ipv6Parent = (IPv6) p;
- break;
- }
- }
- if (ipv6Parent != null) {
- bbChecksum.put(ipv6Parent.getSourceAddress());
- bbChecksum.put(ipv6Parent.getDestinationAddress());
- } else {
- // NOTE: IPv6 source and destination addresses unknown. Use zeroes.
- bbChecksum.put(ZERO_ADDRESS);
- bbChecksum.put(ZERO_ADDRESS);
- }
- bbChecksum.putInt(HEADER_LENGTH + payloadLength);
- bbChecksum.put((byte) 0);
- bbChecksum.put((byte) 0);
- bbChecksum.put((byte) 0);
- bbChecksum.put(IPv6.PROTOCOL_ICMP6);
- bbChecksum.put(this.icmpType);
- bbChecksum.put(this.icmpCode);
- bbChecksum.put((byte) 0);
- bbChecksum.put((byte) 0);
-
- bbData.put(this.icmpType);
- bbData.put(this.icmpCode);
- bbData.putShort(this.checksum);
- if (payloadData != null) {
- bbData.put(payloadData);
- bbChecksum.put(payloadData);
- }
-
- if (this.parent != null) {
- if (this.parent instanceof IPv6) {
- ((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
- } else if (this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
- }
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bbData.rewind();
- bbChecksum.rewind();
- int accumulation = 0;
-
- for (int i = 0; i < checksumData.length / 2; ++i) {
- accumulation += 0xffff & bbChecksum.getShort();
- }
- // pad to an even number of shorts
- if (checksumData.length % 2 > 0) {
- accumulation += (bbChecksum.get() & 0xff) << 8;
- }
-
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bbData.putShort(2, this.checksum);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.icmpType = bb.get();
- this.icmpCode = bb.get();
- this.checksum = bb.getShort();
-
- Deserializer<? extends IPacket> deserializer;
- if (ICMP6.TYPE_DESERIALIZER_MAP.containsKey(icmpType)) {
- deserializer = TYPE_DESERIALIZER_MAP.get(icmpType);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.icmpType;
- result = prime * result + this.icmpCode;
- result = prime * result + this.checksum;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof ICMP6)) {
- return false;
- }
- final ICMP6 other = (ICMP6) obj;
- if (this.icmpType != other.icmpType) {
- return false;
- }
- if (this.icmpCode != other.icmpCode) {
- return false;
- }
- if (this.checksum != other.checksum) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for ICMPv6 packets.
- *
- * @return deserializer function
- */
- public static Deserializer<ICMP6> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- ICMP6 icmp6 = new ICMP6();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- icmp6.icmpType = bb.get();
- icmp6.icmpCode = bb.get();
- icmp6.checksum = bb.getShort();
-
- Deserializer<? extends IPacket> deserializer;
- if (ICMP6.TYPE_DESERIALIZER_MAP.containsKey(icmp6.icmpType)) {
- deserializer = TYPE_DESERIALIZER_MAP.get(icmp6.icmpType);
- } else {
- deserializer = Data.deserializer();
- }
- icmp6.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- icmp6.payload.setParent(icmp6);
-
- return icmp6;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMP.java
deleted file mode 100644
index 254f1325..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMP.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.slf4j.Logger;
-
-import static org.slf4j.LoggerFactory.getLogger;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-
-/**
- * Implements IGMP control packet format.
- */
-public class IGMP extends BasePacket {
- private final Logger log = getLogger(getClass());
-
- public static final byte TYPE_IGMPV3_MEMBERSHIP_QUERY = 0x11;
- public static final byte TYPE_IGMPV1_MEMBERSHIP_REPORT = 0x12;
- public static final byte TYPE_IGMPV2_MEMBERSHIP_REPORT = 0x16;
- public static final byte TYPE_IGMPV2_LEAVE_GROUP = 0x17;
- public static final byte TYPE_IGMPV3_MEMBERSHIP_REPORT = 0x22;
- public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP = new HashMap<>();
-
- public static final int MINIMUM_HEADER_LEN = 12;
-
- List<IGMPGroup> groups = new ArrayList<>();
-
- // Fields contained in the IGMP header
- private byte igmpType;
- private byte resField = 0;
- private short checksum = 0;
-
- private byte[] unsupportTypeData;
-
- public IGMP() {
- }
-
- /**
- * Get the IGMP message type.
- *
- * @return the IGMP message type
- */
- public byte getIgmpType() {
- return igmpType;
- }
-
- /**
- * Set the IGMP message type.
- *
- * @param msgType IGMP message type
- */
- public void setIgmpType(byte msgType) {
- igmpType = msgType;
- }
-
- /**
- * Get the checksum of this message.
- *
- * @return the checksum
- */
- public short getChecksum() {
- return checksum;
- }
-
- /**
- * get the Max Resp Code.
- *
- * @return The Maximum Time allowed before before sending a responding report.
- */
- public byte getMaxRespField() {
- return resField;
- }
-
- /**
- * Set the Max Resp Code.
- *
- * @param respCode the Maximum Response Code.
- */
- public void setMaxRespCode(byte respCode) {
- if (igmpType != IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY) {
- log.debug("Requesting the max response code for an incorrect field: ");
- }
- this.resField = respCode;
- }
-
- /**
- * Get the list of IGMPGroups. The group objects will be either IGMPQuery or IGMPMembership
- * depending on the IGMP message type. For IGMP Query, the groups list should only be
- * one group.
- *
- * @return The list of IGMP groups.
- */
- public List<IGMPGroup> getGroups() {
- return groups;
- }
-
- /**
- * Add a multicast group to this IGMP message.
- *
- * @param group the IGMPGroup will be IGMPQuery or IGMPMembership depending on the message type.
- * @return true if group was valid and added, false otherwise.
- */
- public boolean addGroup(IGMPGroup group) {
- checkNotNull(group);
- switch (this.igmpType) {
- case TYPE_IGMPV3_MEMBERSHIP_QUERY:
- if (group instanceof IGMPMembership) {
- return false;
- }
-
- if (group.sources.size() > 1) {
- return false;
- }
- break;
-
- case TYPE_IGMPV3_MEMBERSHIP_REPORT:
- if (group instanceof IGMPMembership) {
- return false;
- }
- break;
-
- default:
- log.debug("Warning no IGMP message type has been set");
- }
-
- this.groups.add(group);
- return true;
- }
-
- /**
- * Serialize this IGMP packet. This will take care
- * of serializing IGMPv3 Queries and IGMPv3 Membership
- * Reports.
- *
- * @return the serialized IGMP message
- */
- @Override
- public byte[] serialize() {
- byte [] data = new byte[8915];
-
- ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.getIgmpType());
-
- // reserved or max resp code depending on type.
- bb.put(this.resField);
-
- // Must calculate checksum
- bb.putShort((short) 0);
-
- switch (this.igmpType) {
-
- case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
- // reserved
- bb.putShort((short) 0);
- // Number of groups
- bb.putShort((short) groups.size());
- // Fall through
-
- case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:
-
- for (IGMPGroup grp : groups) {
- grp.serialize(bb);
- }
- break;
-
- default:
- bb.put(this.unsupportTypeData);
- break;
- }
-
- int size = bb.position();
- bb.position(0);
- byte [] rdata = new byte[size];
- bb.get(rdata, 0, size);
- return rdata;
- }
-
- /**
- * Deserialize an IGMP message.
- *
- * @param data bytes to deserialize
- * @param offset offset to start deserializing from
- * @param length length of the data to deserialize
- * @return populated IGMP object
- */
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
-
- IGMP igmp = new IGMP();
- try {
- igmp = IGMP.deserializer().deserialize(data, offset, length);
- } catch (DeserializationException e) {
- log.error(e.getStackTrace().toString());
- return this;
- }
- this.igmpType = igmp.igmpType;
- this.resField = igmp.resField;
- this.checksum = igmp.checksum;
- this.groups = igmp.groups;
- return this;
- }
-
- /**
- * Deserializer function for IPv4 packets.
- *
- * @return deserializer function
- */
- public static Deserializer<IGMP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, MINIMUM_HEADER_LEN);
-
- IGMP igmp = new IGMP();
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- igmp.igmpType = bb.get();
- igmp.resField = bb.get();
- igmp.checksum = bb.getShort();
- int len = MINIMUM_HEADER_LEN;
- String msg;
-
- switch (igmp.igmpType) {
-
- case TYPE_IGMPV3_MEMBERSHIP_QUERY:
- IGMPQuery qgroup = new IGMPQuery();
- qgroup.deserialize(bb);
- igmp.groups.add(qgroup);
- break;
-
- case TYPE_IGMPV3_MEMBERSHIP_REPORT:
- bb.getShort(); // Ignore resvd
- int ngrps = bb.getShort();
-
- for (; ngrps > 0; ngrps--) {
- IGMPMembership mgroup = new IGMPMembership();
- mgroup.deserialize(bb);
- igmp.groups.add(mgroup);
- }
- break;
-
- /*
- * NOTE: according to the IGMPv3 spec. These previous IGMP type fields
- * must be supported. At this time we are going to <b>assume</b> we run
- * in a modern network where all devices are IGMPv3 capable.
- */
- case TYPE_IGMPV1_MEMBERSHIP_REPORT:
- case TYPE_IGMPV2_MEMBERSHIP_REPORT:
- case TYPE_IGMPV2_LEAVE_GROUP:
- igmp.unsupportTypeData = bb.array(); // Is this the entire array?
- msg = "IGMP message type: " + igmp.igmpType + " is not supported";
- igmp.log.debug(msg);
- break;
-
- default:
- msg = "IGMP message type: " + igmp.igmpType + " is not recognized";
- igmp.unsupportTypeData = bb.array();
- igmp.log.debug(msg);
- break;
- }
- return igmp;
- };
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof IGMP)) {
- return false;
- }
- final IGMP other = (IGMP) obj;
- if (this.igmpType != other.igmpType) {
- return false;
- }
- if (this.resField != other.resField) {
- return false;
- }
- if (this.checksum != other.checksum) {
- return false;
- }
- if (this.groups.size() != other.groups.size()) {
- return false;
- }
- // TODO: equals should be true regardless of order.
- if (!groups.equals(other.groups)) {
- return false;
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.igmpType;
- result = prime * result + this.groups.size();
- result = prime * result + this.resField;
- result = prime * result + this.checksum;
- result = prime * result + this.groups.hashCode();
- return result;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPGroup.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPGroup.java
deleted file mode 100644
index 70ff5563..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPGroup.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class to represent Groups for membership query and reports.
- */
-public abstract class IGMPGroup {
-
- protected int auxInfo;
- protected IpAddress gaddr;
- protected List<IpAddress> sources = new ArrayList<>();
-
- public IGMPGroup() {
- }
-
- /**
- * Initialize this object with a multicast group address and additional info.
- *
- * @param gaddr: the multicast group address for this message type.
- * @param auxInfo: additional info potentially used by IGMPQuery
- */
- public IGMPGroup(IpAddress gaddr, int auxInfo) {
- this.gaddr = gaddr;
- this.auxInfo = auxInfo;
- }
-
- /**
- * Get the multicast group address.
- *
- * @return the group address
- */
- public IpAddress getGaddr() {
- return this.gaddr;
- }
-
- /**
- * Get the auxillary info.
- *
- * @return the auxillary info
- */
- public int getAuxInfo() {
- return this.auxInfo;
- }
-
- /**
- * Add a unicast source address to this message.
- *
- * @param saddr IPv4 unicast source address
- */
- public void addSource(IpAddress saddr) {
- sources.add(saddr);
- }
-
- /**
- * Return the list of source addresses.
- *
- * @return list of source addresses
- */
- public List<IpAddress> getSources() {
- return sources;
- }
-
- /**
- * Deserialize an IGMPQuery or IGMPMembership message.
- *
- * @param bb the ByteBuffer wrapping the serialized message. The position of the
- * ByteBuffer should be pointing at the head of either message type.
- * @return An object populated with the respective IGMPGroup subclass
- * @throws DeserializationException in case deserialization goes wrong
- */
- public abstract IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException;
-
- /**
- * Serialize the IGMPGroup subclass.
- *
- * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
- * @return The serialized message
- */
- public abstract byte[] serialize(ByteBuffer bb);
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPMembership.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPMembership.java
deleted file mode 100644
index 495e283c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPMembership.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import static org.onlab.packet.PacketUtils.checkBufferLength;
-
-public class IGMPMembership extends IGMPGroup {
-
- public static final byte MODE_IS_INCLUDE = 0x1;
- public static final byte MODE_IS_EXCLUDE = 0x2;
- public static final byte CHANGE_TO_INCLUDE_MODE = 0x3;
- public static final byte CHANGE_TO_EXCLUDE_MODE = 0x4;
- public static final byte ALLOW_NEW_SOURCES = 0x5;
- public static final byte BLOCK_OLD_SOURCES = 0x6;
-
- private final int minGroupRecordLen = Ip4Address.BYTE_LENGTH + 4;
-
- protected byte recordType;
- protected byte auxDataLength = 0;
- protected byte[] auxData;
-
- /**
- * Constructor initialized with a multicast group address.
- *
- * @param gaddr A multicast group address.
- */
- public IGMPMembership(Ip4Address gaddr) {
- super(gaddr, 0);
- }
-
- /**
- * Default constructor.
- */
- public IGMPMembership() {
- super();
- }
-
- /**
- * Serialize this Membership Report.
- *
- * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
- * @return serialized IGMP message.
- */
- @Override
- public byte[] serialize(ByteBuffer bb) {
-
- bb.put(recordType);
- bb.put(auxDataLength); // reserved
- bb.putShort((short) sources.size());
- bb.put(gaddr.toOctets());
- for (IpAddress ipaddr : sources) {
- bb.put(ipaddr.toOctets());
- }
-
- if (auxDataLength > 0) {
- bb.put(auxData);
- }
-
- return bb.array();
- }
-
- /**
- * Deserialize the IGMP Membership report packet.
- *
- * @param bb the ByteBuffer wrapping the serialized message. The position of the
- * ByteBuffer should be pointing at the head of either message type.
- * @return IGMP Group
- * @throws DeserializationException if deserialization fails
- */
- public IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException {
-
- // Make sure there is enough buffer to read the header,
- // including the number of sources
- checkBufferLength(bb.remaining(), 0, minGroupRecordLen);
- recordType = bb.get();
- auxDataLength = bb.get();
- int nsrcs = bb.getShort();
-
- gaddr = Ip4Address.valueOf(bb.getInt());
-
- // Make sure we have enough buffer to hold all of these sources
- checkBufferLength(bb.remaining(), 0, Ip4Address.BYTE_LENGTH * nsrcs);
- for (; nsrcs > 0; nsrcs--) {
- Ip4Address src = Ip4Address.valueOf(bb.getInt());
- this.sources.add(src);
- }
-
- if (auxDataLength > 0) {
- auxData = new byte[auxDataLength];
- bb.get(auxData, 0, auxDataLength);
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals()
- */
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof IGMPMembership)) {
- return false;
- }
- IGMPMembership other = (IGMPMembership) obj;
-
- if (!this.gaddr.equals(other.gaddr)) {
- return false;
- }
- if (this.recordType != other.recordType) {
- return false;
- }
- if (this.auxDataLength != other.auxDataLength) {
- return false;
- }
- if (this.sources.size() != other.sources.size()) {
- return false;
- }
- // TODO: make these tolerant of order
- if (!this.sources.equals(other.sources)) {
- return false;
- }
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.gaddr.hashCode();
- result = prime * result + this.recordType;
- result = prime * result + this.auxDataLength;
- result = prime * result + this.sources.hashCode();
- return result;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPQuery.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPQuery.java
deleted file mode 100644
index bb53eba5..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IGMPQuery.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-public class IGMPQuery extends IGMPGroup {
-
- // Bits and bytes after the group address
- private byte resv = 0;
- private boolean sbit = false;
- private byte qrv = 2;
- private byte qqic = 0x7d;
-
- /**
- * Create IGMP Query message.
- *
- * @param gaddr initiaze with a group address.
- * @param auxInfo auxillary info.
- */
- public IGMPQuery(IpAddress gaddr, int auxInfo) {
- super(gaddr, auxInfo);
- }
-
- /**
- * Create IGMP Query message.
- */
- public IGMPQuery() {
- super();
- }
-
- /**
- * Is the S flag set? Telling adjacent routers to suppress normal timer updates.
- *
- * @return true if the flag is set, false otherwise
- */
- public boolean isSbit() {
- return sbit;
- }
-
- /**
- * Set the S flag. Default is false.
- *
- * @param sbit true or false
- */
- public void setSbit(boolean sbit) {
- this.sbit = sbit;
- }
-
- /**
- * Get the Querier Robustness Variable.
- *
- * @return querier robustness value
- */
- public byte getQrv() {
- return qrv;
- }
-
- /**
- * Set the Querier Robustness Variable. Default is 2.
- *
- * @param qrv new querier robustness value
- */
- public void setQrv(byte qrv) {
- this.qrv = qrv;
- }
-
- /**
- * Get the reserved field. Should be zero, but ignored regardless of it's value.
- *
- * @return the reserved field.
- */
- public byte getResv() {
- return resv;
- }
-
- /**
- * Set the reserved field. Should be 0 and ignored by receivers.
- *
- * @param resv the reserved field.
- */
- public void setResv(byte resv) {
- this.resv = resv;
- }
-
- /**
- * Serialize this IGMPQuery.
- *
- * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
- * @return the serialized message
- */
- @Override
- public byte[] serialize(ByteBuffer bb) {
-
- bb.put(gaddr.toOctets());
- byte fld = (byte) (0x7 & qrv);
- bb.put(fld);
- bb.put(qqic);
- bb.putShort((short) sources.size());
- for (IpAddress ipaddr : sources) {
- bb.put(ipaddr.toOctets());
- }
- return bb.array();
- }
-
- /**
- * Deserialize the IGMP Query group structure.
- *
- * @param bb ByteBuffer pointing at the IGMP Query group address
- * @return the IGMP Group object
- */
- public IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException {
-
- gaddr = Ip4Address.valueOf(bb.getInt());
- byte fld = bb.get();
-
- // Just ignore the reserved bits
- resv = 0;
- this.sbit = ((fld & 0x8) == 0x8);
- qrv = (byte) (fld & 0x7);
-
- // QQIC field
- qqic = bb.get();
-
- // Get the number of sources.
- short nsrcs = bb.getShort();
-
- // Do a sanity check on the amount of space we have in our buffer.
- int lengthNeeded = (Ip4Address.BYTE_LENGTH * nsrcs);
- PacketUtils.checkHeaderLength(bb.remaining(), lengthNeeded);
-
- for (; nsrcs > 0; nsrcs--) {
- Ip4Address ipaddr = Ip4Address.valueOf(bb.getInt());
- this.sources.add(ipaddr);
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals()
- */
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof IGMPQuery)) {
- return false;
- }
- IGMPQuery other = (IGMPQuery) obj;
-
- if (this.sbit != other.sbit) {
- return false;
- }
- if (this.qrv != other.qrv) {
- return false;
- }
- if (this.qqic != other.qqic) {
- return false;
- }
- if (this.sources.size() != other.sources.size()) {
- return false;
- }
-
- // TODO: make these tolerant of order
- if (!this.sources.equals(other.sources)) {
- return false;
- }
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.gaddr.hashCode();
- result = prime * result + this.qqic;
- result = prime * result + this.qrv;
- result = prime * result + this.sources.hashCode();
- return result;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPacket.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPacket.java
deleted file mode 100644
index 64e6ac36..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPacket.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-/**
- *
- */
-public interface IPacket {
- /**
- *
- * @return the payload
- */
- IPacket getPayload();
-
- /**
- *
- * @param packet new payload
- * @return self
- */
- IPacket setPayload(IPacket packet);
-
- /**
- *
- * @return parent packet
- */
- IPacket getParent();
-
- /**
- *
- * @param packet new parent
- * @return self
- */
- IPacket setParent(IPacket packet);
-
- /**
- * Reset any checksums as needed, and call resetChecksum on all parents.
- */
- void resetChecksum();
-
- /**
- * Sets all payloads parent packet if applicable, then serializes this
- * packet and all payloads.
- *
- * @return a byte[] containing this packet and payloads
- */
- byte[] serialize();
-
- /**
- * Deserializes this packet layer and all possible payloads.
- *
- * NOTE: This method has been deprecated and will be removed in a future
- * release. It is now recommended to use the Deserializer function provided
- * by the deserialize() method on each packet to deserialize them. The
- * Deserializer functions are robust to malformed input.
- *
- * @param data bytes to deserialize
- * @param offset
- * offset to start deserializing from
- * @param length
- * length of the data to deserialize
- * @return the deserialized data
- * @deprecated in Cardinal Release
- */
- @Deprecated
- IPacket deserialize(byte[] data, int offset, int length);
-
- /**
- * Clone this packet and its payload packet but not its parent.
- *
- * @return the clone
- */
- Object clone();
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java
deleted file mode 100644
index a5c5f4f1..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv4.java
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- *
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- *
- */
-public class IPv4 extends BasePacket {
- public static final byte PROTOCOL_ICMP = 0x1;
- public static final byte PROTOCOL_IGMP = 0x2;
- public static final byte PROTOCOL_TCP = 0x6;
- public static final byte PROTOCOL_UDP = 0x11;
- public static final byte PROTOCOL_PIM = 0x67;
- public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
- new HashMap<>();
-
- static {
- IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_ICMP, ICMP.deserializer());
- IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_IGMP, IGMP.deserializer());
- IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_TCP, TCP.deserializer());
- IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_UDP, UDP.deserializer());
- IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_PIM, PIM.deserializer());
- }
-
- private static final byte DSCP_MASK = 0x3f;
- private static final byte DSCP_OFFSET = 2;
- private static final byte ECN_MASK = 0x3;
-
- private static final short HEADER_LENGTH = 20;
-
- protected byte version;
- protected byte headerLength;
- protected byte diffServ;
- protected short totalLength;
- protected short identification;
- protected byte flags;
- protected short fragmentOffset;
- protected byte ttl;
- protected byte protocol;
- protected short checksum;
- protected int sourceAddress;
- protected int destinationAddress;
- protected byte[] options;
-
- protected boolean isTruncated;
-
- /**
- * Default constructor that sets the version to 4.
- */
- public IPv4() {
- super();
- this.version = 4;
- this.isTruncated = false;
- }
-
- /**
- * @return the version
- */
- public byte getVersion() {
- return this.version;
- }
-
- /**
- * @param version
- * the version to set
- * @return this
- */
- public IPv4 setVersion(final byte version) {
- this.version = version;
- return this;
- }
-
- /**
- * @return the headerLength
- */
- public byte getHeaderLength() {
- return this.headerLength;
- }
-
- /**
- * Gets the DSCP value (6 bits).
- *
- * @return the DSCP value (6 bits)
- */
- public byte getDscp() {
- return (byte) ((this.diffServ >>> DSCP_OFFSET) & DSCP_MASK);
- }
-
- /**
- * Sets the DSCP value (6 bits).
- *
- * @param dscp the DSCP value (6 bits)
- * @return this
- */
- public IPv4 setDscp(byte dscp) {
- this.diffServ &= ~(DSCP_MASK << DSCP_OFFSET);
- this.diffServ |= (dscp & DSCP_MASK) << DSCP_OFFSET;
- return this;
- }
-
- /**
- * Gets the ECN value (2 bits).
- *
- * @return the ECN value (2 bits)
- */
- public byte getEcn() {
- return (byte) (this.diffServ & ECN_MASK);
- }
-
- /**
- * Sets the ECN value (2 bits).
- *
- * @param ecn the ECN value (2 bits)
- * @return this
- */
- public IPv4 setEcn(byte ecn) {
- this.diffServ &= ~ECN_MASK;
- this.diffServ |= (ecn & ECN_MASK);
- return this;
- }
-
- /**
- * Gets the DiffServ octet (including the DSCP and ECN bits).
- *
- * @return the diffServ octet (including the DSCP and ECN bits)
- */
- public byte getDiffServ() {
- return this.diffServ;
- }
-
- /**
- * Sets the DiffServ octet (including the DSCP and ECN bits).
- *
- * @param diffServ the diffServ octet to set (including the DSCP and ECN
- * bits)
- * @return this
- */
- public IPv4 setDiffServ(final byte diffServ) {
- this.diffServ = diffServ;
- return this;
- }
-
- /**
- * @return the totalLength
- */
- public short getTotalLength() {
- return this.totalLength;
- }
-
- /**
- * @return the identification
- */
- public short getIdentification() {
- return this.identification;
- }
-
- public boolean isTruncated() {
- return this.isTruncated;
- }
-
- public void setTruncated(final boolean isTruncated) {
- this.isTruncated = isTruncated;
- }
-
- /**
- * @param identification
- * the identification to set
- * @return this
- */
- public IPv4 setIdentification(final short identification) {
- this.identification = identification;
- return this;
- }
-
- /**
- * @return the flags
- */
- public byte getFlags() {
- return this.flags;
- }
-
- /**
- * @param flags
- * the flags to set
- * @return this
-s */
- public IPv4 setFlags(final byte flags) {
- this.flags = flags;
- return this;
- }
-
- /**
- * @return the fragmentOffset
- */
- public short getFragmentOffset() {
- return this.fragmentOffset;
- }
-
- /**
- * @param fragmentOffset
- * the fragmentOffset to set
- * @return this
- */
- public IPv4 setFragmentOffset(final short fragmentOffset) {
- this.fragmentOffset = fragmentOffset;
- return this;
- }
-
- /**
- * @return the ttl
- */
- public byte getTtl() {
- return this.ttl;
- }
-
- /**
- * @param ttl
- * the ttl to set
- * @return this
- */
- public IPv4 setTtl(final byte ttl) {
- this.ttl = ttl;
- return this;
- }
-
- /**
- * @return the protocol
- */
- public byte getProtocol() {
- return this.protocol;
- }
-
- /**
- * @param protocol
- * the protocol to set
- * @return this
- */
- public IPv4 setProtocol(final byte protocol) {
- this.protocol = protocol;
- return this;
- }
-
- /**
- * @return the checksum
- */
- public short getChecksum() {
- return this.checksum;
- }
-
- /**
- * @param checksum
- * the checksum to set
- * @return this
- */
- public IPv4 setChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
- @Override
- public void resetChecksum() {
- this.checksum = 0;
- super.resetChecksum();
- }
-
- /**
- * @return the sourceAddress
- */
- public int getSourceAddress() {
- return this.sourceAddress;
- }
-
- /**
- * @param sourceAddress
- * the sourceAddress to set
- * @return this
- */
- public IPv4 setSourceAddress(final int sourceAddress) {
- this.sourceAddress = sourceAddress;
- return this;
- }
-
- /**
- * @param sourceAddress
- * the sourceAddress to set
- * @return this
- */
- public IPv4 setSourceAddress(final String sourceAddress) {
- this.sourceAddress = IPv4.toIPv4Address(sourceAddress);
- return this;
- }
-
- /**
- * @return the destinationAddress
- */
- public int getDestinationAddress() {
- return this.destinationAddress;
- }
-
- /**
- * @param destinationAddress
- * the destinationAddress to set
- * @return this
- */
- public IPv4 setDestinationAddress(final int destinationAddress) {
- this.destinationAddress = destinationAddress;
- return this;
- }
-
- /**
- * @param destinationAddress
- * the destinationAddress to set
- * @return this
- */
- public IPv4 setDestinationAddress(final String destinationAddress) {
- this.destinationAddress = IPv4.toIPv4Address(destinationAddress);
- return this;
- }
-
- /**
- * @return the options
- */
- public byte[] getOptions() {
- return this.options;
- }
-
- /**
- * @param options
- * the options to set
- * @return this
- */
- public IPv4 setOptions(final byte[] options) {
- if (options != null && options.length % 4 > 0) {
- throw new IllegalArgumentException(
- "Options length must be a multiple of 4");
- }
- this.options = options;
- return this;
- }
-
- /**
- * Serializes the packet. Will compute and set the following fields if they
- * are set to specific values at the time serialize is called: -checksum : 0
- * -headerLength : 0 -totalLength : 0
- */
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int optionsLength = 0;
- if (this.options != null) {
- optionsLength = this.options.length / 4;
- }
- this.headerLength = (byte) (5 + optionsLength);
-
- this.totalLength = (short) (this.headerLength * 4 + (payloadData == null ? 0
- : payloadData.length));
-
- final byte[] data = new byte[this.totalLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put((byte) ((this.version & 0xf) << 4 | this.headerLength & 0xf));
- bb.put(this.diffServ);
- bb.putShort(this.totalLength);
- bb.putShort(this.identification);
- bb.putShort((short) ((this.flags & 0x7) << 13 | this.fragmentOffset & 0x1fff));
- bb.put(this.ttl);
- bb.put(this.protocol);
- bb.putShort(this.checksum);
- bb.putInt(this.sourceAddress);
- bb.putInt(this.destinationAddress);
- if (this.options != null) {
- bb.put(this.options);
- }
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bb.rewind();
- int accumulation = 0;
- for (int i = 0; i < this.headerLength * 2; ++i) {
- accumulation += 0xffff & bb.getShort();
- }
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bb.putShort(10, this.checksum);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- short sscratch;
-
- this.version = bb.get();
- this.headerLength = (byte) (this.version & 0xf);
- this.version = (byte) (this.version >> 4 & 0xf);
- this.diffServ = bb.get();
- this.totalLength = bb.getShort();
- this.identification = bb.getShort();
- sscratch = bb.getShort();
- this.flags = (byte) (sscratch >> 13 & 0x7);
- this.fragmentOffset = (short) (sscratch & 0x1fff);
- this.ttl = bb.get();
- this.protocol = bb.get();
- this.checksum = bb.getShort();
- this.sourceAddress = bb.getInt();
- this.destinationAddress = bb.getInt();
-
- if (this.headerLength > 5) {
- final int optionsLength = (this.headerLength - 5) * 4;
- this.options = new byte[optionsLength];
- bb.get(this.options);
- }
-
- if (this.totalLength != length) {
- this.isTruncated = true;
- } else {
- this.isTruncated = false;
- }
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv4.PROTOCOL_DESERIALIZER_MAP.containsKey(this.protocol)) {
- deserializer = IPv4.PROTOCOL_DESERIALIZER_MAP.get(this.protocol);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /**
- * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
- * returns the corresponding 32 bit integer.
- *
- * @param ipAddress ip address in string form
- * @return int ip address value
- */
- public static int toIPv4Address(final String ipAddress) {
- if (ipAddress == null) {
- throw new IllegalArgumentException("Specified IPv4 address must"
- + "contain 4 sets of numerical digits separated by periods");
- }
- final String[] octets = ipAddress.split("\\.");
- if (octets.length != 4) {
- throw new IllegalArgumentException("Specified IPv4 address must"
- + "contain 4 sets of numerical digits separated by periods");
- }
-
- int result = 0;
- for (int i = 0; i < 4; ++i) {
- result |= Integer.parseInt(octets[i]) << (3 - i) * 8;
- }
- return result;
- }
-
- /**
- * Accepts an IPv4 address in a byte array and returns the corresponding
- * 32-bit integer value.
- *
- * @param ipAddress ip address in byte form
- * @return int ip address value
- */
- public static int toIPv4Address(final byte[] ipAddress) {
- int ip = 0;
- for (int i = 0; i < 4; i++) {
- final int t = (ipAddress[i] & 0xff) << (3 - i) * 8;
- ip |= t;
- }
- return ip;
- }
-
- /**
- * Accepts an IPv4 address and returns of string of the form xxx.xxx.xxx.xxx,
- * e.g., 192.168.0.1.
- *
- * @param ipAddress ip address in form
- * @return string form of ip address
- */
- public static String fromIPv4Address(final int ipAddress) {
- final StringBuffer sb = new StringBuffer();
- int result = 0;
- for (int i = 0; i < 4; ++i) {
- result = ipAddress >> (3 - i) * 8 & 0xff;
- sb.append(result);
- if (i != 3) {
- sb.append(".");
- }
- }
- return sb.toString();
- }
-
- /**
- * Accepts a collection of IPv4 addresses as integers and returns a single
- * String useful in toString method's containing collections of IP
- * addresses.
- *
- * @param ipAddresses
- * collection
- * @return ip addresses in comma-separated string form
- */
- public static String fromIPv4AddressCollection(
- final Collection<Integer> ipAddresses) {
- if (ipAddresses == null) {
- return "null";
- }
- final StringBuffer sb = new StringBuffer();
- sb.append("[");
- for (final Integer ip : ipAddresses) {
- sb.append(IPv4.fromIPv4Address(ip));
- sb.append(",");
- }
- sb.replace(sb.length() - 1, sb.length(), "]");
- return sb.toString();
- }
-
- /**
- * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
- * returns the corresponding byte array.
- *
- * @param ipAddress
- * The IP address in the form xx.xxx.xxx.xxx.
- * @return The IP address separated into bytes
- */
- public static byte[] toIPv4AddressBytes(final String ipAddress) {
- final String[] octets = ipAddress.split("\\.");
- if (octets.length != 4) {
- throw new IllegalArgumentException("Specified IPv4 address must"
- + "contain 4 sets of numerical digits separated by periods");
- }
-
- final byte[] result = new byte[4];
- for (int i = 0; i < 4; ++i) {
- result[i] = Integer.valueOf(octets[i]).byteValue();
- }
- return result;
- }
-
- /**
- * Accepts an IPv4 address in the form of an integer and returns the
- * corresponding byte array.
- *
- * @param ipAddress
- * The IP address as an integer.
- * @return The IP address separated into bytes.
- */
- public static byte[] toIPv4AddressBytes(final int ipAddress) {
- return new byte[] {(byte) (ipAddress >>> 24),
- (byte) (ipAddress >>> 16), (byte) (ipAddress >>> 8),
- (byte) ipAddress};
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.checksum;
- result = prime * result + this.destinationAddress;
- result = prime * result + this.diffServ;
- result = prime * result + this.flags;
- result = prime * result + this.fragmentOffset;
- result = prime * result + this.headerLength;
- result = prime * result + this.identification;
- result = prime * result + Arrays.hashCode(this.options);
- result = prime * result + this.protocol;
- result = prime * result + this.sourceAddress;
- result = prime * result + this.totalLength;
- result = prime * result + this.ttl;
- result = prime * result + this.version;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof IPv4)) {
- return false;
- }
- final IPv4 other = (IPv4) obj;
- if (this.checksum != other.checksum) {
- return false;
- }
- if (this.destinationAddress != other.destinationAddress) {
- return false;
- }
- if (this.diffServ != other.diffServ) {
- return false;
- }
- if (this.flags != other.flags) {
- return false;
- }
- if (this.fragmentOffset != other.fragmentOffset) {
- return false;
- }
- if (this.headerLength != other.headerLength) {
- return false;
- }
- if (this.identification != other.identification) {
- return false;
- }
- if (!Arrays.equals(this.options, other.options)) {
- return false;
- }
- if (this.protocol != other.protocol) {
- return false;
- }
- if (this.sourceAddress != other.sourceAddress) {
- return false;
- }
- if (this.totalLength != other.totalLength) {
- return false;
- }
- if (this.ttl != other.ttl) {
- return false;
- }
- if (this.version != other.version) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for IPv4 packets.
- *
- * @return deserializer function
- */
- public static Deserializer<IPv4> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- IPv4 ipv4 = new IPv4();
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- byte versionByte = bb.get();
- ipv4.headerLength = (byte) (versionByte & 0xf);
- ipv4.setVersion((byte) (versionByte >> 4 & 0xf));
- ipv4.setDiffServ(bb.get());
- ipv4.totalLength = bb.getShort();
- ipv4.identification = bb.getShort();
- short flagsFragment = bb.getShort();
- ipv4.flags = (byte) (flagsFragment >> 13 & 0x7);
- ipv4.fragmentOffset = (short) (flagsFragment & 0x1fff);
- ipv4.ttl = bb.get();
- ipv4.protocol = bb.get();
- ipv4.checksum = bb.getShort();
- ipv4.sourceAddress = bb.getInt();
- ipv4.destinationAddress = bb.getInt();
-
- if (ipv4.headerLength > 5) {
- checkHeaderLength(length, ipv4.headerLength * 4);
-
- int optionsLength = (ipv4.headerLength - 5) * 4;
- ipv4.options = new byte[optionsLength];
- bb.get(ipv4.options);
- }
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv4.PROTOCOL_DESERIALIZER_MAP.containsKey(ipv4.protocol)) {
- deserializer = IPv4.PROTOCOL_DESERIALIZER_MAP.get(ipv4.protocol);
- } else {
- deserializer = Data.deserializer();
- }
- ipv4.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- ipv4.payload.setParent(ipv4);
-
- if (ipv4.totalLength != length) {
- ipv4.isTruncated = true;
- } else {
- ipv4.isTruncated = false;
- }
-
- return ipv4;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv6.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv6.java
deleted file mode 100644
index 2e59632a..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IPv6.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.onlab.packet.ipv6.Authentication;
-import org.onlab.packet.ipv6.DestinationOptions;
-import org.onlab.packet.ipv6.EncapSecurityPayload;
-import org.onlab.packet.ipv6.Fragment;
-import org.onlab.packet.ipv6.HopByHopOptions;
-import org.onlab.packet.ipv6.IExtensionHeader;
-import org.onlab.packet.ipv6.Routing;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements IPv6 packet format. (RFC 2460)
- */
-public class IPv6 extends BasePacket implements IExtensionHeader {
- public static final byte FIXED_HEADER_LENGTH = 40; // bytes
-
- public static final byte PROTOCOL_TCP = 0x6;
- public static final byte PROTOCOL_UDP = 0x11;
- public static final byte PROTOCOL_ICMP6 = 0x3A;
- public static final byte PROTOCOL_HOPOPT = 0x00;
- public static final byte PROTOCOL_ROUTING = 0x2B;
- public static final byte PROTOCOL_FRAG = 0x2C;
- public static final byte PROTOCOL_ESP = 0x32;
- public static final byte PROTOCOL_AH = 0x33;
- public static final byte PROTOCOL_DSTOPT = 0x3C;
-
-
- public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
- new HashMap<>();
-
- static {
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ICMP6, ICMP6.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_TCP, TCP.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_UDP, UDP.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_HOPOPT, HopByHopOptions.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ROUTING, Routing.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_FRAG, Fragment.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ESP, EncapSecurityPayload.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_AH, Authentication.deserializer());
- IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_DSTOPT, DestinationOptions.deserializer());
- }
-
- protected byte version;
- protected byte trafficClass;
- protected int flowLabel;
- protected short payloadLength;
- protected byte nextHeader;
- protected byte hopLimit;
- protected byte[] sourceAddress = new byte[Ip6Address.BYTE_LENGTH];
- protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
-
- /**
- * Default constructor that sets the version to 6.
- */
- public IPv6() {
- super();
- this.version = 6;
- }
-
- /**
- * Gets IP version.
- *
- * @return the IP version
- */
- public byte getVersion() {
- return this.version;
- }
-
- /**
- * Sets IP version.
- *
- * @param version the IP version to set
- * @return this
- */
- public IPv6 setVersion(final byte version) {
- this.version = version;
- return this;
- }
-
- /**
- * Gets traffic class.
- *
- * @return the traffic class
- */
- public byte getTrafficClass() {
- return this.trafficClass;
- }
-
- /**
- * Sets traffic class.
- *
- * @param trafficClass the traffic class to set
- * @return this
- */
- public IPv6 setTrafficClass(final byte trafficClass) {
- this.trafficClass = trafficClass;
- return this;
- }
-
- /**
- * Gets flow label.
- *
- * @return the flow label
- */
- public int getFlowLabel() {
- return this.flowLabel;
- }
-
- /**
- * Sets flow label.
- *
- * @param flowLabel the flow label to set
- * @return this
- */
- public IPv6 setFlowLabel(final int flowLabel) {
- this.flowLabel = flowLabel;
- return this;
- }
-
- @Override
- public byte getNextHeader() {
- return this.nextHeader;
- }
-
- @Override
- public IPv6 setNextHeader(final byte nextHeader) {
- this.nextHeader = nextHeader;
- return this;
- }
-
- /**
- * Gets hop limit.
- *
- * @return the hop limit
- */
- public byte getHopLimit() {
- return this.hopLimit;
- }
-
- /**
- * Sets hop limit.
- *
- * @param hopLimit the hop limit to set
- * @return this
- */
- public IPv6 setHopLimit(final byte hopLimit) {
- this.hopLimit = hopLimit;
- return this;
- }
-
- /**
- * Gets source address.
- *
- * @return the IPv6 source address
- */
- public byte[] getSourceAddress() {
- return this.sourceAddress;
- }
-
- /**
- * Sets source address.
- *
- * @param sourceAddress the IPv6 source address to set
- * @return this
- */
- public IPv6 setSourceAddress(final byte[] sourceAddress) {
- this.sourceAddress = Arrays.copyOfRange(sourceAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- /**
- * Gets destination address.
- *
- * @return the IPv6 destination address
- */
- public byte[] getDestinationAddress() {
- return this.destinationAddress;
- }
-
- /**
- * Sets destination address.
- *
- * @param destinationAddress the IPv6 destination address to set
- * @return this
- */
- public IPv6 setDestinationAddress(final byte[] destinationAddress) {
- this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- this.payloadLength = 0;
- if (payloadData != null) {
- this.payloadLength = (short) payloadData.length;
- }
-
- final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt((this.version & 0xf) << 28 | (this.trafficClass & 0xff) << 20 | this.flowLabel & 0xfffff);
- bb.putShort(this.payloadLength);
- bb.put(this.nextHeader);
- bb.put(this.hopLimit);
- bb.put(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- int iscratch;
-
- iscratch = bb.getInt();
- this.version = (byte) (iscratch >> 28 & 0xf);
- this.trafficClass = (byte) (iscratch >> 20 & 0xff);
- this.flowLabel = iscratch & 0xfffff;
- this.payloadLength = bb.getShort();
- this.nextHeader = bb.get();
- this.hopLimit = bb.get();
- bb.get(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- ByteBuffer bb;
- bb = ByteBuffer.wrap(this.destinationAddress);
- for (int i = 0; i < 4; i++) {
- result = prime * result + bb.getInt();
- }
- result = prime * result + this.trafficClass;
- result = prime * result + this.flowLabel;
- result = prime * result + this.hopLimit;
- result = prime * result + this.nextHeader;
- result = prime * result + this.payloadLength;
- bb = ByteBuffer.wrap(this.sourceAddress);
- for (int i = 0; i < 4; i++) {
- result = prime * result + bb.getInt();
- }
- result = prime * result + this.version;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof IPv6)) {
- return false;
- }
- final IPv6 other = (IPv6) obj;
- if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
- return false;
- }
- if (this.trafficClass != other.trafficClass) {
- return false;
- }
- if (this.flowLabel != other.flowLabel) {
- return false;
- }
- if (this.hopLimit != other.hopLimit) {
- return false;
- }
- if (this.nextHeader != other.nextHeader) {
- return false;
- }
- if (this.payloadLength != other.payloadLength) {
- return false;
- }
- if (!Arrays.equals(this.sourceAddress, other.sourceAddress)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for IPv6 packets.
- *
- * @return deserializer function
- */
- public static Deserializer<IPv6> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, FIXED_HEADER_LENGTH);
-
- IPv6 ipv6 = new IPv6();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- int iscratch = bb.getInt();
-
- ipv6.version = (byte) (iscratch >> 28 & 0xf);
- ipv6.trafficClass = (byte) (iscratch >> 20 & 0xff);
- ipv6.flowLabel = iscratch & 0xfffff;
- ipv6.payloadLength = bb.getShort();
- ipv6.nextHeader = bb.get();
- ipv6.hopLimit = bb.get();
- bb.get(ipv6.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.get(ipv6.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(ipv6.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(ipv6.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- ipv6.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- ipv6.payload.setParent(ipv6);
-
- return ipv6;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Address.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Address.java
deleted file mode 100644
index 114f126c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Address.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import com.google.common.net.InetAddresses;
-
-/**
- * A class representing an IPv4 address.
- * This class is immutable.
- */
-public final class Ip4Address extends IpAddress {
- public static final IpAddress.Version VERSION = IpAddress.Version.INET;
- public static final int BYTE_LENGTH = IpAddress.INET_BYTE_LENGTH;
- public static final int BIT_LENGTH = IpAddress.INET_BIT_LENGTH;
-
- /**
- * Constructor for given IP address version and address octets.
- *
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @throws IllegalArgumentException if the arguments are invalid
- */
- private Ip4Address(byte[] value) {
- super(VERSION, value);
- }
-
- /**
- * Returns the integer value of this IPv4 address.
- *
- * @return the IPv4 address's value as an integer
- */
- public int toInt() {
- ByteBuffer bb = ByteBuffer.wrap(super.toOctets());
- return bb.getInt();
- }
-
- /**
- * Converts an integer into an IPv4 address.
- *
- * @param value an integer representing an IPv4 address value
- * @return an IPv4 address
- */
- public static Ip4Address valueOf(int value) {
- byte[] bytes =
- ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
- return new Ip4Address(bytes);
- }
-
- /**
- * Converts a byte array into an IPv4 address.
- *
- * @param value the IPv4 address value stored in network byte order
- * (i.e., the most significant byte first)
- * @return an IPv4 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip4Address valueOf(byte[] value) {
- return new Ip4Address(value);
- }
-
- /**
- * Converts a byte array and a given offset from the beginning of the
- * array into an IPv4 address.
- * <p>
- * The IP address is stored in network byte order (i.e., the most
- * significant byte first).
- * </p>
- * @param value the value to use
- * @param offset the offset in bytes from the beginning of the byte array
- * @return an IPv4 address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static Ip4Address valueOf(byte[] value, int offset) {
- IpAddress.checkArguments(VERSION, value, offset);
- byte[] bc = Arrays.copyOfRange(value, offset, value.length);
- return Ip4Address.valueOf(bc);
- }
-
- /**
- * Converts an InetAddress into an IPv4 address.
- *
- * @param inetAddress the InetAddress value to use. It must contain an IPv4
- * address
- * @return an IPv4 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip4Address valueOf(InetAddress inetAddress) {
- byte[] bytes = inetAddress.getAddress();
- if (inetAddress instanceof Inet4Address) {
- return new Ip4Address(bytes);
- }
- if ((inetAddress instanceof Inet6Address) ||
- (bytes.length == INET6_BYTE_LENGTH)) {
- final String msg = "Invalid IPv4 version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
- // Use the number of bytes as a hint
- if (bytes.length == INET_BYTE_LENGTH) {
- return new Ip4Address(bytes);
- }
- final String msg = "Unrecognized IP version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Converts an IPv4 string literal (e.g., "10.2.3.4") into an IP address.
- *
- * @param value an IPv4 address value in string form
- * @return an IPv4 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip4Address valueOf(String value) {
- InetAddress inetAddress = null;
- try {
- inetAddress = InetAddresses.forString(value);
- } catch (IllegalArgumentException e) {
- final String msg = "Invalid IP address string: " + value;
- throw new IllegalArgumentException(msg);
- }
- return valueOf(inetAddress);
- }
-
- /**
- * Creates an IPv4 network mask prefix.
- *
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32]
- * @return a new IPv4 address that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip4Address makeMaskPrefix(int prefixLength) {
- byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
- return new Ip4Address(mask);
- }
-
- /**
- * Creates an IPv4 address by masking it with a network mask of given
- * mask length.
- *
- * @param address the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32]
- * @return a new IPv4 address that is masked with a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- public static Ip4Address makeMaskedAddress(final Ip4Address address,
- int prefixLength) {
- byte[] net = makeMaskedAddressArray(address, prefixLength);
- return Ip4Address.valueOf(net);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Prefix.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Prefix.java
deleted file mode 100644
index fc442c3e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip4Prefix.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-/**
- * The class representing an IPv4 network address.
- * This class is immutable.
- */
-public final class Ip4Prefix extends IpPrefix {
- public static final IpAddress.Version VERSION = IpAddress.Version.INET;
- // Maximum network mask length
- public static final int MAX_MASK_LENGTH = IpPrefix.MAX_INET_MASK_LENGTH;
-
- /**
- * Constructor for given IPv4 address, and a prefix length.
- *
- * @param address the IPv4 address
- * @param prefixLength the prefix length
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- private Ip4Prefix(Ip4Address address, int prefixLength) {
- super(address, prefixLength);
- }
-
- /**
- * Returns the IPv4 address value of the prefix.
- *
- * @return the IPv4 address value of the prefix
- */
- public Ip4Address address() {
- IpAddress a = super.address();
- return (Ip4Address) a;
- }
-
- /**
- * Converts an integer and a prefix length into an IPv4 prefix.
- *
- * @param address an integer representing the IPv4 address
- * @param prefixLength the prefix length
- * @return an IPv4 prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static Ip4Prefix valueOf(int address, int prefixLength) {
- return new Ip4Prefix(Ip4Address.valueOf(address), prefixLength);
- }
-
- /**
- * Converts a byte array and a prefix length into an IPv4 prefix.
- *
- * @param address the IPv4 address value stored in network byte order
- * @param prefixLength the prefix length
- * @return an IPv4 prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static Ip4Prefix valueOf(byte[] address, int prefixLength) {
- return new Ip4Prefix(Ip4Address.valueOf(address), prefixLength);
- }
-
- /**
- * Converts an IPv4 address and a prefix length into an IPv4 prefix.
- *
- * @param address the IPv4 address
- * @param prefixLength the prefix length
- * @return an IPv4 prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static Ip4Prefix valueOf(Ip4Address address, int prefixLength) {
- return new Ip4Prefix(address, prefixLength);
- }
-
- /**
- * Converts a CIDR (slash) notation string (e.g., "10.1.0.0/16")
- * into an IPv4 prefix.
- *
- * @param address an IP prefix in string form (e.g., "10.1.0.0/16")
- * @return an IPv4 prefix
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static Ip4Prefix valueOf(String address) {
- final String[] parts = address.split("/");
- if (parts.length != 2) {
- String msg = "Malformed IPv4 prefix string: " + address + ". " +
- "Address must take form \"x.x.x.x/y\"";
- throw new IllegalArgumentException(msg);
- }
- Ip4Address ipAddress = Ip4Address.valueOf(parts[0]);
- int prefixLength = Integer.parseInt(parts[1]);
-
- return new Ip4Prefix(ipAddress, prefixLength);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java
deleted file mode 100644
index d353422b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Address.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.util.Arrays;
-
-import com.google.common.net.InetAddresses;
-
-/**
- * A class representing an IPv6 address.
- * This class is immutable.
- */
-public final class Ip6Address extends IpAddress {
- public static final IpAddress.Version VERSION = IpAddress.Version.INET6;
- public static final int BYTE_LENGTH = IpAddress.INET6_BYTE_LENGTH;
- public static final int BIT_LENGTH = IpAddress.INET6_BIT_LENGTH;
-
- /**
- * Constructor for given IP address version and address octets.
- *
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @throws IllegalArgumentException if the arguments are invalid
- */
- private Ip6Address(byte[] value) {
- super(VERSION, value);
- }
-
- /**
- * Converts a byte array into an IPv6 address.
- *
- * @param value the IPv6 address value stored in network byte order
- * (i.e., the most significant byte first)
- * @return an IPv6 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip6Address valueOf(byte[] value) {
- return new Ip6Address(value);
- }
-
- /**
- * Converts a byte array and a given offset from the beginning of the
- * array into an IPv6 address.
- * <p>
- * The IP address is stored in network byte order (i.e., the most
- * significant byte first).
- * </p>
- * @param value the value to use
- * @param offset the offset in bytes from the beginning of the byte array
- * @return an IPv6 address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static Ip6Address valueOf(byte[] value, int offset) {
- IpAddress.checkArguments(VERSION, value, offset);
- byte[] bc = Arrays.copyOfRange(value, offset, value.length);
- return Ip6Address.valueOf(bc);
- }
-
- /**
- * Converts an InetAddress into an IPv6 address.
- *
- * @param inetAddress the InetAddress value to use. It must contain an IPv6
- * address
- * @return an IPv6 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip6Address valueOf(InetAddress inetAddress) {
- byte[] bytes = inetAddress.getAddress();
- if (inetAddress instanceof Inet6Address) {
- return new Ip6Address(bytes);
- }
- if ((inetAddress instanceof Inet4Address) ||
- (bytes.length == INET_BYTE_LENGTH)) {
- final String msg = "Invalid IPv6 version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
- // Use the number of bytes as a hint
- if (bytes.length == INET6_BYTE_LENGTH) {
- return new Ip6Address(bytes);
- }
- final String msg = "Unrecognized IP version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Converts an IPv6 string literal (e.g., "1111:2222::8888") into an IP
- * address.
- *
- * @param value an IPv6 address value in string form
- * @return an IPv6 address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static Ip6Address valueOf(String value) {
- InetAddress inetAddress = null;
- try {
- inetAddress = InetAddresses.forString(value);
- } catch (IllegalArgumentException e) {
- final String msg = "Invalid IP address string: " + value;
- throw new IllegalArgumentException(msg);
- }
- return valueOf(inetAddress);
- }
-
- /**
- * Creates an IPv6 network mask prefix.
- *
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 128]
- * @return a new IPv6 address that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static Ip6Address makeMaskPrefix(int prefixLength) {
- byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
- return new Ip6Address(mask);
- }
-
- /**
- * Creates an IPv6 address by masking it with a network mask of given
- * mask length.
- *
- * @param address the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 128]
- * @return a new IPv6 address that is masked with a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- public static Ip6Address makeMaskedAddress(final Ip6Address address,
- int prefixLength) {
- byte[] net = makeMaskedAddressArray(address, prefixLength);
- return Ip6Address.valueOf(net);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Prefix.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Prefix.java
deleted file mode 100644
index 4ea9099b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/Ip6Prefix.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-/**
- * The class representing an IPv6 network address.
- * This class is immutable.
- */
-public final class Ip6Prefix extends IpPrefix {
- public static final IpAddress.Version VERSION = IpAddress.Version.INET6;
- // Maximum network mask length
- public static final int MAX_MASK_LENGTH = IpPrefix.MAX_INET6_MASK_LENGTH;
-
- /**
- * Constructor for given IPv6 address, and a prefix length.
- *
- * @param address the IPv6 address
- * @param prefixLength the prefix length
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- private Ip6Prefix(Ip6Address address, int prefixLength) {
- super(address, prefixLength);
- }
-
- /**
- * Returns the IPv6 address value of the prefix.
- *
- * @return the IPv6 address value of the prefix
- */
- public Ip6Address address() {
- IpAddress a = super.address();
- return (Ip6Address) a;
- }
-
- /**
- * Converts a byte array and a prefix length into an IPv6 prefix.
- *
- * @param address the IPv6 address value stored in network byte order
- * @param prefixLength the prefix length
- * @return an IPv6 prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static Ip6Prefix valueOf(byte[] address, int prefixLength) {
- return new Ip6Prefix(Ip6Address.valueOf(address), prefixLength);
- }
-
- /**
- * Converts an IPv6 address and a prefix length into an IPv6 prefix.
- *
- * @param address the IPv6 address
- * @param prefixLength the prefix length
- * @return an IPv6 prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static Ip6Prefix valueOf(Ip6Address address, int prefixLength) {
- return new Ip6Prefix(address, prefixLength);
- }
-
- /**
- * Converts a CIDR (slash) notation string (e.g., "1111:2222::/64")
- * into an IPv6 prefix.
- *
- * @param address an IP prefix in string form (e.g.,"1111:2222::/64")
- * @return an IPv6 prefix
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static Ip6Prefix valueOf(String address) {
- final String[] parts = address.split("/");
- if (parts.length != 2) {
- String msg = "Malformed IPv6 prefix string: " + address + ". " +
- "Address must take form " +
- "\"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/y\"";
- throw new IllegalArgumentException(msg);
- }
- Ip6Address ipAddress = Ip6Address.valueOf(parts[0]);
- int prefixLength = Integer.parseInt(parts[1]);
-
- return new Ip6Prefix(ipAddress, prefixLength);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
deleted file mode 100644
index 5fdd3276..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Objects;
-import com.google.common.net.InetAddresses;
-import com.google.common.primitives.UnsignedBytes;
-
-
-/**
- * A class representing an IP address.
- * This class is immutable.
- */
-public class IpAddress implements Comparable<IpAddress> {
- private static final int BIT_MASK = 0x000000ff;
-
- // IP Versions
- public enum Version { INET, INET6 };
-
- // lengths of address, in bytes
- public static final int INET_BYTE_LENGTH = 4;
- public static final int INET_BIT_LENGTH = INET_BYTE_LENGTH * Byte.SIZE;
- public static final int INET6_BYTE_LENGTH = 16;
- public static final int INET6_BIT_LENGTH = INET6_BYTE_LENGTH * Byte.SIZE;
-
- private final Version version;
- private final byte[] octets;
-
- /**
- * Constructor for given IP address version and address octets.
- *
- * @param version the IP address version
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @throws IllegalArgumentException if the arguments are invalid
- */
- protected IpAddress(Version version, byte[] value) {
- checkArguments(version, value, 0);
- this.version = version;
- switch (version) {
- case INET:
- this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
- break;
- case INET6:
- this.octets = Arrays.copyOf(value, INET6_BYTE_LENGTH);
- break;
- default:
- // Should not be reached
- this.octets = null;
- break;
- }
- }
-
- /**
- * Returns the IP version of this address.
- *
- * @return the version
- */
- public Version version() {
- return this.version;
- }
-
- /**
- * Tests whether the IP version of this address is IPv4.
- *
- * @return true if the IP version of this address is IPv4, otherwise false.
- */
- public boolean isIp4() {
- return (version() == Ip4Address.VERSION);
- }
-
- /**
- * Tests whether the IP version of this address is IPv6.
- *
- * @return true if the IP version of this address is IPv6, otherwise false.
- */
- public boolean isIp6() {
- return (version() == Ip6Address.VERSION);
- }
-
- /**
- * Gets the {@link Ip4Address} view of the IP address.
- *
- * @return the {@link Ip4Address} view of the IP address if it is IPv4,
- * otherwise null
- */
- public Ip4Address getIp4Address() {
- if (!isIp4()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip4Address
- if (this instanceof Ip4Address) {
- return (Ip4Address) this;
- }
- return Ip4Address.valueOf(octets);
- }
-
- /**
- * Gets the {@link Ip6Address} view of the IP address.
- *
- * @return the {@link Ip6Address} view of the IP address if it is IPv6,
- * otherwise null
- */
- public Ip6Address getIp6Address() {
- if (!isIp6()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip6Address
- if (this instanceof Ip6Address) {
- return (Ip6Address) this;
- }
- return Ip6Address.valueOf(octets);
- }
-
- /**
- * Returns the IP address as a byte array.
- *
- * @return a byte array
- */
- public byte[] toOctets() {
- return Arrays.copyOf(octets, octets.length);
- }
-
- /**
- * Computes the IP address byte length for a given IP version.
- *
- * @param version the IP version
- * @return the IP address byte length for the IP version
- * @throws IllegalArgumentException if the IP version is invalid
- */
- public static int byteLength(Version version) {
- switch (version) {
- case INET:
- return INET_BYTE_LENGTH;
- case INET6:
- return INET6_BYTE_LENGTH;
- default:
- String msg = "Invalid IP version " + version;
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Converts an integer into an IPv4 address.
- *
- * @param value an integer representing an IPv4 address value
- * @return an IP address
- */
- public static IpAddress valueOf(int value) {
- byte[] bytes =
- ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
- return new IpAddress(Version.INET, bytes);
- }
-
- /**
- * Converts a byte array into an IP address.
- *
- * @param version the IP address version
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @return an IP address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress valueOf(Version version, byte[] value) {
- return new IpAddress(version, value);
- }
-
- /**
- * Converts a byte array and a given offset from the beginning of the
- * array into an IP address.
- * <p>
- * The IP address is stored in network byte order (i.e., the most
- * significant byte first).
- * </p>
- * @param version the IP address version
- * @param value the value to use
- * @param offset the offset in bytes from the beginning of the byte array
- * @return an IP address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress valueOf(Version version, byte[] value,
- int offset) {
- checkArguments(version, value, offset);
- byte[] bc = Arrays.copyOfRange(value, offset, value.length);
- return IpAddress.valueOf(version, bc);
- }
-
- /**
- * Converts an InetAddress into an IP address.
- *
- * @param inetAddress the InetAddress value to use
- * @return an IP address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static IpAddress valueOf(InetAddress inetAddress) {
- byte[] bytes = inetAddress.getAddress();
- if (inetAddress instanceof Inet4Address) {
- return new IpAddress(Version.INET, bytes);
- }
- if (inetAddress instanceof Inet6Address) {
- return new IpAddress(Version.INET6, bytes);
- }
- // Use the number of bytes as a hint
- if (bytes.length == INET_BYTE_LENGTH) {
- return new IpAddress(Version.INET, bytes);
- }
- if (bytes.length == INET6_BYTE_LENGTH) {
- return new IpAddress(Version.INET6, bytes);
- }
- final String msg = "Unrecognized IP version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Converts an IPv4 or IPv6 string literal (e.g., "10.2.3.4" or
- * "1111:2222::8888") into an IP address.
- *
- * @param value an IP address value in string form
- * @return an IP address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static IpAddress valueOf(String value) {
- InetAddress inetAddress = null;
- try {
- inetAddress = InetAddresses.forString(value);
- } catch (IllegalArgumentException e) {
- final String msg = "Invalid IP address string: " + value;
- throw new IllegalArgumentException(msg);
- }
- return valueOf(inetAddress);
- }
-
- /**
- * Creates an IP network mask prefix.
- *
- * @param version the IP address version
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a new IP address that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress makeMaskPrefix(Version version, int prefixLength) {
- byte[] mask = makeMaskPrefixArray(version, prefixLength);
- return new IpAddress(version, mask);
- }
-
- /**
- * Creates an IP address by masking it with a network mask of given
- * mask length.
- *
- * @param address the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a new IP address that is masked with a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- public static IpAddress makeMaskedAddress(final IpAddress address,
- int prefixLength) {
- if (address instanceof Ip4Address) {
- Ip4Address ip4a = (Ip4Address) address;
- return Ip4Address.makeMaskedAddress(ip4a, prefixLength);
- } else if (address instanceof Ip6Address) {
- Ip6Address ip6a = (Ip6Address) address;
- return Ip6Address.makeMaskedAddress(ip6a, prefixLength);
- } else {
- byte[] net = makeMaskedAddressArray(address, prefixLength);
- return IpAddress.valueOf(address.version(), net);
- }
- }
-
- /**
- * Check if this IP address is zero.
- *
- * @return true if this address is zero
- */
- public boolean isZero() {
- for (byte b : octets) {
- if (b != 0) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Check if this IP address is self-assigned.
- *
- * @return true if this address is self-assigned
- */
- public boolean isSelfAssigned() {
- return isIp4() && octets[0] == (byte) 169;
- }
-
- @Override
- public int compareTo(IpAddress o) {
- // Compare first the version
- if (this.version != o.version) {
- return this.version.compareTo(o.version);
- }
-
- // Compare the bytes, one-by-one
- for (int i = 0; i < this.octets.length; i++) {
- if (this.octets[i] != o.octets[i]) {
- return UnsignedBytes.compare(this.octets[i], o.octets[i]);
- }
- }
- return 0; // Equal
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(version, Arrays.hashCode(octets));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj == null) || (!(obj instanceof IpAddress))) {
- return false;
- }
- IpAddress other = (IpAddress) obj;
- return (version == other.version) &&
- Arrays.equals(octets, other.octets);
- }
-
- @Override
- /*
- * (non-Javadoc)
- * The string representation of the IP address: "x.x.x.x" for IPv4
- * addresses, or ':' separated string for IPv6 addresses.
- *
- * @see java.lang.Object#toString()
- */
- public String toString() {
- // FIXME InetAddress is super slow
- switch (version) {
- case INET:
- return String.format("%d.%d.%d.%d", octets[0] & 0xff,
- octets[1] & 0xff,
- octets[2] & 0xff,
- octets[3] & 0xff);
- case INET6:
- default:
- return ipv6ToStringHelper();
- }
- }
-
- /**
- * Generates an IP prefix.
- *
- * @return the IP prefix of the IP address
- */
- public IpPrefix toIpPrefix() {
-
- if (isIp4()) {
- return IpPrefix.valueOf(new IpAddress(Version.INET, octets),
- Ip4Address.BIT_LENGTH);
- } else {
- return IpPrefix.valueOf(new IpAddress(Version.INET6, octets),
- Ip6Address.BIT_LENGTH);
- }
- }
-
- /**
- * Gets the IP address name for the IP address version.
- *
- * @param version the IP address version
- * @return the IP address name for the IP address version
- */
- private static String addressName(Version version) {
- switch (version) {
- case INET:
- return "IPv4";
- case INET6:
- return "IPv6";
- default:
- break;
- }
- return "UnknownIP(" + version + ")";
- }
-
- /**
- * Checks whether the arguments are valid.
- *
- * @param version the IP address version
- * @param value the IP address value stored in a byte array
- * @param offset the offset in bytes from the beginning of the byte
- * array with the address
- * @throws IllegalArgumentException if any of the arguments is invalid
- */
- static void checkArguments(Version version, byte[] value, int offset) {
- // Check the offset and byte array length
- int addrByteLength = byteLength(version);
- if ((offset < 0) || (offset + addrByteLength > value.length)) {
- String msg;
- if (value.length < addrByteLength) {
- msg = "Invalid " + addressName(version) +
- " address array: array length: " + value.length +
- ". Must be at least " + addrByteLength;
- } else {
- msg = "Invalid " + addressName(version) +
- " address array: array offset: " + offset +
- ". Must be in the interval [0, " +
- (value.length - addrByteLength) + "]";
- }
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Creates a byte array for IP network mask prefix.
- *
- * @param version the IP address version
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a byte array that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the arguments are invalid
- */
- static byte[] makeMaskPrefixArray(Version version, int prefixLength) {
- int addrByteLength = byteLength(version);
- int addrBitLength = addrByteLength * Byte.SIZE;
-
- // Verify the prefix length
- if ((prefixLength < 0) || (prefixLength > addrBitLength)) {
- final String msg = "Invalid IP prefix length: " + prefixLength +
- ". Must be in the interval [0, " + addrBitLength + "].";
- throw new IllegalArgumentException(msg);
- }
-
- // Number of bytes and extra bits that should be all 1s
- int maskBytes = prefixLength / Byte.SIZE;
- int maskBits = prefixLength % Byte.SIZE;
- byte[] mask = new byte[addrByteLength];
-
- // Set the bytes and extra bits to 1s
- for (int i = 0; i < maskBytes; i++) {
- mask[i] = (byte) 0xff; // Set mask bytes to 1s
- }
- for (int i = maskBytes; i < addrByteLength; i++) {
- mask[i] = 0; // Set remaining bytes to 0s
- }
- if (maskBits > 0) {
- mask[maskBytes] = (byte) (0xff << (Byte.SIZE - maskBits));
- }
- return mask;
- }
-
- /**
- * Creates a byte array that represents an IP address masked with
- * a network mask of given mask length.
- *
- * @param addr the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a byte array that represents the IP address masked with
- * a mask prefix of the specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- static byte[] makeMaskedAddressArray(final IpAddress addr,
- int prefixLength) {
- byte[] mask = IpAddress.makeMaskPrefixArray(addr.version(),
- prefixLength);
- byte[] net = new byte[mask.length];
-
- // Mask each byte
- for (int i = 0; i < net.length; i++) {
- net[i] = (byte) (addr.octets[i] & mask[i]);
- }
- return net;
- }
-
- /**
- * Creates a string based on the IPv6 recommendations for canonical representations found here:
- * https://tools.ietf.org/html/rfc5952#section-1.
- * @return A properly formatted IPv6 canonical representation.
- */
- private String ipv6ToStringHelper() {
- //Populate a buffer with the string of the full address with leading zeros stripped
- StringBuffer buff = new StringBuffer();
- buff.append(String.format("%x:%x:%x:%x:%x:%x:%x:%x",
- (((octets[0] & BIT_MASK) << 8) | (octets[1] & BIT_MASK)),
- (((octets[2] & BIT_MASK) << 8) | (octets[3] & BIT_MASK)),
- (((octets[4] & BIT_MASK) << 8) | (octets[5] & BIT_MASK)),
- (((octets[6] & BIT_MASK) << 8) | (octets[7] & BIT_MASK)),
- (((octets[8] & BIT_MASK) << 8) | (octets[9] & BIT_MASK)),
- (((octets[10] & BIT_MASK) << 8) | (octets[11] & BIT_MASK)),
- (((octets[12] & BIT_MASK) << 8) | (octets[13] & BIT_MASK)),
- (((octets[14] & BIT_MASK) << 8) | (octets[15] & BIT_MASK))));
- //Initialize variables for tracking longest zero subsequence, tiebreaking by first occurence
- int longestSeqStart, longestSeqLen, currSeqStart, currSeqLen;
- longestSeqStart = 0;
- longestSeqLen = 0;
- currSeqStart = 0;
- currSeqLen = 0;
-
- for (int index = 0; index < buff.length(); index++) {
- if (buff.charAt(index) == ':') {
- if (currSeqLen != 0 && buff.charAt(index + 1) == '0') {
- currSeqLen += 1;
- }
- } else if (buff.charAt(index) == '0' && ((index == 0) || (buff.charAt(index - 1) == ':'))) {
- if (currSeqLen == 0) {
- currSeqStart = index;
- }
- currSeqLen += 1;
- } else {
- if (currSeqLen > longestSeqLen) {
- longestSeqStart = currSeqStart;
- longestSeqLen = currSeqLen;
- }
- currSeqLen = 0;
- }
- }
-
- if (currSeqLen > longestSeqLen) {
- longestSeqLen = currSeqLen;
- longestSeqStart = currSeqStart;
- }
- if (longestSeqLen > 1) {
- if (buff.length() == (longestSeqStart + longestSeqLen)) {
- buff.append(':');
- }
-
- buff.delete(longestSeqStart, longestSeqStart + longestSeqLen);
-
- if (longestSeqStart == 0) {
- buff.insert(0, ':');
- }
- }
-
- return buff.toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpPrefix.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpPrefix.java
deleted file mode 100644
index 14d07fed..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpPrefix.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.util.Objects;
-
-/**
- * A class representing an IP prefix. A prefix consists of an IP address and
- * a subnet mask.
- * This class is immutable.
- * <p>
- * NOTE: The stored IP address in the result IP prefix is masked to
- * contain zeroes in all bits after the prefix length.
- * </p>
- */
-public class IpPrefix {
- // Maximum network mask length
- public static final int MAX_INET_MASK_LENGTH = IpAddress.INET_BIT_LENGTH;
- public static final int MAX_INET6_MASK_LENGTH = IpAddress.INET6_BIT_LENGTH;
-
- private final IpAddress address;
- private final short prefixLength;
-
- /**
- * Constructor for given IP address, and a prefix length.
- *
- * @param address the IP address
- * @param prefixLength the prefix length
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- protected IpPrefix(IpAddress address, int prefixLength) {
- checkPrefixLength(address.version(), prefixLength);
- this.address = IpAddress.makeMaskedAddress(address, prefixLength);
- this.prefixLength = (short) prefixLength;
- }
-
- /**
- * Returns the IP version of the prefix.
- *
- * @return the IP version of the prefix
- */
- public IpAddress.Version version() {
- return address.version();
- }
-
- /**
- * Tests whether the IP version of this prefix is IPv4.
- *
- * @return true if the IP version of this prefix is IPv4, otherwise false.
- */
- public boolean isIp4() {
- return address.isIp4();
- }
-
- /**
- * Tests whether the IP version of this prefix is IPv6.
- *
- * @return true if the IP version of this prefix is IPv6, otherwise false.
- */
- public boolean isIp6() {
- return address.isIp6();
- }
-
- /**
- * Returns the IP address value of the prefix.
- *
- * @return the IP address value of the prefix
- */
- public IpAddress address() {
- return address;
- }
-
- /**
- * Returns the IP address prefix length.
- *
- * @return the IP address prefix length
- */
- public int prefixLength() {
- return prefixLength;
- }
-
- /**
- * Gets the {@link Ip4Prefix} view of the IP prefix.
- *
- * @return the {@link Ip4Prefix} view of the IP prefix if it is IPv4,
- * otherwise null
- */
- public Ip4Prefix getIp4Prefix() {
- if (!isIp4()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip4Prefix
- if (this instanceof Ip4Prefix) {
- return (Ip4Prefix) this;
- }
- return Ip4Prefix.valueOf(address.getIp4Address(), prefixLength);
- }
-
- /**
- * Gets the {@link Ip6Prefix} view of the IP prefix.
- *
- * @return the {@link Ip6Prefix} view of the IP prefix if it is IPv6,
- * otherwise null
- */
- public Ip6Prefix getIp6Prefix() {
- if (!isIp6()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip6Prefix
- if (this instanceof Ip6Prefix) {
- return (Ip6Prefix) this;
- }
- return Ip6Prefix.valueOf(address.getIp6Address(), prefixLength);
- }
-
- /**
- * Converts an integer and a prefix length into an IPv4 prefix.
- *
- * @param address an integer representing the IPv4 address
- * @param prefixLength the prefix length
- * @return an IP prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static IpPrefix valueOf(int address, int prefixLength) {
- return new IpPrefix(IpAddress.valueOf(address), prefixLength);
- }
-
- /**
- * Converts a byte array and a prefix length into an IP prefix.
- *
- * @param version the IP address version
- * @param address the IP address value stored in network byte order
- * @param prefixLength the prefix length
- * @return an IP prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static IpPrefix valueOf(IpAddress.Version version, byte[] address,
- int prefixLength) {
- return new IpPrefix(IpAddress.valueOf(version, address), prefixLength);
- }
-
- /**
- * Converts an IP address and a prefix length into an IP prefix.
- *
- * @param address the IP address
- * @param prefixLength the prefix length
- * @return an IP prefix
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- public static IpPrefix valueOf(IpAddress address, int prefixLength) {
- return new IpPrefix(address, prefixLength);
- }
-
- /**
- * Converts a CIDR (slash) notation string (e.g., "10.1.0.0/16" or
- * "1111:2222::/64") into an IP prefix.
- *
- * @param address an IP prefix in string form (e.g. "10.1.0.0/16" or
- * "1111:2222::/64")
- * @return an IP prefix
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpPrefix valueOf(String address) {
- final String[] parts = address.split("/");
- if (parts.length != 2) {
- String msg = "Malformed IP prefix string: " + address + ". " +
- "Address must take form \"x.x.x.x/y\" or " +
- "\"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/y\"";
- throw new IllegalArgumentException(msg);
- }
- IpAddress ipAddress = IpAddress.valueOf(parts[0]);
- int prefixLength = Integer.parseInt(parts[1]);
-
- return new IpPrefix(ipAddress, prefixLength);
- }
-
- /**
- * Determines whether a given IP prefix is contained within this prefix.
- *
- * @param other the IP prefix to test
- * @return true if the other IP prefix is contained in this prefix,
- * otherwise false
- */
- public boolean contains(IpPrefix other) {
- if (version() != other.version()) {
- return false;
- }
-
- if (this.prefixLength > other.prefixLength) {
- return false; // This prefix has smaller prefix size
- }
-
- //
- // Mask the other address with my prefix length.
- // If the other prefix is within this prefix, the masked address must
- // be same as the address of this prefix.
- //
- IpAddress maskedAddr =
- IpAddress.makeMaskedAddress(other.address, this.prefixLength);
- return this.address.equals(maskedAddr);
- }
-
- /**
- * Determines whether a given IP address is contained within this prefix.
- *
- * @param other the IP address to test
- * @return true if the IP address is contained in this prefix, otherwise
- * false
- */
- public boolean contains(IpAddress other) {
- if (version() != other.version()) {
- return false;
- }
-
- //
- // Mask the other address with my prefix length.
- // If the other prefix is within this prefix, the masked address must
- // be same as the address of this prefix.
- //
- IpAddress maskedAddr =
- IpAddress.makeMaskedAddress(other, this.prefixLength);
- return this.address.equals(maskedAddr);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(address, prefixLength);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj == null) || (!(obj instanceof IpPrefix))) {
- return false;
- }
- IpPrefix other = (IpPrefix) obj;
- return ((prefixLength == other.prefixLength) &&
- address.equals(other.address));
- }
-
- @Override
- /*
- * (non-Javadoc)
- * The format is "x.x.x.x/y" for IPv4 prefixes.
- *
- * @see java.lang.Object#toString()
- */
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append(address.toString());
- builder.append("/");
- builder.append(String.format("%d", prefixLength));
- return builder.toString();
- }
-
- /**
- * Checks whether the prefix length is valid.
- *
- * @param version the IP address version
- * @param prefixLength the prefix length value to check
- * @throws IllegalArgumentException if the prefix length value is invalid
- */
- private static void checkPrefixLength(IpAddress.Version version,
- int prefixLength) {
- int maxPrefixLen = 0;
-
- switch (version) {
- case INET:
- maxPrefixLen = MAX_INET_MASK_LENGTH;
- break;
- case INET6:
- maxPrefixLen = MAX_INET6_MASK_LENGTH;
- break;
- default:
- String msg = "Invalid IP version " + version;
- throw new IllegalArgumentException(msg);
- }
-
- if ((prefixLength < 0) || (prefixLength > maxPrefixLen)) {
- String msg = "Invalid prefix length " + prefixLength + ". " +
- "The value must be in the interval [0, " +
- maxPrefixLen + "]";
- throw new IllegalArgumentException(msg);
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLC.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLC.java
deleted file mode 100644
index 78b4f3fa..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLC.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- * This class represents an Link Local Control header that is used in Ethernet
- * 802.3.
- *
- *
- */
-public class LLC extends BasePacket {
-
- public static final byte LLC_HEADER_LENGTH = 3;
-
- private byte dsap = 0;
- private byte ssap = 0;
- private byte ctrl = 0;
-
- public byte getDsap() {
- return this.dsap;
- }
-
- public void setDsap(final byte dsap) {
- this.dsap = dsap;
- }
-
- public byte getSsap() {
- return this.ssap;
- }
-
- public void setSsap(final byte ssap) {
- this.ssap = ssap;
- }
-
- public byte getCtrl() {
- return this.ctrl;
- }
-
- public void setCtrl(final byte ctrl) {
- this.ctrl = ctrl;
- }
-
- @Override
- public byte[] serialize() {
- final byte[] data = new byte[3];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.dsap);
- bb.put(this.ssap);
- bb.put(this.ctrl);
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.dsap = bb.get();
- this.ssap = bb.get();
- this.ctrl = bb.get();
- return this;
- }
-
- /**
- * Deserializer function for LLC packets.
- *
- * @return deserializer function
- */
- public static Deserializer<LLC> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, LLC_HEADER_LENGTH);
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- LLC llc = new LLC();
-
- llc.dsap = bb.get();
- llc.ssap = bb.get();
- llc.ctrl = bb.get();
-
- return llc;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java
deleted file mode 100644
index ae9d7173..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- *
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- *
- */
-public class LLDP extends BasePacket {
- public static final byte CHASSIS_TLV_TYPE = 1;
- public static final short CHASSIS_TLV_SIZE = 7;
- public static final byte CHASSIS_TLV_SUBTYPE = 4;
-
- public static final byte PORT_TLV_TYPE = 2;
- public static final short PORT_TLV_SIZE = 5;
- public static final byte PORT_TLV_SUBTYPE = 2;
-
- public static final byte TTL_TLV_TYPE = 3;
- public static final short TTL_TLV_SIZE = 2;
-
- protected LLDPTLV chassisId;
- protected LLDPTLV portId;
- protected LLDPTLV ttl;
- protected List<LLDPTLV> optionalTLVList;
- protected short ethType;
-
- public LLDP() {
- this.optionalTLVList = new LinkedList<>();
- this.ethType = Ethernet.TYPE_LLDP;
- }
-
- /**
- * @return the chassisId
- */
- public LLDPTLV getChassisId() {
- return this.chassisId;
- }
-
- /**
- * @param chassis
- * the chassisId to set
- * @return this
- */
- public LLDP setChassisId(final LLDPTLV chassis) {
- this.chassisId = chassis;
- return this;
- }
-
- /**
- * @return the portId
- */
- public LLDPTLV getPortId() {
- return this.portId;
- }
-
- /**
- * @param portId
- * the portId to set
- * @return this
- */
- public LLDP setPortId(final LLDPTLV portId) {
- this.portId = portId;
- return this;
- }
-
- /**
- * @return the ttl
- */
- public LLDPTLV getTtl() {
- return this.ttl;
- }
-
- /**
- * @param ttl
- * the ttl to set
- * @return this
- */
- public LLDP setTtl(final LLDPTLV ttl) {
- this.ttl = ttl;
- return this;
- }
-
- /**
- * @return the optionalTLVList
- */
- public List<LLDPTLV> getOptionalTLVList() {
- return this.optionalTLVList;
- }
-
- /**
- * @param optionalTLVList
- * the optionalTLVList to set
- * @return this
- */
- public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) {
- this.optionalTLVList = optionalTLVList;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- int length = 2 + this.chassisId.getLength() + 2
- + this.portId.getLength() + 2 + this.ttl.getLength() + 2;
- for (final LLDPTLV tlv : this.optionalTLVList) {
- length += 2 + tlv.getLength();
- }
-
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.put(this.chassisId.serialize());
- bb.put(this.portId.serialize());
- bb.put(this.ttl.serialize());
- for (final LLDPTLV tlv : this.optionalTLVList) {
- bb.put(tlv.serialize());
- }
- bb.putShort((short) 0); // End of LLDPDU
-
- /*
- * if (this.parent != null && this.parent instanceof Ethernet) {
- * ((Ethernet) this.parent).setEtherType(this.ethType); }
- */
-
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- LLDPTLV tlv;
- do {
- try {
- tlv = new LLDPOrganizationalTLV().deserialize(bb);
- } catch (DeserializationException e) {
- break;
- }
-
- // if there was a failure to deserialize stop processing TLVs
- if (tlv == null) {
- break;
- }
- switch (tlv.getType()) {
- case 0x0:
- // can throw this one away, its just an end delimiter
- break;
- case 0x1:
- this.chassisId = tlv;
- break;
- case 0x2:
- this.portId = tlv;
- break;
- case 0x3:
- this.ttl = tlv;
- break;
-
- default:
- this.optionalTLVList.add(tlv);
- break;
- }
- } while (tlv.getType() != 0 && bb.hasRemaining());
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 883;
- int result = super.hashCode();
- result = prime * result
- + (this.chassisId == null ? 0 : this.chassisId.hashCode());
- result = prime * result + this.optionalTLVList.hashCode();
- result = prime * result
- + (this.portId == null ? 0 : this.portId.hashCode());
- result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof LLDP)) {
- return false;
- }
- final LLDP other = (LLDP) obj;
- if (this.chassisId == null) {
- if (other.chassisId != null) {
- return false;
- }
- } else if (!this.chassisId.equals(other.chassisId)) {
- return false;
- }
- if (!this.optionalTLVList.equals(other.optionalTLVList)) {
- return false;
- }
- if (this.portId == null) {
- if (other.portId != null) {
- return false;
- }
- } else if (!this.portId.equals(other.portId)) {
- return false;
- }
- if (this.ttl == null) {
- if (other.ttl != null) {
- return false;
- }
- } else if (!this.ttl.equals(other.ttl)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for LLDP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<LLDP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, 0);
-
- LLDP lldp = new LLDP();
-
- int currentIndex = 0;
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- LLDPTLV tlv;
- do {
- // Each new TLV must be a minimum of 2 bytes
- // (containing the type and length fields).
- currentIndex += 2;
- checkHeaderLength(length, currentIndex);
-
- tlv = new LLDPOrganizationalTLV().deserialize(bb);
-
- // if there was a failure to deserialize stop processing TLVs
- if (tlv == null) {
- break;
- }
- switch (tlv.getType()) {
- case 0x0:
- // can throw this one away, it's just an end delimiter
- break;
- case 0x1:
- lldp.chassisId = tlv;
- break;
- case 0x2:
- lldp.portId = tlv;
- break;
- case 0x3:
- lldp.ttl = tlv;
- break;
- default:
- lldp.optionalTLVList.add(tlv);
- break;
- }
-
- currentIndex += tlv.getLength();
- } while (tlv.getType() != 0);
-
- return lldp;
- };
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPOrganizationalTLV.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPOrganizationalTLV.java
deleted file mode 100644
index bedf439f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPOrganizationalTLV.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License. You may obtain
- * a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- **/
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-
-/**
- * The class representing LLDP Organizationally Specific TLV.
- *
- */
-public class LLDPOrganizationalTLV extends LLDPTLV {
- public static final int OUI_LENGTH = 3;
- public static final int SUBTYPE_LENGTH = 1;
- public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
- public static final int MAX_INFOSTRING_LENGTH = 507;
-
- protected byte[] oui;
- protected byte subType;
- private byte[] infoString;
-
- public LLDPOrganizationalTLV() {
- this.type = LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE;
- }
-
- /**
- * Set the value of OUI.
- *
- * @param oui
- * The value of OUI to be set.
- * @return This LLDP Organizationally Specific TLV.
- */
- public LLDPOrganizationalTLV setOUI(final byte[] oui) {
- if (oui.length != LLDPOrganizationalTLV.OUI_LENGTH) {
- throw new IllegalArgumentException("The length of OUI must be "
- + LLDPOrganizationalTLV.OUI_LENGTH + ", but it is "
- + oui.length);
- }
- this.oui = Arrays.copyOf(oui, oui.length);
- return this;
- }
-
- /**
- * Returns the value of the OUI.
- *
- * @return The value of the OUI .
- */
- public byte[] getOUI() {
- return Arrays.copyOf(this.oui, this.oui.length);
- }
-
- /**
- * Set the value of sub type.
- *
- * @param subType
- * The value of sub type to be set.
- * @return This LLDP Organizationally Specific TLV.
- */
- public LLDPOrganizationalTLV setSubType(final byte subType) {
- this.subType = subType;
- return this;
- }
-
- /**
- * Returns the value of the sub type.
- *
- * @return The value of the sub type.
- */
- public byte getSubType() {
- return this.subType;
- }
-
- /**
- * Set the value of information string.
- *
- * @param infoString
- * the byte array of the value of information string.
- * @return This LLDP Organizationally Specific TLV.
- */
- public LLDPOrganizationalTLV setInfoString(final byte[] infoString) {
- if (infoString.length > LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH) {
- throw new IllegalArgumentException(
- "The length of infoString cannot exceed "
- + LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH);
- }
- this.infoString = Arrays.copyOf(infoString, infoString.length);
- return this;
- }
-
- /**
- * Set the value of information string. The String value is automatically
- * converted into byte array with UTF-8 encoding.
- *
- * @param infoString
- * the String value of information string.
- * @return This LLDP Organizationally Specific TLV.
- */
- public LLDPOrganizationalTLV setInfoString(final String infoString) {
- final byte[] infoStringBytes = infoString.getBytes(Charset
- .forName("UTF-8"));
- return this.setInfoString(infoStringBytes);
- }
-
- /**
- * Returns the value of information string.
- *
- * @return the value of information string.
- */
- public byte[] getInfoString() {
- return Arrays.copyOf(this.infoString, this.infoString.length);
- }
-
- @Override
- public byte[] serialize() {
- if (this.type != LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
- return super.serialize();
- }
- final int valueLength = LLDPOrganizationalTLV.OUI_LENGTH
- + LLDPOrganizationalTLV.SUBTYPE_LENGTH + this.infoString.length;
- this.value = new byte[valueLength];
- final ByteBuffer bb = ByteBuffer.wrap(this.value);
- bb.put(this.oui);
- bb.put(this.subType);
- bb.put(this.infoString);
- return super.serialize();
- }
-
- @Override
- public LLDPTLV deserialize(final ByteBuffer bb) throws DeserializationException {
- super.deserialize(bb);
- if (this.getType() != LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
- return this;
- }
-
- if (this.getLength() <= OUI_LENGTH + SUBTYPE_LENGTH) {
- throw new DeserializationException(
- "TLV length is less than required for organizational TLV");
- }
-
- final ByteBuffer optionalField = ByteBuffer.wrap(this.value);
-
- final byte[] oui = new byte[LLDPOrganizationalTLV.OUI_LENGTH];
- optionalField.get(oui);
- this.setOUI(oui);
-
- this.setSubType(optionalField.get());
-
- final byte[] infoString = new byte[this.getLength()
- - LLDPOrganizationalTLV.OUI_LENGTH
- - LLDPOrganizationalTLV.SUBTYPE_LENGTH];
- optionalField.get(infoString);
- this.setInfoString(infoString);
- return this;
- }
-
- @Override
- public int hashCode() {
- final int prime = 1423;
- int result = 1;
- result = prime * result + this.type;
- result = prime * result + this.length;
- result = prime * result + Arrays.hashCode(this.oui);
- result = prime * result + this.subType;
- result = prime * result + Arrays.hashCode(this.infoString);
- return result;
- }
-
- @Override
- public boolean equals(final Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof LLDPOrganizationalTLV)) {
- return false;
- }
-
- final LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) o;
- if (this.type != other.type) {
- return false;
- }
- if (this.length != other.length) {
- return false;
- }
- if (!Arrays.equals(this.oui, other.oui)) {
- return false;
- }
- if (this.subType != other.subType) {
- return false;
- }
- if (!Arrays.equals(this.infoString, other.infoString)) {
- return false;
- }
-
- return true;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPTLV.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPTLV.java
deleted file mode 100644
index 77efe1b7..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDPTLV.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- *
- *
- */
-public class LLDPTLV {
- protected byte type;
- protected short length;
- protected byte[] value;
-
- /**
- * @return the type
- */
- public byte getType() {
- return this.type;
- }
-
- /**
- * @param type
- * the type to set
- * @return this
- */
- public LLDPTLV setType(final byte type) {
- this.type = type;
- return this;
- }
-
- /**
- * @return the length
- */
- public short getLength() {
- return this.length;
- }
-
- /**
- * @param length
- * the length to set
- * @return this
- */
- public LLDPTLV setLength(final short length) {
- this.length = length;
- return this;
- }
-
- /**
- * @return the value
- */
- public byte[] getValue() {
- return this.value;
- }
-
- /**
- * @param value
- * the value to set
- * @return this
- */
- public LLDPTLV setValue(final byte[] value) {
- this.value = value;
- return this;
- }
-
- public byte[] serialize() {
- // type = 7 bits
- // info string length 9 bits, each value == byte
- // info string
- final short scratch = (short) ((0x7f & this.type) << 9 | 0x1ff & this.length);
- final byte[] data = new byte[2 + this.length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
- bb.putShort(scratch);
- if (this.value != null) {
- bb.put(this.value);
- }
- return data;
- }
-
- public LLDPTLV deserialize(final ByteBuffer bb) throws DeserializationException {
- if (bb.remaining() < 2) {
- throw new DeserializationException(
- "Not enough bytes to deserialize TLV type and length");
- }
- short typeLength;
- typeLength = bb.getShort();
- this.type = (byte) (typeLength >> 9 & 0x7f);
- this.length = (short) (typeLength & 0x1ff);
-
- if (this.length > 0) {
- this.value = new byte[this.length];
-
- // if there is an underrun just toss the TLV
- if (bb.remaining() < this.length) {
- throw new DeserializationException(
- "Remaining bytes are less then the length of the TLV");
- }
- bb.get(this.value);
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 1423;
- int result = 1;
- result = prime * result + this.length;
- result = prime * result + this.type;
- result = prime * result + Arrays.hashCode(this.value);
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof LLDPTLV)) {
- return false;
- }
- final LLDPTLV other = (LLDPTLV) obj;
- if (this.length != other.length) {
- return false;
- }
- if (this.type != other.type) {
- return false;
- }
- if (!Arrays.equals(this.value, other.value)) {
- return false;
- }
- return true;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java
deleted file mode 100644
index 71c5803e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MPLS.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class MPLS extends BasePacket {
- public static final int HEADER_LENGTH = 4;
-
- public static final byte PROTOCOL_IPV4 = 0x1;
- public static final byte PROTOCOL_MPLS = 0x6;
- static Map<Byte, Deserializer<? extends IPacket>> protocolDeserializerMap
- = new HashMap<>();
-
- static {
- protocolDeserializerMap.put(PROTOCOL_IPV4, IPv4.deserializer());
- protocolDeserializerMap.put(PROTOCOL_MPLS, MPLS.deserializer());
- }
-
- protected int label; //20bits
- protected byte bos; //1bit
- protected byte ttl; //8bits
- protected byte protocol;
-
- /**
- * Default constructor that sets the version to 4.
- */
- public MPLS() {
- super();
- this.bos = 1;
- this.protocol = PROTOCOL_IPV4;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (payload != null) {
- payload.setParent(this);
- payloadData = payload.serialize();
- }
-
- byte[] data = new byte[(4 + ((payloadData != null) ? payloadData.length : 0)) ];
- ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt(((this.label & 0x000fffff) << 12) | ((this.bos & 0x1) << 8 | (this.ttl & 0xff)));
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- int mplsheader = bb.getInt();
- this.label = ((mplsheader & 0xfffff000) >> 12);
- this.bos = (byte) ((mplsheader & 0x00000100) >> 8);
- this.bos = (byte) (mplsheader & 0x000000ff);
- this.protocol = (this.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
-
- Deserializer<? extends IPacket> deserializer;
- if (protocolDeserializerMap.containsKey(this.protocol)) {
- deserializer = protocolDeserializerMap.get(this.protocol);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /**
- * Returns the MPLS label.
- *
- * @return MPLS label
- */
- public int getLabel() {
- return label;
- }
-
- /**
- * Sets the MPLS label.
- *
- * @param label MPLS label
- */
- public void setLabel(int label) {
- this.label = label;
- }
-
- /**
- * Returns the MPLS TTL of the packet.
- *
- * @return MPLS TTL of the packet
- */
- public byte getTtl() {
- return ttl;
- }
-
- /**
- * Sets the MPLS TTL of the packet.
- *
- * @param ttl MPLS TTL
- */
- public void setTtl(byte ttl) {
- this.ttl = ttl;
- }
-
- /**
- * Deserializer function for MPLS packets.
- *
- * @return deserializer function
- */
- public static Deserializer<MPLS> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- MPLS mpls = new MPLS();
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- int mplsheader = bb.getInt();
- mpls.label = ((mplsheader & 0xfffff000) >>> 12);
- mpls.bos = (byte) ((mplsheader & 0x00000100) >> 8);
- mpls.ttl = (byte) (mplsheader & 0x000000ff);
- mpls.protocol = (mpls.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
-
- Deserializer<? extends IPacket> deserializer;
- if (protocolDeserializerMap.containsKey(mpls.protocol)) {
- deserializer = protocolDeserializerMap.get(mpls.protocol);
- } else {
- deserializer = Data.deserializer();
- }
- mpls.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
- mpls.payload.setParent(mpls);
-
- return mpls;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MacAddress.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
deleted file mode 100644
index cb7f2013..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.util.Arrays;
-
-/**
- * The class representing MAC address.
- */
-public class MacAddress {
-
- public static final MacAddress NONE = valueOf("a4:23:05:00:00:00");
- public static final MacAddress ZERO = valueOf("00:00:00:00:00:00");
- public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff");
-
- private static final byte[] LL = new byte[]{
- 0x01, (byte) 0x80, (byte) 0xc2, 0x00, 0x00,
- 0x00, 0x0e, 0x03
- };
-
- public static final int MAC_ADDRESS_LENGTH = 6;
- private byte[] address = new byte[MacAddress.MAC_ADDRESS_LENGTH];
-
- public MacAddress(final byte[] address) {
- this.address = Arrays.copyOf(address, MacAddress.MAC_ADDRESS_LENGTH);
- }
-
- /**
- * Returns a MAC address instance representing the value of the specified
- * {@code String}.
- *
- * @param address the String representation of the MAC Address to be parsed.
- * @return a MAC Address instance representing the value of the specified
- * {@code String}.
- * @throws IllegalArgumentException if the string cannot be parsed as a MAC address.
- */
- public static MacAddress valueOf(final String address) {
- final String[] elements = address.split(":");
- if (elements.length != MacAddress.MAC_ADDRESS_LENGTH) {
- throw new IllegalArgumentException(
- "Specified MAC Address must contain 12 hex digits"
- + " separated pairwise by :'s.");
- }
-
- final byte[] addressInBytes = new byte[MacAddress.MAC_ADDRESS_LENGTH];
- for (int i = 0; i < MacAddress.MAC_ADDRESS_LENGTH; i++) {
- final String element = elements[i];
- addressInBytes[i] = (byte) Integer.parseInt(element, 16);
- }
-
- return new MacAddress(addressInBytes);
- }
-
- /**
- * Returns a MAC address instance representing the specified {@code byte}
- * array.
- *
- * @param address the byte array to be parsed.
- * @return a MAC address instance representing the specified {@code byte}
- * array.
- * @throws IllegalArgumentException if the byte array cannot be parsed as a MAC address.
- */
- public static MacAddress valueOf(final byte[] address) {
- if (address.length != MacAddress.MAC_ADDRESS_LENGTH) {
- throw new IllegalArgumentException("the length is not "
- + MacAddress.MAC_ADDRESS_LENGTH);
- }
-
- return new MacAddress(address);
- }
-
- /**
- * Returns a MAC address instance representing the specified {@code long}
- * value. The lower 48 bits of the long value are used to parse as a MAC
- * address.
- *
- * @param address the long value to be parsed. The lower 48 bits are used for a
- * MAC address.
- * @return a MAC address instance representing the specified {@code long}
- * value.
- * @throws IllegalArgumentException if the long value cannot be parsed as a MAC address.
- */
- public static MacAddress valueOf(final long address) {
- final byte[] addressInBytes = new byte[]{
- (byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff),
- (byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff),
- (byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff)};
-
- return new MacAddress(addressInBytes);
- }
-
- /**
- * Returns the length of the {@code MACAddress}.
- *
- * @return the length of the {@code MACAddress}.
- */
- public int length() {
- return this.address.length;
- }
-
- /**
- * Returns the value of the {@code MACAddress} as a {@code byte} array.
- *
- * @return the numeric value represented by this object after conversion to
- * type {@code byte} array.
- */
- public byte[] toBytes() {
- return Arrays.copyOf(this.address, this.address.length);
- }
-
- /**
- * Returns the value of the {@code MACAddress} as a {@code long}.
- *
- * @return the numeric value represented by this object after conversion to
- * type {@code long}.
- */
- public long toLong() {
- long mac = 0;
- for (int i = 0; i < 6; i++) {
- final long t = (this.address[i] & 0xffL) << (5 - i) * 8;
- mac |= t;
- }
- return mac;
- }
-
- /**
- * Returns {@code true} if the MAC address is the broadcast address.
- *
- * @return {@code true} if the MAC address is the broadcast address.
- */
- public boolean isBroadcast() {
- for (final byte b : this.address) {
- if (b != -1) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns {@code true} if the MAC address is the multicast address.
- *
- * @return {@code true} if the MAC address is the multicast address.
- */
- public boolean isMulticast() {
- if (this.isBroadcast()) {
- return false;
- }
- return (this.address[0] & 0x01) != 0;
- }
-
- /**
- * Returns true if this MAC address is link local.
- *
- * @return true if link local
- */
- public boolean isLinkLocal() {
- return LL[0] == address[0] && LL[1] == address[1] && LL[2] == address[2] &&
- LL[3] == address[3] && LL[4] == address[4] &&
- (LL[5] == address[5] || LL[6] == address[5] || LL[7] == address[5]);
- }
-
- @Override
- public boolean equals(final Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof MacAddress)) {
- return false;
- }
-
- final MacAddress other = (MacAddress) o;
- return Arrays.equals(this.address, other.address);
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(toLong());
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- for (final byte b : this.address) {
- if (builder.length() > 0) {
- builder.append(":");
- }
- builder.append(String.format("%02X", b & 0xFF));
- }
- return builder.toString();
- }
-
- /**
- * @return MAC address in string representation without colons (useful for
- * radix tree storage)
- */
- public String toStringNoColon() {
- final StringBuilder builder = new StringBuilder();
- for (final byte b : this.address) {
- builder.append(String.format("%02X", b & 0xFF));
- }
- return builder.toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java
deleted file mode 100644
index 09a939fc..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/MplsLabel.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.onlab.packet;
-
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Representation of a MPLS label.
- */
-public class MplsLabel {
-
- private final int mplsLabel;
-
- // An MPLS Label maximum 20 bits.
- public static final int MAX_MPLS = 0xFFFFF;
-
- protected MplsLabel(int value) {
- this.mplsLabel = value;
- }
-
- public static MplsLabel mplsLabel(int value) {
-
- if (value < 0 || value > MAX_MPLS) {
- String errorMsg = "MPLS label value " + value +
- " is not in the interval [0, 0xFFFFF]";
- throw new IllegalArgumentException(errorMsg);
- }
- return new MplsLabel(value);
- }
-
- public int toInt() {
- return this.mplsLabel;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof MplsLabel) {
-
- MplsLabel other = (MplsLabel) obj;
-
- if (this.mplsLabel == other.mplsLabel) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.mplsLabel;
- }
-
- @Override
- public String toString() {
- return String.valueOf(this.mplsLabel);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java
deleted file mode 100644
index 5b3902a8..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.ArrayUtils;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-
-/**
- * ONOS LLDP containing organizational TLV for ONOS device dicovery.
- */
-public class ONOSLLDP extends LLDP {
-
- public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
- public static final String DEFAULT_DEVICE = "INVALID";
- public static final String DEFAULT_NAME = "ONOS Discovery";
-
- public static final byte[] LLDP_NICIRA = {0x01, 0x23, 0x20, 0x00, 0x00,
- 0x01};
- public static final byte[] LLDP_MULTICAST = {0x01, (byte) 0x80,
- (byte) 0xc2, 0x00, 0x00, 0x0e};
- public static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
-
- private static final byte NAME_SUBTYPE = 1;
- private static final byte DEVICE_SUBTYPE = 2;
- private static final short NAME_LENGTH = 4; //1 for subtype + 3 for OUI
- private static final short DEVICE_LENGTH = 4; //1 for subtype + 3 for OUI
- private final LLDPOrganizationalTLV nameTLV = new LLDPOrganizationalTLV();
- private final LLDPOrganizationalTLV deviceTLV = new LLDPOrganizationalTLV();
-
- // TLV constants: type, size and subtype
- // Organizationally specific TLV also have packet offset and contents of TLV
- // header
- private static final byte CHASSIS_TLV_TYPE = 1;
- private static final byte CHASSIS_TLV_SIZE = 7;
- private static final byte CHASSIS_TLV_SUBTYPE = 4;
-
- private static final byte PORT_TLV_TYPE = 2;
- private static final byte PORT_TLV_SIZE = 5;
- private static final byte PORT_TLV_SUBTYPE = 2;
-
- private static final byte TTL_TLV_TYPE = 3;
-
-
- private final byte[] ttlValue = new byte[] {0, 0x78};
-
- public ONOSLLDP() {
- super();
- setName(DEFAULT_NAME);
- setDevice(DEFAULT_DEVICE);
- setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV));
- setTtl(new LLDPTLV().setType(TTL_TLV_TYPE)
- .setLength((short) ttlValue.length)
- .setValue(ttlValue));
-
- }
-
- private ONOSLLDP(LLDP lldp) {
- this.portId = lldp.getPortId();
- this.chassisId = lldp.getChassisId();
- this.ttl = lldp.getTtl();
- this.optionalTLVList = lldp.getOptionalTLVList();
- }
-
- public void setName(String name) {
- nameTLV.setLength((short) (name.length() + NAME_LENGTH));
- nameTLV.setInfoString(name);
- nameTLV.setSubType(NAME_SUBTYPE);
- nameTLV.setOUI(ONLAB_OUI);
- }
-
- public void setDevice(String device) {
- deviceTLV.setInfoString(device);
- deviceTLV.setLength((short) (device.length() + DEVICE_LENGTH));
- deviceTLV.setSubType(DEVICE_SUBTYPE);
- deviceTLV.setOUI(ONLAB_OUI);
- }
-
- public void setChassisId(final ChassisId chassisId) {
- MacAddress chassisMac = MacAddress.valueOf(chassisId.value());
- byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE},
- chassisMac.toBytes());
-
- LLDPTLV chassisTLV = new LLDPTLV();
- chassisTLV.setLength(CHASSIS_TLV_SIZE);
- chassisTLV.setType(CHASSIS_TLV_TYPE);
- chassisTLV.setValue(chassis);
- this.setChassisId(chassisTLV);
- }
-
- public void setPortId(final int portNumber) {
- byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_SUBTYPE},
- ByteBuffer.allocate(4).putInt(portNumber).array());
-
- LLDPTLV portTLV = new LLDPTLV();
- portTLV.setLength(PORT_TLV_SIZE);
- portTLV.setType(PORT_TLV_TYPE);
- portTLV.setValue(port);
- this.setPortId(portTLV);
- }
-
- public LLDPOrganizationalTLV getNameTLV() {
- for (LLDPTLV tlv : this.getOptionalTLVList()) {
- if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
- LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
- if (orgTLV.getSubType() == NAME_SUBTYPE) {
- return orgTLV;
- }
- }
- }
- return null;
- }
-
- public LLDPOrganizationalTLV getDeviceTLV() {
- for (LLDPTLV tlv : this.getOptionalTLVList()) {
- if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
- LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
- if (orgTLV.getSubType() == DEVICE_SUBTYPE) {
- return orgTLV;
- }
- }
- }
- return null;
- }
-
- public String getNameString() {
- LLDPOrganizationalTLV tlv = getNameTLV();
- if (tlv != null) {
- return new String(tlv.getInfoString(), StandardCharsets.UTF_8);
- }
- return null;
- }
-
- public String getDeviceString() {
- LLDPOrganizationalTLV tlv = getDeviceTLV();
- if (tlv != null) {
- return new String(tlv.getInfoString(), StandardCharsets.UTF_8);
- }
- return null;
- }
-
- public Integer getPort() {
- ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue());
- portBB.position(1);
- return portBB.getInt();
- }
-
- /**
- * Given an ethernet packet, determines if this is an LLDP from
- * ONOS and returns the device the LLDP came from.
- * @param eth an ethernet packet
- * @return a the lldp packet or null
- */
- public static ONOSLLDP parseONOSLLDP(Ethernet eth) {
- if (eth.getEtherType() == Ethernet.TYPE_LLDP ||
- eth.getEtherType() == Ethernet.TYPE_BSN) {
- ONOSLLDP onosLldp = new ONOSLLDP((LLDP) eth.getPayload()); //(ONOSLLDP) eth.getPayload();
- if (ONOSLLDP.DEFAULT_NAME.equals(onosLldp.getNameString())) {
- return onosLldp;
- }
- }
- return null;
- }
-
-
-
-
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java
deleted file mode 100755
index e6ef0aed..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PIM.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import org.onlab.packet.pim.PIMHello;
-import org.onlab.packet.pim.PIMJoinPrune;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements PIM control packet format.
- */
-public class PIM extends BasePacket {
-
- public static final IpAddress PIM_ADDRESS = IpAddress.valueOf("224.0.0.13");
-
- public static final byte TYPE_HELLO = 0x00;
- public static final byte TYPE_REGISTER = 0x01;
- public static final byte TYPE_REGISTER_STOP = 0x02;
- public static final byte TYPE_JOIN_PRUNE_REQUEST = 0x03;
- public static final byte TYPE_BOOTSTRAP = 0x04;
- public static final byte TYPE_ASSERT = 0x05;
- public static final byte TYPE_GRAFT = 0x06;
- public static final byte TYPE_GRAFT_ACK = 0x07;
- public static final byte TYPE_CANDIDATE_RP_ADV = 0x08;
-
- public static final int PIM_HEADER_LEN = 4;
-
- public static final byte ADDRESS_FAMILY_IP4 = 0x1;
- public static final byte ADDRESS_FAMILY_IP6 = 0x2;
-
- public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
- new HashMap<>();
-
- static {
- PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_HELLO, PIMHello.deserializer());
- PIM.PROTOCOL_DESERIALIZER_MAP.put(PIM.TYPE_JOIN_PRUNE_REQUEST, PIMJoinPrune.deserializer());
- }
-
- /*
- * PIM Header fields
- */
- protected byte version;
- protected byte type;
- protected byte reserved;
- protected short checksum;
-
- /**
- * Default constructor.
- */
- public PIM() {
- super();
- this.version = 2;
- this.reserved = 0;
- }
-
- /**
- * Return the PIM message type.
- *
- * @return the pimMsgType
- */
- public byte getPimMsgType() {
- return this.type;
- }
-
- /**
- * Set the PIM message type. Currently PIMJoinPrune and PIMHello are
- * supported.
- *
- * @param type PIM message type
- * @return PIM Header
- */
- public PIM setPIMType(final byte type) {
- this.type = type;
- return this;
- }
-
- /**
- * Get the version of PIM.
- *
- * @return the PIM version. Must be 2.
- */
- public byte getVersion() {
- return version;
- }
-
- /**
- * Set the PIM version type. Should not change from 2.
- *
- * @param version PIM version
- */
- public void setVersion(byte version) {
- this.version = version;
- }
-
- /**
- * Get the reserved field.
- *
- * @return the reserved field. Must be ignored.
- */
- public byte getReserved() {
- return reserved;
- }
-
- /**
- * Set the reserved field.
- *
- * @param reserved should be 0
- */
- public void setReserved(byte reserved) {
- this.reserved = reserved;
- }
-
- /**
- * Get the checksum of this packet.
- *
- * @return the checksum
- */
- public short getChecksum() {
- return checksum;
- }
-
- /**
- * Set the checksum.
- *
- * @param checksum the checksum
- */
- public void setChecksum(short checksum) {
- this.checksum = checksum;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.type;
- result = prime * result + this.version;
- result = prime * result + this.checksum;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof PIM)) {
- return false;
- }
- final PIM other = (PIM) obj;
- if (this.type != other.type) {
- return false;
- }
- if (this.version != other.version) {
- return false;
- }
- if (this.checksum != other.checksum) {
- return false;
- }
- return true;
- }
-
- /**
- * Serializes the packet. Will compute and set the following fields if they
- * are set to specific values at the time serialize is called: -checksum : 0
- * -length : 0
- *
- * @return will return the serialized packet
- */
- @Override
- public byte[] serialize() {
- int length = 4;
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- length += payloadData.length;
- }
-
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put((byte) ((this.version & 0xf) << 4 | this.type & 0xf));
- bb.put(this.reserved);
- bb.putShort(this.checksum);
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof PIM) {
- ((PIM) this.parent).setPIMType(TYPE_JOIN_PRUNE_REQUEST);
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bb.rewind();
- int accumulation = 0;
-
- for (int i = 0; i < length / 2; ++i) {
- accumulation += 0xffff & bb.getShort();
- }
- // pad to an even number of shorts
- if (length % 2 > 0) {
- accumulation += (bb.get() & 0xff) << 8;
- }
-
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bb.putShort(2, this.checksum);
- }
- return data;
- }
-
- /**
- * Deserialize the PIM packet.
- *
- * @param data bytes to deserialize.
- * @param offset offset to start deserializing from
- * @param length length of the data to deserialize
- *
- * @return the deserialized PIM packet.
- */
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.type = bb.get();
- this.version = bb.get();
- this.checksum = bb.getShort();
-
- //this.payload = new Data();
- this.payload = this.payload.deserialize(data, bb.position(), bb.limit() - bb.position());
- this.payload.setParent(this);
- return this;
- }
- /**
- * Deserializer function for IPv4 packets.
- *
- * @return deserializer function
- */
- public static Deserializer<PIM> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, PIM_HEADER_LEN);
-
- PIM pim = new PIM();
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- byte versionByte = bb.get();
- pim.version = (byte) (versionByte >> 4 & 0xf);
- pim.setPIMType((byte) (versionByte & 0xf));
- pim.reserved = bb.get();
- pim.checksum = bb.getShort();
-
- Deserializer<? extends IPacket> deserializer;
- if (PIM.PROTOCOL_DESERIALIZER_MAP.containsKey(pim.getPimMsgType())) {
- deserializer = PIM.PROTOCOL_DESERIALIZER_MAP.get(pim.getPimMsgType());
- } else {
- deserializer = Data.deserializer();
- }
-
- pim.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
- pim.payload.setParent(pim);
-
- return pim;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PacketUtils.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PacketUtils.java
deleted file mode 100644
index c3bede2f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/PacketUtils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Utilities for working with packet headers.
- */
-public final class PacketUtils {
-
- private PacketUtils() {
- }
-
- /**
- * Check the length of the input buffer is appropriate given the offset and
- * length parameters.
- *
- * @param byteLength length of the input buffer array
- * @param offset offset given to begin reading bytes from
- * @param length length given to read up until
- * @throws DeserializationException if the input parameters don't match up (i.e
- * we can't read that many bytes from the buffer at the given offest)
- */
- public static void checkBufferLength(int byteLength, int offset, int length)
- throws DeserializationException {
- boolean ok = (offset >= 0 && offset < byteLength);
- ok = ok & (length >= 0 && offset + length <= byteLength);
-
- if (!ok) {
- throw new DeserializationException("Unable to read " + length + " bytes from a "
- + byteLength + " byte array starting at offset " + offset);
- }
- }
-
- /**
- * Check that there are enough bytes in the buffer to read some number of
- * bytes that we need to read a full header.
- *
- * @param givenLength given size of the buffer
- * @param requiredLength number of bytes we need to read some header fully
- * @throws DeserializationException if there aren't enough bytes
- */
- public static void checkHeaderLength(int givenLength, int requiredLength)
- throws DeserializationException {
- if (requiredLength > givenLength) {
- throw new DeserializationException(requiredLength
- + " bytes are needed to continue deserialization, however only "
- + givenLength + " remain in buffer");
- }
- }
-
- /**
- * Check the input parameters are sane and there's enough bytes to read
- * the required length.
- *
- * @param data input byte buffer
- * @param offset offset of the start of the header
- * @param length length given to deserialize the header
- * @param requiredLength length needed to deserialize header
- * @throws DeserializationException if we're unable to deserialize the
- * packet based on the input parameters
- */
- public static void checkInput(byte[] data, int offset, int length, int requiredLength)
- throws DeserializationException {
- checkNotNull(data);
- checkBufferLength(data.length, offset, length);
- checkHeaderLength(length, requiredLength);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUS.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUS.java
deleted file mode 100644
index 297fee7c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUS.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- *
- * * Copyright 2015 AT&T Foundry
- * *
- * * Licensed under the Apache License, Version 2.0 (the "License");
- * * you may not use this file except in compliance with the License.
- * * You may obtain a copy of the License at
- * *
- * * http://www.apache.org/licenses/LICENSE-2.0
- * *
- * * Unless required by applicable law or agreed to in writing, software
- * * distributed under the License is distributed on an "AS IS" BASIS,
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * * See the License for the specific language governing permissions and
- * * limitations under the License.
- *
- */
-
-package org.onlab.packet;
-
-import org.slf4j.Logger;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * RADIUS packet.
- */
-public class RADIUS extends BasePacket {
- protected byte code;
- protected byte identifier;
- protected short length = RADIUS_MIN_LENGTH;
- protected byte[] authenticator = new byte[16];
- protected List<RADIUSAttribute> attributes = new ArrayList<>();
-
- // RADIUS parameters
- public static final short RADIUS_MIN_LENGTH = 20;
- public static final short MAX_ATTR_VALUE_LENGTH = 253;
- public static final short RADIUS_MAX_LENGTH = 4096;
-
- // RADIUS packet types
- public static final byte RADIUS_CODE_ACCESS_REQUEST = 0x01;
- public static final byte RADIUS_CODE_ACCESS_ACCEPT = 0x02;
- public static final byte RADIUS_CODE_ACCESS_REJECT = 0x03;
- public static final byte RADIUS_CODE_ACCOUNTING_REQUEST = 0x04;
- public static final byte RADIUS_CODE_ACCOUNTING_RESPONSE = 0x05;
- public static final byte RADIUS_CODE_ACCESS_CHALLENGE = 0x0b;
-
- private final Logger log = getLogger(getClass());
-
- /**
- * Default constructor.
- */
- public RADIUS() {
- }
-
- /**
- * Constructs a RADIUS packet with the given code and identifier.
- *
- * @param code code
- * @param identifier identifier
- */
- public RADIUS(byte code, byte identifier) {
- this.code = code;
- this.identifier = identifier;
- }
-
- /**
- * Gets the code.
- *
- * @return code
- */
- public byte getCode() {
- return this.code;
- }
-
- /**
- * Sets the code.
- *
- * @param code code
- */
- public void setCode(byte code) {
- this.code = code;
- }
-
- /**
- * Gets the identifier.
- *
- * @return identifier
- */
- public byte getIdentifier() {
- return this.identifier;
- }
-
- /**
- * Sets the identifier.
- *
- * @param identifier identifier
- */
- public void setIdentifier(byte identifier) {
- this.identifier = identifier;
- }
-
- /**
- * Gets the authenticator.
- *
- * @return authenticator
- */
- public byte[] getAuthenticator() {
- return this.authenticator;
- }
-
- /**
- * Sets the authenticator.
- *
- * @param authenticator authenticator
- */
- public void setAuthenticator(byte[] authenticator) {
- this.authenticator = authenticator;
- }
-
- /**
- * Generates an authenticator code.
- *
- * @return the authenticator
- */
- public byte[] generateAuthCode() {
- new SecureRandom().nextBytes(this.authenticator);
- return this.authenticator;
- }
-
- /**
- * Checks if the packet's code field is valid.
- *
- * @return whether the code is valid
- */
- public boolean isValidCode() {
- return this.code == RADIUS_CODE_ACCESS_REQUEST ||
- this.code == RADIUS_CODE_ACCESS_ACCEPT ||
- this.code == RADIUS_CODE_ACCESS_REJECT ||
- this.code == RADIUS_CODE_ACCOUNTING_REQUEST ||
- this.code == RADIUS_CODE_ACCOUNTING_RESPONSE ||
- this.code == RADIUS_CODE_ACCESS_CHALLENGE;
- }
-
- /**
- * Adds a message authenticator to the packet based on the given key.
- *
- * @param key key to generate message authenticator
- * @return the messgae authenticator RADIUS attribute
- */
- public RADIUSAttribute addMessageAuthenticator(String key) {
- // Message-Authenticator = HMAC-MD5 (Type, Identifier, Length,
- // Request Authenticator, Attributes)
- // When the message integrity check is calculated the signature string
- // should be considered to be sixteen octets of zero.
- byte[] hashOutput = new byte[16];
- Arrays.fill(hashOutput, (byte) 0);
-
- RADIUSAttribute authAttribute = this.getAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH);
- if (authAttribute != null) {
- // If Message-Authenticator was already present, override it
- this.log.warn("Attempted to add duplicate Message-Authenticator");
- authAttribute = this.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, hashOutput);
- } else {
- // Else generate a new attribute padded with zeroes
- authAttribute = this.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, hashOutput);
- }
- // Calculate the MD5 HMAC based on the message
- try {
- SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5");
- Mac mac = Mac.getInstance("HmacMD5");
- mac.init(keySpec);
- hashOutput = mac.doFinal(this.serialize());
- // Update HMAC in Message-Authenticator
- authAttribute = this.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, hashOutput);
- } catch (Exception e) {
- this.log.error("Failed to generate message authenticator: {}", e.getMessage());
- }
-
- return authAttribute;
- }
-
- /**
- * Checks the message authenticator in the packet with one generated from
- * the given key.
- *
- * @param key key to generate message authenticator
- * @return whether the message authenticators match or not
- */
- public boolean checkMessageAuthenticator(String key) {
- byte[] newHash = new byte[16];
- Arrays.fill(newHash, (byte) 0);
- byte[] messageAuthenticator = this.getAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH).getValue();
- this.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, newHash);
- // Calculate the MD5 HMAC based on the message
- try {
- SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5");
- Mac mac = Mac.getInstance("HmacMD5");
- mac.init(keySpec);
- newHash = mac.doFinal(this.serialize());
- } catch (Exception e) {
- log.error("Failed to generate message authenticator: {}", e.getMessage());
- }
- this.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuthenticator);
- // Compare the calculated Message-Authenticator with the one in the message
- return Arrays.equals(newHash, messageAuthenticator);
- }
-
- /**
- * Encapsulates an EAP packet in this RADIUS packet.
- *
- * @param message EAP message object to be embedded in the RADIUS
- * EAP-Message attributed
- */
- public void encapsulateMessage(EAP message) {
- if (message.length <= MAX_ATTR_VALUE_LENGTH) {
- // Use the regular serialization method as it fits into one EAP-Message attribute
- this.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
- message.serialize());
- } else {
- // Segment the message into chucks and embed them in several EAP-Message attributes
- short remainingLength = message.length;
- byte[] messageBuffer = message.serialize();
- final ByteBuffer bb = ByteBuffer.wrap(messageBuffer);
- while (bb.hasRemaining()) {
- byte[] messageAttributeData;
- if (remainingLength > MAX_ATTR_VALUE_LENGTH) {
- // The remaining data is still too long to fit into one attribute, keep going
- messageAttributeData = new byte[MAX_ATTR_VALUE_LENGTH];
- bb.get(messageAttributeData, 0, MAX_ATTR_VALUE_LENGTH);
- remainingLength -= MAX_ATTR_VALUE_LENGTH;
- } else {
- // The remaining data fits, this will be the last chunk
- messageAttributeData = new byte[remainingLength];
- bb.get(messageAttributeData, 0, remainingLength);
- }
- this.attributes.add(new RADIUSAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
- (byte) (messageAttributeData.length + 2), messageAttributeData));
-
- // Adding the size of the data to the total RADIUS length
- this.length += (short) (messageAttributeData.length & 0xFF);
- // Adding the size of the overhead attribute type and length
- this.length += 2;
- }
- }
- }
-
- /**
- * Decapsulates an EAP packet from the RADIUS packet.
- *
- * @return An EAP object containing the reassembled EAP message
- */
- public EAP decapsulateMessage() {
- EAP message = new EAP();
- ByteArrayOutputStream messageStream = new ByteArrayOutputStream();
- // Iterating through EAP-Message attributes to concatenate their value
- for (RADIUSAttribute ra : this.getAttributeList(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE)) {
- try {
- messageStream.write(ra.getValue());
- } catch (IOException e) {
- log.error("Error while reassembling EAP message: {}", e.getMessage());
- }
- }
- // Assembling EAP object from the concatenated stream
- message.deserialize(messageStream.toByteArray(), 0, messageStream.size());
- return message;
- }
-
- /**
- * Gets a list of attributes from the RADIUS packet.
- *
- * @param attrType the type field of the required attributes
- * @return List of the attributes that matches the type or an empty list if there is none
- */
- public ArrayList<RADIUSAttribute> getAttributeList(byte attrType) {
- ArrayList<RADIUSAttribute> attrList = new ArrayList<>();
- for (int i = 0; i < this.attributes.size(); i++) {
- if (this.attributes.get(i).getType() == attrType) {
- attrList.add(this.attributes.get(i));
- }
- }
- return attrList;
- }
-
- /**
- * Gets an attribute from the RADIUS packet.
- *
- * @param attrType the type field of the required attribute
- * @return the first attribute that matches the type or null if does not exist
- */
- public RADIUSAttribute getAttribute(byte attrType) {
- for (int i = 0; i < this.attributes.size(); i++) {
- if (this.attributes.get(i).getType() == attrType) {
- return this.attributes.get(i);
- }
- }
- return null;
- }
-
- /**
- * Sets an attribute in the RADIUS packet.
- *
- * @param attrType the type field of the attribute to set
- * @param value value to be set
- * @return reference to the attribute object
- */
- public RADIUSAttribute setAttribute(byte attrType, byte[] value) {
- byte attrLength = (byte) (value.length + 2);
- RADIUSAttribute newAttribute = new RADIUSAttribute(attrType, attrLength, value);
- this.attributes.add(newAttribute);
- this.length += (short) (attrLength & 0xFF);
- return newAttribute;
- }
-
- /**
- * Updates an attribute in the RADIUS packet.
- *
- * @param attrType the type field of the attribute to update
- * @param value the value to update to
- * @return reference to the attribute object
- */
- public RADIUSAttribute updateAttribute(byte attrType, byte[] value) {
- for (int i = 0; i < this.attributes.size(); i++) {
- if (this.attributes.get(i).getType() == attrType) {
- this.length -= (short) (this.attributes.get(i).getLength() & 0xFF);
- RADIUSAttribute newAttr = new RADIUSAttribute(attrType, (byte) (value.length + 2), value);
- this.attributes.set(i, newAttr);
- this.length += (short) (newAttr.getLength() & 0xFF);
- return newAttr;
- }
- }
- return null;
- }
-
- /**
- * Deserializer for RADIUS packets.
- *
- * @return deserializer
- */
- public static Deserializer<RADIUS> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, RADIUS_MIN_LENGTH);
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- RADIUS radius = new RADIUS();
- radius.code = bb.get();
- radius.identifier = bb.get();
- radius.length = bb.getShort();
- bb.get(radius.authenticator, 0, 16);
-
- checkHeaderLength(length, radius.length);
-
- int remainingLength = radius.length - RADIUS_MIN_LENGTH;
- while (remainingLength > 0 && bb.hasRemaining()) {
-
- RADIUSAttribute attr = new RADIUSAttribute();
- attr.setType(bb.get());
- attr.setLength(bb.get());
- short attrLength = (short) (attr.length & 0xff);
- attr.value = new byte[attrLength - 2];
- bb.get(attr.value, 0, attrLength - 2);
- radius.attributes.add(attr);
- remainingLength -= attr.length;
- }
- return radius;
- };
- }
-
- @Override
- public byte[] serialize() {
- final byte[] data = new byte[this.length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.code);
- bb.put(this.identifier);
- bb.putShort(this.length);
- bb.put(this.authenticator);
- for (int i = 0; i < this.attributes.size(); i++) {
- RADIUSAttribute attr = this.attributes.get(i);
- bb.put(attr.getType());
- bb.put(attr.getLength());
- bb.put(attr.getValue());
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.code = bb.get();
- this.identifier = bb.get();
- this.length = bb.getShort();
- bb.get(this.authenticator, 0, 16);
-
- int remainingLength = this.length - RADIUS_MIN_LENGTH;
- while (remainingLength > 0 && bb.hasRemaining()) {
- RADIUSAttribute attr = new RADIUSAttribute();
- attr.setType(bb.get());
- attr.setLength(bb.get());
- short attrLength = (short) (attr.length & 0xff);
- attr.value = new byte[attrLength - 2];
- bb.get(attr.value, 0, attrLength - 2);
- this.attributes.add(attr);
- remainingLength -= attr.length;
- }
- return this;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUSAttribute.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUSAttribute.java
deleted file mode 100644
index 9687e377..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/RADIUSAttribute.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- *
- * * Copyright 2015 AT&T Foundry
- * *
- * * Licensed under the Apache License, Version 2.0 (the "License");
- * * you may not use this file except in compliance with the License.
- * * You may obtain a copy of the License at
- * *
- * * http://www.apache.org/licenses/LICENSE-2.0
- * *
- * * Unless required by applicable law or agreed to in writing, software
- * * distributed under the License is distributed on an "AS IS" BASIS,
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * * See the License for the specific language governing permissions and
- * * limitations under the License.
- *
- */
-
-package org.onlab.packet;
-
-/**
- * An attribute in a RADIUS packet.
- */
-public class RADIUSAttribute {
- protected byte type;
- protected byte length;
- protected byte[] value;
-
- // RADIUS attribute types
- public static final byte RADIUS_ATTR_USERNAME = 1;
- public static final byte RADIUS_ATTR_NAS_IP = 4;
- public static final byte RADIUS_ATTR_NAS_PORT = 5;
- public static final byte RADIUS_ATTR_FRAMED_MTU = 12;
- public static final byte RADIUS_ATTR_STATE = 24;
- public static final byte RADIUS_ATTR_VENDOR_SPECIFIC = 26;
- public static final byte RADIUS_ATTR_CALLING_STATION_ID = 31;
- public static final byte RADIUS_ATTR_NAS_ID = 32;
- public static final byte RADIUS_ATTR_ACCT_SESSION_ID = 44;
- public static final byte RADIUS_ATTR_NAS_PORT_TYPE = 61;
- public static final byte RADIUS_ATTR_EAP_MESSAGE = 79;
- public static final byte RADIUS_ATTR_MESSAGE_AUTH = 80;
- public static final byte RADIUS_ATTR_NAS_PORT_ID = 87;
-
- /**
- * Default constructor.
- */
- public RADIUSAttribute() {
- }
-
- /**
- * Constructs a RADIUS attribute with the give type, length and value.
- *
- * @param type type
- * @param length length
- * @param value value
- */
- public RADIUSAttribute(final byte type, final byte length, final byte[] value) {
- this.type = type;
- this.length = length;
- this.value = value;
- }
-
- /**
- * Checks if the attribute type is valid.
- *
- * @return whether the type is valid or not
- */
- public boolean isValidType() {
- return this.type == RADIUS_ATTR_USERNAME ||
- this.type == RADIUS_ATTR_NAS_IP ||
- this.type == RADIUS_ATTR_NAS_PORT ||
- this.type == RADIUS_ATTR_VENDOR_SPECIFIC ||
- this.type == RADIUS_ATTR_CALLING_STATION_ID ||
- this.type == RADIUS_ATTR_NAS_ID ||
- this.type == RADIUS_ATTR_ACCT_SESSION_ID ||
- this.type == RADIUS_ATTR_NAS_PORT_TYPE ||
- this.type == RADIUS_ATTR_EAP_MESSAGE ||
- this.type == RADIUS_ATTR_MESSAGE_AUTH ||
- this.type == RADIUS_ATTR_NAS_PORT_ID;
- }
-
- /**
- * Gets the attribute type.
- *
- * @return the type
- */
- public byte getType() {
- return this.type;
- }
-
- /**
- * Sets the attribute type.
- *
- * @param type the code to set
- * @return this
- */
- public RADIUSAttribute setType(final byte type) {
- this.type = type;
- return this;
- }
-
- /**
- * Gets the attribute length.
- *
- * @return the length
- */
- public byte getLength() {
- return this.length;
- }
-
- /**
- * Sets the attribute length.
- *
- * @param length the length to set
- * @return this
- */
- public RADIUSAttribute setLength(final byte length) {
- this.length = length;
- return this;
- }
-
- /**
- * Gets the attribute value.
- *
- * @return the value
- */
- public byte[] getValue() {
- return this.value;
- }
-
- /**
- * Sets the attribute value.
- *
- * @param value the data to set
- * @return this
- */
- public RADIUSAttribute setValue(final byte[] value) {
- this.value = value;
- return this;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TCP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TCP.java
deleted file mode 100644
index e089f272..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TCP.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- * Implements TCP packet format.
- */
-
-public class TCP extends BasePacket {
-
- private static final short TCP_HEADER_LENGTH = 20;
-
- protected int sourcePort;
- protected int destinationPort;
- protected int sequence;
- protected int acknowledge;
- protected byte dataOffset;
- protected short flags;
- protected short windowSize;
- protected short checksum;
- protected short urgentPointer;
- protected byte[] options;
-
- /**
- * Gets TCP source port.
- *
- * @return TCP source port
- */
- public int getSourcePort() {
- return this.sourcePort;
- }
-
- /**
- * Sets TCP source port.
- *
- * @param sourcePort the sourcePort to set (unsigned 16 bits integer)
- * @return this
- */
- public TCP setSourcePort(final int sourcePort) {
- this.sourcePort = sourcePort;
- return this;
- }
-
- /**
- * Gets TCP destination port.
- *
- * @return the destinationPort
- */
- public int getDestinationPort() {
- return this.destinationPort;
- }
-
- /**
- * Sets TCP destination port.
- *
- * @param destinationPort the destinationPort to set (unsigned 16 bits integer)
- * @return this
- */
- public TCP setDestinationPort(final int destinationPort) {
- this.destinationPort = destinationPort;
- return this;
- }
-
- /**
- * Gets checksum.
- *
- * @return the checksum
- */
- public short getChecksum() {
- return this.checksum;
- }
-
- /**
- * Sets checksum.
- *
- * @param checksum the checksum to set
- * @return this
- */
- public TCP setChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
- /**
- * Gets sequence number.
- *
- * @return the sequence number
- */
- public int getSequence() {
- return this.sequence;
- }
-
- /**
- * Sets sequence number.
- *
- * @param seq the sequence number to set
- * @return this
- */
- public TCP setSequence(final int seq) {
- this.sequence = seq;
- return this;
- }
-
- /**
- * Gets acknowledge number.
- *
- * @return the acknowledge number
- */
- public int getAcknowledge() {
- return this.acknowledge;
- }
-
- /**
- * Sets acknowledge number.
- *
- * @param ack the acknowledge number to set
- * @return this
- */
- public TCP setAcknowledge(final int ack) {
- this.acknowledge = ack;
- return this;
- }
-
- /**
- * Gets offset.
- *
- * @return the offset
- */
- public byte getDataOffset() {
- return this.dataOffset;
- }
-
- /**
- * Sets offset.
- *
- * @param offset the offset to set
- * @return this
- */
- public TCP setDataOffset(final byte offset) {
- this.dataOffset = offset;
- return this;
- }
-
- /**
- * Gets TCP flags.
- *
- * @return the TCP flags
- */
- public short getFlags() {
- return this.flags;
- }
-
- /**
- * Sets TCP flags.
- *
- * @param flags the TCP flags to set
- * @return this
- */
- public TCP setFlags(final short flags) {
- this.flags = flags;
- return this;
- }
-
- /**
- * Gets TCP window size.
- *
- * @return the TCP window size
- */
- public short getWindowSize() {
- return this.windowSize;
- }
-
- /**
- * Sets TCP window size.
- *
- * @param windowSize the TCP window size to set
- * @return this
- */
- public TCP setWindowSize(final short windowSize) {
- this.windowSize = windowSize;
- return this;
- }
-
- @Override
- public void resetChecksum() {
- this.checksum = 0;
- super.resetChecksum();
- }
-
- /**
- * Gets urgent pointer.
- *
- * @return the urgent pointer
- */
- public short getUrgentPointer() {
- return this.urgentPointer;
- }
-
- /**
- * Sets urgent pointer.
- *
- * @param urgentPointer the urgent pointer to set
- * @return this
- */
- public TCP setUrgentPointer(final short urgentPointer) {
- this.urgentPointer = urgentPointer;
- return this;
- }
-
- /**
- * Gets TCP options.
- *
- * @return the TCP options
- */
- public byte[] getOptions() {
- return this.options;
- }
-
- /**
- * Sets TCP options.
- *
- * @param options the options to set
- * @return this
- */
- public TCP setOptions(final byte[] options) {
- this.options = options;
- this.dataOffset = (byte) (20 + options.length + 3 >> 2);
- return this;
- }
-
- /**
- * Serializes the packet. Will compute and set the following fields if they
- * are set to specific values at the time serialize is called: -checksum : 0
- * -length : 0
- */
- @Override
- public byte[] serialize() {
- int length;
- if (this.dataOffset == 0) {
- this.dataOffset = 5; // default header length
- }
- length = this.dataOffset << 2;
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- length += payloadData.length;
- }
-
- final byte[] data = new byte[length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putShort((short) (this.sourcePort & 0xffff));
- bb.putShort((short) (this.destinationPort & 0xffff));
- bb.putInt(this.sequence);
- bb.putInt(this.acknowledge);
- bb.putShort((short) (this.flags | this.dataOffset << 12));
- bb.putShort(this.windowSize);
- bb.putShort(this.checksum);
- bb.putShort(this.urgentPointer);
- if (this.dataOffset > 5) {
- int padding;
- bb.put(this.options);
- padding = (this.dataOffset << 2) - 20 - this.options.length;
- for (int i = 0; i < padding; i++) {
- bb.put((byte) 0);
- }
- }
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IPv4) {
- ((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_TCP);
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bb.rewind();
- int accumulation = 0;
-
- // compute pseudo header mac
- if (this.parent != null) {
- if (this.parent instanceof IPv4) {
- final IPv4 ipv4 = (IPv4) this.parent;
- accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
- + (ipv4.getSourceAddress() & 0xffff);
- accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
- + (ipv4.getDestinationAddress() & 0xffff);
- accumulation += ipv4.getProtocol() & 0xff;
- accumulation += length & 0xffff;
- } else if (this.parent instanceof IPv6) {
- final IPv6 ipv6 = (IPv6) this.parent;
- final int bbLength =
- Ip6Address.BYTE_LENGTH * 2 // IPv6 src, dst
- + 2 // nextHeader (with padding)
- + 4; // length
- final ByteBuffer bbChecksum = ByteBuffer.allocate(bbLength);
- bbChecksum.put(ipv6.getSourceAddress());
- bbChecksum.put(ipv6.getDestinationAddress());
- bbChecksum.put((byte) 0); // padding
- bbChecksum.put(ipv6.getNextHeader());
- bbChecksum.putInt(length);
- bbChecksum.rewind();
- for (int i = 0; i < bbLength / 2; ++i) {
- accumulation += 0xffff & bbChecksum.getShort();
- }
- }
- }
-
- for (int i = 0; i < length / 2; ++i) {
- accumulation += 0xffff & bb.getShort();
- }
- // pad to an even number of shorts
- if (length % 2 > 0) {
- accumulation += (bb.get() & 0xff) << 8;
- }
-
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bb.putShort(16, this.checksum);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.sourcePort = (bb.getShort() & 0xffff);
- this.destinationPort = (bb.getShort() & 0xffff);
- this.sequence = bb.getInt();
- this.acknowledge = bb.getInt();
- this.flags = bb.getShort();
- this.dataOffset = (byte) (this.flags >> 12 & 0xf);
- this.flags = (short) (this.flags & 0x1ff);
- this.windowSize = bb.getShort();
- this.checksum = bb.getShort();
- this.urgentPointer = bb.getShort();
- if (this.dataOffset > 5) {
- int optLength = (this.dataOffset << 2) - 20;
- if (bb.limit() < bb.position() + optLength) {
- optLength = bb.limit() - bb.position();
- }
- try {
- this.options = new byte[optLength];
- bb.get(this.options, 0, optLength);
- } catch (final IndexOutOfBoundsException e) {
- this.options = null;
- }
- }
-
- this.payload = new Data();
- this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- - bb.position());
- this.payload.setParent(this);
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.checksum;
- result = prime * result + this.destinationPort;
- result = prime * result + this.sourcePort;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof TCP)) {
- return false;
- }
- final TCP other = (TCP) obj;
- // May want to compare fields based on the flags set
- return this.checksum == other.checksum
- && this.destinationPort == other.destinationPort
- && this.sourcePort == other.sourcePort
- && this.sequence == other.sequence
- && this.acknowledge == other.acknowledge
- && this.dataOffset == other.dataOffset
- && this.flags == other.flags
- && this.windowSize == other.windowSize
- && this.urgentPointer == other.urgentPointer
- && (this.dataOffset == 5 || Arrays.equals(this.options, other.options));
- }
-
- /**
- * Deserializer function for TCP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<TCP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, TCP_HEADER_LENGTH);
-
- TCP tcp = new TCP();
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- tcp.sourcePort = (bb.getShort() & 0xffff);
- tcp.destinationPort = (bb.getShort() & 0xffff);
- tcp.sequence = bb.getInt();
- tcp.acknowledge = bb.getInt();
- tcp.flags = bb.getShort();
- tcp.dataOffset = (byte) (tcp.flags >> 12 & 0xf);
- tcp.flags = (short) (tcp.flags & 0x1ff);
- tcp.windowSize = bb.getShort();
- tcp.checksum = bb.getShort();
- tcp.urgentPointer = bb.getShort();
- if (tcp.dataOffset > 5) {
- int optLength = (tcp.dataOffset << 2) - 20;
- checkHeaderLength(length, TCP_HEADER_LENGTH + tcp.dataOffset);
- tcp.options = new byte[optLength];
- bb.get(tcp.options, 0, optLength);
- }
-
- tcp.payload = Data.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
- tcp.payload.setParent(tcp);
- return tcp;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TpPort.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TpPort.java
deleted file mode 100644
index 9b86a816..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/TpPort.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.onlab.packet;
-
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Representation of a transport layer port.
- */
-public class TpPort {
-
- private final int port;
-
- // Transport layer port is unsigned 16 bits integer.
- public static final int MAX_PORT = 0xFFFF;
- public static final int MIN_PORT = 0;
-
- /**
- * Constructs a new TpPort.
- *
- * @param value the transport layer port
- */
- protected TpPort(int value) {
- this.port = value;
- }
-
- /**
- * Converts an integer into a TpPort.
- *
- * @param value an integer representing the transport layer port
- * @return a TpPort
- * @throws IllegalArgumentException if the value is invalid
- */
- public static TpPort tpPort(int value) {
- if (value < MIN_PORT || value > MAX_PORT) {
- throw new IllegalArgumentException(
- "Transport layer port value " + value + "is not in the interval [0, 0xFFFF]");
- }
- return new TpPort(value);
- }
-
- /**
- * Returns the integer value for this transport port.
- *
- * @return an integer value
- */
- public int toInt() {
- return this.port;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof TpPort) {
-
- TpPort other = (TpPort) obj;
-
- if (this.port == other.port) {
- return true;
- }
- }
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return this.port;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return String.valueOf(this.port);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/UDP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/UDP.java
deleted file mode 100644
index a30c9a92..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/UDP.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.*;
-
-/**
- * Representation of a UDP packet.
- */
-public class UDP extends BasePacket {
- public static final Map<Integer, Deserializer<? extends IPacket>> PORT_DESERIALIZER_MAP =
- new HashMap<>();
- public static final int DHCP_SERVER_PORT = 67;
- public static final int DHCP_CLIENT_PORT = 68;
-
- private static final short UDP_HEADER_LENGTH = 8;
-
- static {
- /*
- * Disable DHCP until the deserialize code is hardened to deal with
- * garbage input
- */
- UDP.PORT_DESERIALIZER_MAP.put(UDP.DHCP_SERVER_PORT, DHCP.deserializer());
- UDP.PORT_DESERIALIZER_MAP.put(UDP.DHCP_CLIENT_PORT, DHCP.deserializer());
-
- }
-
- protected int sourcePort;
- protected int destinationPort;
- protected short length;
- protected short checksum;
-
- /**
- * @return the sourcePort
- */
- public int getSourcePort() {
- return this.sourcePort;
- }
-
- /**
- * @param sourcePort
- * the sourcePort to set (16 bits unsigned integer)
- * @return this
- */
- public UDP setSourcePort(final int sourcePort) {
- this.sourcePort = sourcePort;
- return this;
- }
-
- /**
- * @return the destinationPort
- */
- public int getDestinationPort() {
- return this.destinationPort;
- }
-
- /**
- * @param destinationPort
- * the destinationPort to set (16 bits unsigned integer)
- * @return this
- */
- public UDP setDestinationPort(final int destinationPort) {
- this.destinationPort = destinationPort;
- return this;
- }
-
- /**
- * @return the length
- */
- public short getLength() {
- return this.length;
- }
-
- /**
- * @return the checksum
- */
- public short getChecksum() {
- return this.checksum;
- }
-
- /**
- * @param checksum
- * the checksum to set
- * @return this
- */
- public UDP setChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
- @Override
- public void resetChecksum() {
- this.checksum = 0;
- super.resetChecksum();
- }
-
- /**
- * Serializes the packet. Will compute and set the following fields if they
- * are set to specific values at the time serialize is called: -checksum : 0
- * -length : 0
- */
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- this.length = (short) (8 + (payloadData == null ? 0
- : payloadData.length));
-
- final byte[] data = new byte[this.length];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putShort((short) (this.sourcePort & 0xffff));
- bb.putShort((short) (this.destinationPort & 0xffff));
- bb.putShort(this.length);
- bb.putShort(this.checksum);
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IPv4) {
- ((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_UDP);
- }
-
- // compute checksum if needed
- if (this.checksum == 0) {
- bb.rewind();
- int accumulation = 0;
-
- // compute pseudo header mac
- if (this.parent != null) {
- if (this.parent instanceof IPv4) {
- final IPv4 ipv4 = (IPv4) this.parent;
- accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
- + (ipv4.getSourceAddress() & 0xffff);
- accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
- + (ipv4.getDestinationAddress() & 0xffff);
- accumulation += ipv4.getProtocol() & 0xff;
- accumulation += length & 0xffff;
- } else if (this.parent instanceof IPv6) {
- final IPv6 ipv6 = (IPv6) this.parent;
- final int bbLength =
- Ip6Address.BYTE_LENGTH * 2 // IPv6 src, dst
- + 2 // nextHeader (with padding)
- + 4; // length
- final ByteBuffer bbChecksum = ByteBuffer.allocate(bbLength);
- bbChecksum.put(ipv6.getSourceAddress());
- bbChecksum.put(ipv6.getDestinationAddress());
- bbChecksum.put((byte) 0); // padding
- bbChecksum.put(ipv6.getNextHeader());
- bbChecksum.putInt(length);
- bbChecksum.rewind();
- for (int i = 0; i < bbLength / 2; ++i) {
- accumulation += 0xffff & bbChecksum.getShort();
- }
- }
- }
-
- for (int i = 0; i < this.length / 2; ++i) {
- accumulation += 0xffff & bb.getShort();
- }
- // pad to an even number of shorts
- if (this.length % 2 > 0) {
- accumulation += (bb.get() & 0xff) << 8;
- }
-
- accumulation = (accumulation >> 16 & 0xffff)
- + (accumulation & 0xffff);
- this.checksum = (short) (~accumulation & 0xffff);
- bb.putShort(6, this.checksum);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.sourcePort = (bb.getShort() & 0xffff);
- this.destinationPort = (bb.getShort() & 0xffff);
- this.length = bb.getShort();
- this.checksum = bb.getShort();
-
- Deserializer<? extends IPacket> deserializer;
- if (UDP.PORT_DESERIALIZER_MAP.containsKey(this.destinationPort)) {
- deserializer = UDP.PORT_DESERIALIZER_MAP.get(this.destinationPort);
- } else if (UDP.PORT_DESERIALIZER_MAP.containsKey(this.sourcePort)) {
- deserializer = UDP.PORT_DESERIALIZER_MAP.get(this.sourcePort);
- } else {
- deserializer = Data.deserializer();
- }
-
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.checksum;
- result = prime * result + this.destinationPort;
- result = prime * result + this.length;
- result = prime * result + this.sourcePort;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof UDP)) {
- return false;
- }
- final UDP other = (UDP) obj;
- if (this.checksum != other.checksum) {
- return false;
- }
- if (this.destinationPort != other.destinationPort) {
- return false;
- }
- if (this.length != other.length) {
- return false;
- }
- if (this.sourcePort != other.sourcePort) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for UDP packets.
- *
- * @return deserializer function
- */
- public static Deserializer<UDP> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, UDP_HEADER_LENGTH);
-
- UDP udp = new UDP();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- udp.sourcePort = (bb.getShort() & 0xffff);
- udp.destinationPort = (bb.getShort() & 0xffff);
- udp.length = bb.getShort();
- udp.checksum = bb.getShort();
-
- Deserializer<? extends IPacket> deserializer;
- if (UDP.PORT_DESERIALIZER_MAP.containsKey(udp.destinationPort)) {
- deserializer = UDP.PORT_DESERIALIZER_MAP.get(udp.destinationPort);
- } else if (UDP.PORT_DESERIALIZER_MAP.containsKey(udp.sourcePort)) {
- deserializer = UDP.PORT_DESERIALIZER_MAP.get(udp.sourcePort);
- } else {
- deserializer = Data.deserializer();
- }
-
- udp.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- udp.payload.setParent(udp);
- return udp;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/VlanId.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/VlanId.java
deleted file mode 100644
index 4b38308b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/VlanId.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-/**
- * Representation of a VLAN ID.
- */
-public class VlanId {
-
- private final short value;
-
- // Based on convention used elsewhere? Check and change if needed
- public static final short UNTAGGED = (short) 0xffff;
-
- // In a traffic selector, this means that a VLAN ID must be present, but
- // can have any value. We use the same value as OpenFlow, but this is not
- // required.
- public static final short ANY_VALUE = (short) 0x1000;
-
- public static final VlanId NONE = VlanId.vlanId(UNTAGGED);
- public static final VlanId ANY = VlanId.vlanId(ANY_VALUE);
-
- // A VLAN ID is actually 12 bits of a VLAN tag.
- public static final short MAX_VLAN = 4095;
-
- protected VlanId() {
- this.value = UNTAGGED;
- }
-
- protected VlanId(short value) {
- this.value = value;
- }
-
- public static VlanId vlanId() {
- return new VlanId(UNTAGGED);
- }
-
- public static VlanId vlanId(short value) {
- if (value == UNTAGGED) {
- return new VlanId();
- }
-
- if (value == ANY_VALUE) {
- return new VlanId(ANY_VALUE);
- }
-
- if (value > MAX_VLAN) {
- throw new IllegalArgumentException(
- "value exceeds allowed maximum VLAN ID value (4095)");
- }
- return new VlanId(value);
- }
-
- public short toShort() {
- return this.value;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof VlanId) {
-
- VlanId other = (VlanId) obj;
-
- if (this.value == other.value) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.value;
- }
-
- @Override
- public String toString() {
- if (this.value == ANY_VALUE) {
- return "Any";
- }
- return String.valueOf(this.value);
- }
-}
-
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java
deleted file mode 100644
index ec04a812..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IPv6;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements IPv6 authentication extension header format. (RFC 4302)
- */
-public class Authentication extends BasePacket implements IExtensionHeader {
- public static final byte FIXED_HEADER_LENGTH = 12; // bytes
- public static final byte LENGTH_UNIT = 4; // bytes per unit
- public static final byte MINUS = 2;
-
- protected byte nextHeader;
- protected byte payloadLength;
- protected int securityParamIndex;
- protected int sequence;
- protected byte[] integrityCheck;
-
- @Override
- public byte getNextHeader() {
- return this.nextHeader;
- }
-
- @Override
- public Authentication setNextHeader(final byte nextHeader) {
- this.nextHeader = nextHeader;
- return this;
- }
-
- /**
- * Gets the payload length of this header.
- *
- * @return the payload length
- */
- public byte getPayloadLength() {
- return this.payloadLength;
- }
-
- /**
- * Sets the payload length of this header.
- *
- * @param payloadLength the payload length to set
- * @return this
- */
- public Authentication setPayloadLength(final byte payloadLength) {
- this.payloadLength = payloadLength;
- return this;
- }
-
- /**
- * Gets the security parameter index of this header.
- *
- * @return the security parameter index
- */
- public int getSecurityParamIndex() {
- return this.securityParamIndex;
- }
-
- /**
- * Sets the security parameter index of this header.
- *
- * @param securityParamIndex the security parameter index to set
- * @return this
- */
- public Authentication setSecurityParamIndex(final int securityParamIndex) {
- this.securityParamIndex = securityParamIndex;
- return this;
- }
-
- /**
- * Gets the sequence number of this header.
- *
- * @return the sequence number
- */
- public int getSequence() {
- return this.sequence;
- }
-
- /**
- * Sets the sequence number of this header.
- *
- * @param sequence the sequence number to set
- * @return this
- */
- public Authentication setSequence(final int sequence) {
- this.sequence = sequence;
- return this;
- }
-
- /**
- * Gets the integrity check value of this header.
- *
- * @return the integrity check value
- */
- public byte[] getIntegrityCheck() {
- return this.integrityCheck;
- }
-
- /**
- * Sets the integrity check value of this header.
- *
- * @param integrityCheck the integrity check value to set
- * @return this
- */
- public Authentication setIngegrityCheck(final byte[] integrityCheck) {
- this.integrityCheck =
- Arrays.copyOfRange(integrityCheck, 0, integrityCheck.length);
- return this;
- }
-
- /**
- * Gets the total length of this header.
- * According to spec, payload length should be the total length of this AH
- * in 4-octet unit, minus 2
- *
- * @return the total length
- */
- public int getTotalLength() {
- return (this.payloadLength + MINUS) * LENGTH_UNIT;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int headerLength = FIXED_HEADER_LENGTH + integrityCheck.length;
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[headerLength + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.nextHeader);
- bb.put(this.payloadLength);
- bb.putShort((short) 0);
- bb.putInt(this.securityParamIndex);
- bb.putInt(this.sequence);
- bb.put(this.integrityCheck, 0, integrityCheck.length);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_AH);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.nextHeader = bb.get();
- this.payloadLength = bb.get();
- bb.getShort();
- this.securityParamIndex = bb.getInt();
- this.sequence = bb.getInt();
- int icvLength = getTotalLength() - FIXED_HEADER_LENGTH;
- this.integrityCheck = new byte[icvLength];
- bb.get(this.integrityCheck, 0, icvLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
-
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.nextHeader;
- result = prime * result + this.payloadLength;
- result = prime * result + this.securityParamIndex;
- result = prime * result + this.sequence;
- for (byte b : this.integrityCheck) {
- result = prime * result + b;
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Authentication)) {
- return false;
- }
- final Authentication other = (Authentication) obj;
- if (this.nextHeader != other.nextHeader) {
- return false;
- }
- if (this.payloadLength != other.payloadLength) {
- return false;
- }
- if (this.securityParamIndex != other.securityParamIndex) {
- return false;
- }
- if (this.sequence != other.sequence) {
- return false;
- }
- if (!Arrays.equals(this.integrityCheck, other.integrityCheck)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for authentication headers.
- *
- * @return deserializer function
- */
- public static Deserializer<Authentication> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, FIXED_HEADER_LENGTH);
-
- Authentication authentication = new Authentication();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- authentication.nextHeader = bb.get();
- authentication.payloadLength = bb.get();
- bb.getShort();
- authentication.securityParamIndex = bb.getInt();
- authentication.sequence = bb.getInt();
- int icvLength = (authentication.payloadLength + MINUS) * LENGTH_UNIT - FIXED_HEADER_LENGTH;
- authentication.integrityCheck = new byte[icvLength];
- bb.get(authentication.integrityCheck, 0, icvLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(authentication.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(authentication.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- authentication.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- authentication.payload.setParent(authentication);
-
- return authentication;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java
deleted file mode 100644
index f57b756e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IPv6;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Base class for hop-by-hop options and destination options.
- */
-public class BaseOptions extends BasePacket implements IExtensionHeader {
- public static final byte FIXED_HEADER_LENGTH = 2; // bytes
- public static final byte FIXED_OPTIONS_LENGTH = 6; // bytes
- public static final byte LENGTH_UNIT = 8; // bytes per unit
-
- protected byte nextHeader;
- protected byte headerExtLength;
- protected byte[] options;
- protected byte type;
-
- @Override
- public byte getNextHeader() {
- return this.nextHeader;
- }
-
- @Override
- public BaseOptions setNextHeader(final byte nextHeader) {
- this.nextHeader = nextHeader;
- return this;
- }
-
- /**
- * Gets the extension length of this header.
- *
- * @return header length
- */
- public byte getHeaderExtLength() {
- return this.headerExtLength;
- }
-
- /**
- * Sets the extension length of this header.
- *
- * @param headerExtLength the header length to set
- * @return this
- */
- public BaseOptions setHeaderExtLength(final byte headerExtLength) {
- this.headerExtLength = headerExtLength;
- return this;
- }
-
- /**
- * Gets the options.
- *
- * @return the options
- */
- public byte[] getOptions() {
- return this.options;
- }
-
- /**
- * Sets the options.
- *
- * @param options the options to set
- * @return this
- */
- public BaseOptions setOptions(final byte[] options) {
- this.options =
- Arrays.copyOfRange(options, 0, options.length);
- return this;
- }
-
- /**
- * Gets the type of this option.
- *
- * @return the type
- */
- protected byte getType() {
- return this.type;
- }
-
- /**
- * Sets the type of this option.
- * Must be either IPv6.PROTOCOL_HOPOPT or IPv6.PROTOCOL_DSTOPT
- *
- * @param type the type to set
- * @return this
- */
- protected BaseOptions setType(final byte type) {
- this.type = type;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int headerLength = FIXED_HEADER_LENGTH + options.length;
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[headerLength + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.nextHeader);
- bb.put(this.headerExtLength);
- bb.put(this.options, 0, options.length);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(this.type);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.nextHeader = bb.get();
- this.headerExtLength = bb.get();
- int optionLength =
- FIXED_OPTIONS_LENGTH + LENGTH_UNIT * this.headerExtLength;
- this.options = new byte[optionLength];
- bb.get(this.options, 0, optionLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.nextHeader;
- result = prime * result + this.headerExtLength;
- for (byte b : this.options) {
- result = prime * result + b;
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof BaseOptions)) {
- return false;
- }
- final BaseOptions other = (BaseOptions) obj;
- if (this.nextHeader != other.nextHeader) {
- return false;
- }
- if (this.headerExtLength != other.headerExtLength) {
- return false;
- }
- if (!Arrays.equals(this.options, other.options)) {
- return false;
- }
- if (this.type != other.type) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for IPv6 base options.
- *
- * @return deserializer function
- */
- public static Deserializer<BaseOptions> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, FIXED_HEADER_LENGTH);
-
- BaseOptions baseOptions = new BaseOptions();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- baseOptions.nextHeader = bb.get();
- baseOptions.headerExtLength = bb.get();
- int optionLength =
- FIXED_OPTIONS_LENGTH + LENGTH_UNIT * baseOptions.headerExtLength;
-
- checkHeaderLength(bb.remaining(), optionLength);
-
- baseOptions.options = new byte[optionLength];
- bb.get(baseOptions.options, 0, optionLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(baseOptions.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(baseOptions.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- baseOptions.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- baseOptions.payload.setParent(baseOptions);
-
- return baseOptions;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/DestinationOptions.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/DestinationOptions.java
deleted file mode 100644
index 208bdd7e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/DestinationOptions.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.IPv6;
-
-/**
- * Implements IPv6 Destination Options extension header format. (RFC 2460)
- */
-public class DestinationOptions extends BaseOptions {
- public DestinationOptions() {
- super();
- this.setType(IPv6.PROTOCOL_DSTOPT);
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java
deleted file mode 100644
index e46a1261..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Data;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IPv6;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements IPv6 Encapsulating Security Payload (ESP) extension header format.
- * (RFC 4303)
- */
-public class EncapSecurityPayload extends BasePacket {
- public static final byte HEADER_LENGTH = 8; // bytes
-
- protected int securityParamIndex;
- protected int sequence;
- //
- // NOTE: The remaining fields including payload data, padding length and
- // next header are encrypted and all considered as a payload of ESP.
- //
-
- /**
- * Gets the security parameter index of this header.
- *
- * @return the security parameter index
- */
- public int getSecurityParamIndex() {
- return this.securityParamIndex;
- }
-
- /**
- * Sets the security parameter index of this header.
- *
- * @param securityParamIndex the security parameter index to set
- * @return this
- */
- public EncapSecurityPayload setSecurityParamIndex(final int securityParamIndex) {
- this.securityParamIndex = securityParamIndex;
- return this;
- }
-
- /**
- * Gets the sequence number of this header.
- *
- * @return the sequence number
- */
- public int getSequence() {
- return this.sequence;
- }
-
- /**
- * Sets the sequence number of this header.
- *
- * @param sequence the sequence number to set
- * @return this
- */
- public EncapSecurityPayload setSequence(final int sequence) {
- this.sequence = sequence;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt(this.securityParamIndex);
- bb.putInt(this.sequence);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ESP);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.securityParamIndex = bb.getInt();
- this.sequence = bb.getInt();
-
- this.payload = new Data();
- this.payload.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.securityParamIndex;
- result = prime * result + this.sequence;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof EncapSecurityPayload)) {
- return false;
- }
- final EncapSecurityPayload other = (EncapSecurityPayload) obj;
- if (this.securityParamIndex != other.securityParamIndex) {
- return false;
- }
- if (this.sequence != other.sequence) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for encapsulated security payload headers.
- *
- * @return deserializer function
- */
- public static Deserializer<EncapSecurityPayload> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- EncapSecurityPayload encapSecurityPayload = new EncapSecurityPayload();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- encapSecurityPayload.securityParamIndex = bb.getInt();
- encapSecurityPayload.sequence = bb.getInt();
-
- encapSecurityPayload.payload = Data.deserializer().deserialize(
- data, bb.position(), bb.limit() - bb.position());
- encapSecurityPayload.payload.setParent(encapSecurityPayload);
-
- return encapSecurityPayload;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java
deleted file mode 100644
index 68015d31..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IPv6;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements IPv6 fragment extension header format. (RFC 2460)
- */
-public class Fragment extends BasePacket implements IExtensionHeader {
- public static final byte HEADER_LENGTH = 8; // bytes
-
- protected byte nextHeader;
- protected short fragmentOffset;
- protected byte moreFragment;
- protected int identification;
-
- @Override
- public byte getNextHeader() {
- return this.nextHeader;
- }
-
- @Override
- public Fragment setNextHeader(final byte nextHeader) {
- this.nextHeader = nextHeader;
- return this;
- }
-
- /**
- * Gets the fragment offset of this header.
- *
- * @return fragment offset
- */
- public short getFragmentOffset() {
- return this.fragmentOffset;
- }
-
- /**
- * Sets the fragment offset of this header.
- *
- * @param fragmentOffset the fragment offset to set
- * @return this
- */
- public Fragment setFragmentOffset(final short fragmentOffset) {
- this.fragmentOffset = fragmentOffset;
- return this;
- }
-
- /**
- * Gets the more fragment flag of this header.
- *
- * @return more fragment flag
- */
- public byte getMoreFragment() {
- return this.moreFragment;
- }
-
- /**
- * Sets the more fragment flag of this header.
- *
- * @param moreFragment the more fragment flag to set
- * @return this
- */
- public Fragment setMoreFragment(final byte moreFragment) {
- this.moreFragment = moreFragment;
- return this;
- }
-
- /**
- * Gets the identification of this header.
- *
- * @return identification
- */
- public int getIdentification() {
- return this.identification;
- }
-
- /**
- * Sets the identification of this header.
- *
- * @param identification the identification to set
- * @return this
- */
- public Fragment setIdentification(final int identification) {
- this.identification = identification;
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.nextHeader);
- bb.put((byte) 0);
- bb.putShort((short) (
- (this.fragmentOffset & 0x1fff) << 3 |
- this.moreFragment & 0x1
- ));
- bb.putInt(this.identification);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_FRAG);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.nextHeader = bb.get();
- bb.get();
- short sscratch = bb.getShort();
- this.fragmentOffset = (short) (sscratch >> 3 & 0x1fff);
- this.moreFragment = (byte) (sscratch & 0x1);
- this.identification = bb.getInt();
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.nextHeader;
- result = prime * result + this.fragmentOffset;
- result = prime * result + this.moreFragment;
- result = prime * result + this.identification;
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Fragment)) {
- return false;
- }
- final Fragment other = (Fragment) obj;
- if (this.nextHeader != other.nextHeader) {
- return false;
- }
- if (this.fragmentOffset != other.fragmentOffset) {
- return false;
- }
- if (this.moreFragment != other.moreFragment) {
- return false;
- }
- if (this.identification != other.identification) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for fragment headers.
- *
- * @return deserializer function
- */
- public static Deserializer<Fragment> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- Fragment fragment = new Fragment();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- fragment.nextHeader = bb.get();
- bb.get();
- short sscratch = bb.getShort();
- fragment.fragmentOffset = (short) (sscratch >> 3 & 0x1fff);
- fragment.moreFragment = (byte) (sscratch & 0x1);
- fragment.identification = bb.getInt();
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(fragment.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(fragment.nextHeader);
- } else {
- deserializer = Data.deserializer();
- }
- fragment.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- fragment.payload.setParent(fragment);
-
- return fragment;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/HopByHopOptions.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/HopByHopOptions.java
deleted file mode 100644
index cd8c141c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/HopByHopOptions.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.IPv6;
-
-/**
- * Implements IPv6 Hop-by-hop Options extension header format. (RFC 2460)
- */
-public class HopByHopOptions extends BaseOptions {
- public HopByHopOptions() {
- super();
- this.setType(IPv6.PROTOCOL_HOPOPT);
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/IExtensionHeader.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/IExtensionHeader.java
deleted file mode 100644
index 252f1a3c..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/IExtensionHeader.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-/**
- * Interface for IPv6 extension header.
- */
-public interface IExtensionHeader {
- /**
- * Gets the type of next header.
- *
- * @return next header
- */
- byte getNextHeader();
-
- /**
- * Sets the type of next header.
- *
- * @param nextHeader the next header to set
- * @return this
- */
- IExtensionHeader setNextHeader(final byte nextHeader);
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java
deleted file mode 100644
index d7d204a9..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IPv6;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.onlab.packet.PacketUtils.checkHeaderLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements IPv6 routing extension header format. (RFC 2460)
- */
-public class Routing extends BasePacket implements IExtensionHeader {
- public static final byte FIXED_HEADER_LENGTH = 4; // bytes
- public static final byte FIXED_ROUTING_DATA_LENGTH = 4; // bytes
- public static final byte LENGTH_UNIT = 8; // bytes per unit
-
- protected byte nextHeader;
- protected byte headerExtLength;
- protected byte routingType;
- protected byte segmentsLeft;
- protected byte[] routingData;
-
- @Override
- public byte getNextHeader() {
- return this.nextHeader;
- }
-
- @Override
- public Routing setNextHeader(final byte nextHeader) {
- this.nextHeader = nextHeader;
- return this;
- }
-
- /**
- * Gets the extension length of this header.
- *
- * @return header length
- */
- public byte getHeaderExtLength() {
- return this.headerExtLength;
- }
-
- /**
- * Sets the extension length of this header.
- *
- * @param headerExtLength the header length to set
- * @return this
- */
- public Routing setHeaderExtLength(final byte headerExtLength) {
- this.headerExtLength = headerExtLength;
- return this;
- }
-
- /**
- * Gets the routing type of this header.
- *
- * @return routing type
- */
- public byte getRoutingType() {
- return this.routingType;
- }
-
- /**
- * Sets the routing type of this header.
- *
- * @param routingType the routing type to set
- * @return this
- */
- public Routing setRoutingType(final byte routingType) {
- this.routingType = routingType;
- return this;
- }
-
- /**
- * Gets the number of remaining route segments of this header.
- *
- * @return number of remaining route segments
- */
- public byte getSegmentsLeft() {
- return this.segmentsLeft;
- }
-
- /**
- * Sets the number of remaining route segments of this header.
- *
- * @param segmentsLeft the number of remaining route segments to set
- * @return this
- */
- public Routing setSegmntsLeft(final byte segmentsLeft) {
- this.segmentsLeft = segmentsLeft;
- return this;
- }
-
- /**
- * Gets the routing data.
- *
- * @return the routing data
- */
- public byte[] getRoutingData() {
- return this.routingData;
- }
-
- /**
- * Sets the routing data.
- *
- * @param routingData the routing data to set
- * @return this
- */
- public Routing setRoutingData(final byte[] routingData) {
- this.routingData =
- Arrays.copyOfRange(routingData, 0, routingData.length);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] payloadData = null;
- if (this.payload != null) {
- this.payload.setParent(this);
- payloadData = this.payload.serialize();
- }
-
- int headerLength = FIXED_HEADER_LENGTH + routingData.length;
- int payloadLength = 0;
- if (payloadData != null) {
- payloadLength = payloadData.length;
- }
-
- final byte[] data = new byte[headerLength + payloadLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.nextHeader);
- bb.put(this.headerExtLength);
- bb.put(this.routingType);
- bb.put(this.segmentsLeft);
- bb.put(this.routingData, 0, routingData.length);
-
- if (payloadData != null) {
- bb.put(payloadData);
- }
-
- if (this.parent != null && this.parent instanceof IExtensionHeader) {
- ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ROUTING);
- }
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- this.nextHeader = bb.get();
- this.headerExtLength = bb.get();
- this.routingType = bb.get();
- this.segmentsLeft = bb.get();
- int dataLength =
- FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * this.headerExtLength;
- this.routingData = new byte[dataLength];
- bb.get(this.routingData, 0, dataLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
- } else {
- deserializer = new Data().deserializer();
- }
- try {
- this.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- this.payload.setParent(this);
- } catch (DeserializationException e) {
- return this;
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.nextHeader;
- result = prime * result + this.headerExtLength;
- result = prime * result + this.routingType;
- result = prime * result + this.segmentsLeft;
- for (byte b : this.routingData) {
- result = prime * result + b;
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Routing)) {
- return false;
- }
- final Routing other = (Routing) obj;
- if (this.nextHeader != other.nextHeader) {
- return false;
- }
- if (this.headerExtLength != other.headerExtLength) {
- return false;
- }
- if (this.routingType != other.routingType) {
- return false;
- }
- if (this.segmentsLeft != other.segmentsLeft) {
- return false;
- }
- if (!Arrays.equals(this.routingData, other.routingData)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for routing headers.
- *
- * @return deserializer function
- */
- public static Deserializer<Routing> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, FIXED_HEADER_LENGTH);
-
- Routing routing = new Routing();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- routing.nextHeader = bb.get();
- routing.headerExtLength = bb.get();
- routing.routingType = bb.get();
- routing.segmentsLeft = bb.get();
- int dataLength =
- FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * routing.headerExtLength;
-
- checkHeaderLength(bb.remaining(), dataLength);
-
- routing.routingData = new byte[dataLength];
- bb.get(routing.routingData, 0, dataLength);
-
- Deserializer<? extends IPacket> deserializer;
- if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(routing.nextHeader)) {
- deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(routing.nextHeader);
- } else {
- deserializer = new Data().deserializer();
- }
- routing.payload = deserializer.deserialize(data, bb.position(),
- bb.limit() - bb.position());
- routing.payload.setParent(routing);
-
- return routing;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/package-info.java
deleted file mode 100644
index 714fd1b2..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ipv6/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utilities for decoding and encoding IPv6 extension headers.
- */
-package org.onlab.packet.ipv6;
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java
deleted file mode 100644
index 99fa0dd6..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.Ip6Address;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 Neighbor Advertisement packet format (RFC 4861).
- */
-public class NeighborAdvertisement extends BasePacket {
- public static final byte HEADER_LENGTH = 20; // bytes
-
- protected byte routerFlag;
- protected byte solicitedFlag;
- protected byte overrideFlag;
- protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
-
- private final NeighborDiscoveryOptions options =
- new NeighborDiscoveryOptions();
-
- /**
- * Gets router flag.
- *
- * @return the router flag
- */
- public byte getRouterFlag() {
- return this.routerFlag;
- }
-
- /**
- * Sets router flag.
- *
- * @param routerFlag the router flag to set
- * @return this
- */
- public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
- this.routerFlag = routerFlag;
- return this;
- }
-
- /**
- * Gets solicited flag.
- *
- * @return the solicited flag
- */
- public byte getSolicitedFlag() {
- return this.solicitedFlag;
- }
-
- /**
- * Sets solicited flag.
- *
- * @param solicitedFlag the solicited flag to set
- * @return this
- */
- public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
- this.solicitedFlag = solicitedFlag;
- return this;
- }
-
- /**
- * Gets override flag.
- *
- * @return the override flag
- */
- public byte getOverrideFlag() {
- return this.overrideFlag;
- }
-
- /**
- * Sets override flag.
- *
- * @param overrideFlag the override flag to set
- * @return this
- */
- public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
- this.overrideFlag = overrideFlag;
- return this;
- }
-
- /**
- * Gets target address.
- *
- * @return the target IPv6 address
- */
- public byte[] getTargetAddress() {
- return this.targetAddress;
- }
-
- /**
- * Sets target address.
- *
- * @param targetAddress the target IPv6 address to set
- * @return this
- */
- public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
- this.targetAddress =
- Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> getOptions() {
- return this.options.options();
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public NeighborAdvertisement addOption(final byte type,
- final byte[] data) {
- this.options.addOption(type, data);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] optionsData = null;
- if (this.options.hasOptions()) {
- optionsData = this.options.serialize();
- }
-
- int optionsLength = 0;
- if (optionsData != null) {
- optionsLength = optionsData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + optionsLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt((this.routerFlag & 0x1) << 31 |
- (this.solicitedFlag & 0x1) << 30 |
- (this.overrideFlag & 0x1) << 29);
- bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
- if (optionsData != null) {
- bb.put(optionsData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- int iscratch;
-
- iscratch = bb.getInt();
- this.routerFlag = (byte) (iscratch >> 31 & 0x1);
- this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
- this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
- bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
- this.options.deserialize(data, bb.position(),
- bb.limit() - bb.position());
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- ByteBuffer bb;
- result = prime * result + this.routerFlag;
- result = prime * result + this.solicitedFlag;
- result = prime * result + this.overrideFlag;
- bb = ByteBuffer.wrap(this.targetAddress);
- for (int i = 0; i < this.targetAddress.length / 4; i++) {
- result = prime * result + bb.getInt();
- }
- result = prime * result + this.options.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof NeighborAdvertisement)) {
- return false;
- }
- final NeighborAdvertisement other = (NeighborAdvertisement) obj;
- if (this.routerFlag != other.routerFlag) {
- return false;
- }
- if (this.solicitedFlag != other.solicitedFlag) {
- return false;
- }
- if (this.overrideFlag != other.overrideFlag) {
- return false;
- }
- if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
- return false;
- }
- if (!this.options.equals(other.options)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for neighbor advertisement packets.
- *
- * @return deserializer function
- */
- public static Deserializer<NeighborAdvertisement> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- NeighborAdvertisement neighborAdvertisement = new NeighborAdvertisement();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- int iscratch;
-
- iscratch = bb.getInt();
- neighborAdvertisement.routerFlag = (byte) (iscratch >> 31 & 0x1);
- neighborAdvertisement.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
- neighborAdvertisement.overrideFlag = (byte) (iscratch >> 29 & 0x1);
- bb.get(neighborAdvertisement.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
- if (bb.limit() - bb.position() > 0) {
- NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
-
- for (NeighborDiscoveryOptions.Option option : options.options()) {
- neighborAdvertisement.addOption(option.type(), option.data());
- }
- }
-
- return neighborAdvertisement;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java
deleted file mode 100644
index 00a26068..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Neighbor Discovery Protocol packet options.
- */
-public class NeighborDiscoveryOptions extends BasePacket {
- public static final byte TYPE_SOURCE_LL_ADDRESS = 1;
- public static final byte TYPE_TARGET_LL_ADDRESS = 2;
- public static final byte TYPE_PREFIX_INFORMATION = 3;
- public static final byte TYPE_REDIRECTED_HEADER = 4;
- public static final byte TYPE_MTU = 5;
-
- public static final byte INITIAL_HEADER_REQUIRED = 2;
-
- private static final String BUFFER_UNDERFLOW_ERROR =
- "Not enough bytes in buffer to read option";
-
- private final List<Option> options = new ArrayList<>();
-
- /**
- * Packet option.
- */
- public final class Option {
- private final byte type;
- private final byte[] data;
-
- /**
- * Constructor.
- *
- * @param type the option type
- * @param data the option data
- */
- private Option(byte type, byte[] data) {
- this.type = type;
- this.data = Arrays.copyOfRange(data, 0, data.length);
- }
-
- /**
- * Gets the option type.
- *
- * @return the option type
- */
- public byte type() {
- return this.type;
- }
-
- /**
- * Gets the option data.
- *
- * @return the option data
- */
- public byte[] data() {
- return this.data;
- }
-
- /**
- * Gets the option data length (in number of octets).
- *
- * @return the option data length (in number of octets)
- */
- public int dataLength() {
- return data.length;
- }
-
- /**
- * Gets the option length (in number of octets), including the type and
- * length fields (one octet each).
- *
- * @return the option length (in number of octets), including the type
- * and length fields
- */
- private int optionLength() {
- return 2 + dataLength();
- }
-
- /**
- * Gets the option length field value (in units of 8 octets).
- *
- * @return the option length field value (in units of 8 octets)
- */
- private byte optionLengthField() {
- return (byte) ((optionLength() + 7) / 8);
- }
-
- /**
- * Gets the option length on the wire (in number of octets).
- *
- * @return the option length on the wire (in number of octets)
- */
- private int optionWireLength() {
- return 8 * optionLengthField();
- }
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public NeighborDiscoveryOptions addOption(byte type, byte[] data) {
- options.add(new Option(type, data));
- return this;
- }
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> options() {
- return this.options;
- }
-
- /**
- * Checks whether any options are included.
- *
- * @return true if options are included, otherwise false
- */
- public boolean hasOptions() {
- return !this.options.isEmpty();
- }
-
- @Override
- public byte[] serialize() {
- // Compute first the total length on the wire for all options
-
- int wireLength = 0;
-
- for (Option option : this.options) {
- wireLength += option.optionWireLength();
- }
-
- final byte[] data = new byte[wireLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- //
- // Serialize all options
- //
- for (Option option : this.options) {
- bb.put(option.type());
- bb.put(option.optionLengthField());
- bb.put(option.data());
- // Add the padding
- int paddingLength =
- option.optionWireLength() - option.optionLength();
- for (int i = 0; i < paddingLength; i++) {
- bb.put((byte) 0);
- }
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- options.clear();
-
- //
- // Deserialize all options
- //
- while (bb.hasRemaining()) {
- byte type = bb.get();
- if (!bb.hasRemaining()) {
- break;
- }
- byte lengthField = bb.get();
- int dataLength = lengthField * 8; // The data length field is in
- // unit of 8 octets
-
- // Exclude the type and length fields
- if (dataLength < 2) {
- break;
- }
- dataLength -= 2;
-
- if (bb.remaining() < dataLength) {
- break;
- }
- byte[] optionData = new byte[dataLength];
- bb.get(optionData, 0, optionData.length);
- addOption(type, optionData);
- }
-
- return this;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
-
- for (Option option : this.options) {
- result = prime * result + option.type();
- result = prime * result + Arrays.hashCode(option.data());
- }
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof NeighborDiscoveryOptions) {
- NeighborDiscoveryOptions other = (NeighborDiscoveryOptions) obj;
- return this.options.equals(other.options);
- }
- return false;
- }
-
- public static Deserializer<NeighborDiscoveryOptions> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, INITIAL_HEADER_REQUIRED);
-
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- NeighborDiscoveryOptions ndo = new NeighborDiscoveryOptions();
-
- ndo.options.clear();
-
- //
- // Deserialize all options
- //
- while (bb.hasRemaining()) {
- byte type = bb.get();
- if (!bb.hasRemaining()) {
- throw new DeserializationException(BUFFER_UNDERFLOW_ERROR);
- }
- byte lengthField = bb.get();
- int dataLength = lengthField * 8; // The data length field is in
- // unit of 8 octets
-
- // Exclude the type and length fields
- if (dataLength < 2) {
- break;
- }
- dataLength -= 2;
-
- if (bb.remaining() < dataLength) {
- throw new DeserializationException(BUFFER_UNDERFLOW_ERROR);
- }
- byte[] optionData = new byte[dataLength];
- bb.get(optionData, 0, optionData.length);
- ndo.addOption(type, optionData);
- }
-
- return ndo;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
deleted file mode 100644
index 77c119a0..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.Ip6Address;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 Neighbor Solicitation packet format. (RFC 4861)
- */
-public class NeighborSolicitation extends BasePacket {
- public static final byte HEADER_LENGTH = 20; // bytes
-
- protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
-
- private final NeighborDiscoveryOptions options =
- new NeighborDiscoveryOptions();
-
- /**
- * Gets target address.
- *
- * @return the target IPv6 address
- */
- public byte[] getTargetAddress() {
- return this.targetAddress;
- }
-
- /**
- * Sets target address.
- *
- * @param targetAddress the target IPv6 address to set
- * @return this
- */
- public NeighborSolicitation setTargetAddress(final byte[] targetAddress) {
- this.targetAddress =
- Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> getOptions() {
- return this.options.options();
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public NeighborSolicitation addOption(final byte type,
- final byte[] data) {
- this.options.addOption(type, data);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] optionsData = null;
- if (this.options.hasOptions()) {
- optionsData = this.options.serialize();
- }
-
- int optionsLength = 0;
- if (optionsData != null) {
- optionsLength = optionsData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + optionsLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt(0);
- bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
- if (optionsData != null) {
- bb.put(optionsData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
- bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
- this.options.deserialize(data, bb.position(),
- bb.limit() - bb.position());
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- ByteBuffer bb;
- bb = ByteBuffer.wrap(this.targetAddress);
- for (int i = 0; i < this.targetAddress.length / 4; i++) {
- result = prime * result + bb.getInt();
- }
- result = prime * result + this.options.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof NeighborSolicitation)) {
- return false;
- }
- final NeighborSolicitation other = (NeighborSolicitation) obj;
- if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
- return false;
- }
- if (!this.options.equals(other.options)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for neighbor solicitation packets.
- *
- * @return deserializer function
- */
- public static Deserializer<NeighborSolicitation> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- NeighborSolicitation neighborSolicitation = new NeighborSolicitation();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
- bb.get(neighborSolicitation.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
- if (bb.limit() - bb.position() > 0) {
- NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
-
- for (NeighborDiscoveryOptions.Option option : options.options()) {
- neighborSolicitation.addOption(option.type(), option.data());
- }
- }
-
- return neighborSolicitation;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java
deleted file mode 100644
index 51256d41..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.Ip6Address;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 Redirect packet format. (RFC 4861)
- */
-public class Redirect extends BasePacket {
- public static final byte HEADER_LENGTH = 36; // bytes
-
- protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
- protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
-
- private final NeighborDiscoveryOptions options =
- new NeighborDiscoveryOptions();
-
- /**
- * Gets target address.
- *
- * @return the target IPv6 address
- */
- public byte[] getTargetAddress() {
- return this.targetAddress;
- }
-
- /**
- * Sets target address.
- *
- * @param targetAddress the target IPv6 address to set
- * @return this
- */
- public Redirect setTargetAddress(final byte[] targetAddress) {
- this.targetAddress =
- Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- /**
- * Gets destination address.
- *
- * @return the destination IPv6 address
- */
- public byte[] getDestinationAddress() {
- return this.destinationAddress;
- }
-
- /**
- * Sets destination address.
- *
- * @param destinationAddress the destination IPv6 address to set
- * @return this
- */
- public Redirect setDestinationAddress(final byte[] destinationAddress) {
- this.destinationAddress =
- Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
- return this;
- }
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> getOptions() {
- return this.options.options();
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public Redirect addOption(final byte type, final byte[] data) {
- this.options.addOption(type, data);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] optionsData = null;
- if (this.options.hasOptions()) {
- optionsData = this.options.serialize();
- }
-
- int optionsLength = 0;
- if (optionsData != null) {
- optionsLength = optionsData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + optionsLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt(0);
- bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
- if (optionsData != null) {
- bb.put(optionsData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
- bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
- this.options.deserialize(data, bb.position(),
- bb.limit() - bb.position());
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- ByteBuffer bb;
- bb = ByteBuffer.wrap(this.targetAddress);
- for (int i = 0; i < this.targetAddress.length / 4; i++) {
- result = prime * result + bb.getInt();
- }
- bb = ByteBuffer.wrap(this.destinationAddress);
- for (int i = 0; i < this.destinationAddress.length / 4; i++) {
- result = prime * result + bb.getInt();
- }
- result = prime * result + this.options.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Redirect)) {
- return false;
- }
- final Redirect other = (Redirect) obj;
- if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
- return false;
- }
- if (!Arrays.equals(this.destinationAddress,
- other.destinationAddress)) {
- return false;
- }
- if (!this.options.equals(other.options)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for redirect packets.
- *
- * @return deserializer function
- */
- public static Deserializer<Redirect> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- Redirect redirect = new Redirect();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
-
- bb.get(redirect.targetAddress, 0, Ip6Address.BYTE_LENGTH);
- bb.get(redirect.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
- if (bb.limit() - bb.position() > 0) {
- NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
-
- for (NeighborDiscoveryOptions.Option option : options.options()) {
- redirect.addOption(option.type(), option.data());
- }
- }
-
- return redirect;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java
deleted file mode 100644
index 597fc9f8..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 Router Advertisement packet format. (RFC 4861)
- */
-public class RouterAdvertisement extends BasePacket {
- public static final byte HEADER_LENGTH = 12; // bytes
-
- protected byte currentHopLimit;
- protected byte mFlag;
- protected byte oFlag;
- protected short routerLifetime;
- protected int reachableTime;
- protected int retransmitTimer;
-
- private final NeighborDiscoveryOptions options =
- new NeighborDiscoveryOptions();
-
- /**
- * Gets current hop limit.
- *
- * @return the current hop limit
- */
- public byte getCurrentHopLimit() {
- return this.currentHopLimit;
- }
-
- /**
- * Sets current hop limit.
- *
- * @param currentHopLimit the current hop limit to set
- * @return this
- */
- public RouterAdvertisement setCurrentHopLimit(final byte currentHopLimit) {
- this.currentHopLimit = currentHopLimit;
- return this;
- }
-
- /**
- * Gets managed address configuration flag.
- *
- * @return the managed address configuration flag
- */
- public byte getMFlag() {
- return this.mFlag;
- }
-
- /**
- * Sets managed address configuration flag.
- *
- * @param mFlag the managed address configuration flag to set
- * @return this
- */
- public RouterAdvertisement setMFlag(final byte mFlag) {
- this.mFlag = mFlag;
- return this;
- }
-
- /**
- * Gets other configuration flag.
- *
- * @return the other configuration flag
- */
- public byte getOFlag() {
- return this.oFlag;
- }
-
- /**
- * Sets other configuration flag.
- *
- * @param oFlag the other configuration flag to set
- * @return this
- */
- public RouterAdvertisement setOFlag(final byte oFlag) {
- this.oFlag = oFlag;
- return this;
- }
-
- /**
- * Gets router lifetime.
- *
- * @return the router lifetime
- */
- public short getRouterLifetime() {
- return this.routerLifetime;
- }
-
- /**
- * Sets router lifetime.
- *
- * @param routerLifetime the router lifetime to set
- * @return this
- */
- public RouterAdvertisement setRouterLifetime(final short routerLifetime) {
- this.routerLifetime = routerLifetime;
- return this;
- }
-
- /**
- * Gets reachable time.
- *
- * @return the reachable time
- */
- public int getReachableTime() {
- return this.reachableTime;
- }
-
- /**
- * Sets reachable time.
- *
- * @param reachableTime the reachable time to set
- * @return this
- */
- public RouterAdvertisement setReachableTime(final int reachableTime) {
- this.reachableTime = reachableTime;
- return this;
- }
-
- /**
- * Gets retransmission timer.
- *
- * @return the retransmission timer
- */
- public int getRetransmitTimer() {
- return this.retransmitTimer;
- }
-
- /**
- * Sets retransmission timer.
- *
- * @param retransmitTimer the retransmission timer to set
- * @return this
- */
- public RouterAdvertisement setRetransmitTimer(final int retransmitTimer) {
- this.retransmitTimer = retransmitTimer;
- return this;
- }
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> getOptions() {
- return this.options.options();
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public RouterAdvertisement addOption(final byte type, final byte[] data) {
- this.options.addOption(type, data);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] optionsData = null;
- if (this.options.hasOptions()) {
- optionsData = this.options.serialize();
- }
-
- int optionsLength = 0;
- if (optionsData != null) {
- optionsLength = optionsData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + optionsLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.currentHopLimit);
- bb.put((byte) ((this.mFlag & 0x1) << 7 | (this.oFlag & 0x1) << 6));
- bb.putShort(routerLifetime);
- bb.putInt(reachableTime);
- bb.putInt(retransmitTimer);
-
- if (optionsData != null) {
- bb.put(optionsData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- int bscratch;
-
- this.currentHopLimit = bb.get();
- bscratch = bb.get();
- this.mFlag = (byte) ((bscratch >> 7) & 0x1);
- this.oFlag = (byte) ((bscratch >> 6) & 0x1);
- this.routerLifetime = bb.getShort();
- this.reachableTime = bb.getInt();
- this.retransmitTimer = bb.getInt();
-
- this.options.deserialize(data, bb.position(),
- bb.limit() - bb.position());
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.currentHopLimit;
- result = prime * result + this.mFlag;
- result = prime * result + this.oFlag;
- result = prime * result + this.routerLifetime;
- result = prime * result + this.reachableTime;
- result = prime * result + this.retransmitTimer;
- result = prime * result + this.options.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof RouterAdvertisement)) {
- return false;
- }
- final RouterAdvertisement other = (RouterAdvertisement) obj;
- if (this.currentHopLimit != other.currentHopLimit) {
- return false;
- }
- if (this.mFlag != other.mFlag) {
- return false;
- }
- if (this.oFlag != other.oFlag) {
- return false;
- }
- if (this.routerLifetime != other.routerLifetime) {
- return false;
- }
- if (this.reachableTime != other.reachableTime) {
- return false;
- }
- if (this.retransmitTimer != other.retransmitTimer) {
- return false;
- }
- if (!this.options.equals(other.options)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for router advertisement packets.
- *
- * @return deserializer function
- */
- public static Deserializer<RouterAdvertisement> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- RouterAdvertisement routerAdvertisement = new RouterAdvertisement();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- int bscratch;
-
- routerAdvertisement.currentHopLimit = bb.get();
- bscratch = bb.get();
- routerAdvertisement.mFlag = (byte) ((bscratch >> 7) & 0x1);
- routerAdvertisement.oFlag = (byte) ((bscratch >> 6) & 0x1);
- routerAdvertisement.routerLifetime = bb.getShort();
- routerAdvertisement.reachableTime = bb.getInt();
- routerAdvertisement.retransmitTimer = bb.getInt();
-
- if (bb.limit() - bb.position() > 0) {
- NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
-
- for (NeighborDiscoveryOptions.Option option : options.options()) {
- routerAdvertisement.addOption(option.type(), option.data());
- }
- }
-
- return routerAdvertisement;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java
deleted file mode 100644
index e279a404..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-/**
- * Implements ICMPv6 Router Solicitation packet format. (RFC 4861)
- */
-public class RouterSolicitation extends BasePacket {
- public static final byte HEADER_LENGTH = 4; // bytes
-
- private final NeighborDiscoveryOptions options = new NeighborDiscoveryOptions();
-
- /**
- * Gets the Neighbor Discovery Protocol packet options.
- *
- * @return the Neighbor Discovery Protocol packet options
- */
- public List<NeighborDiscoveryOptions.Option> getOptions() {
- return this.options.options();
- }
-
- /**
- * Adds a Neighbor Discovery Protocol packet option.
- *
- * @param type the option type
- * @param data the option data
- * @return this
- */
- public RouterSolicitation addOption(final byte type, final byte[] data) {
- this.options.addOption(type, data);
- return this;
- }
-
- @Override
- public byte[] serialize() {
- byte[] optionsData = null;
- if (this.options.hasOptions()) {
- optionsData = this.options.serialize();
- }
-
- int optionsLength = 0;
- if (optionsData != null) {
- optionsLength = optionsData.length;
- }
-
- final byte[] data = new byte[HEADER_LENGTH + optionsLength];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.putInt(0);
-
- if (optionsData != null) {
- bb.put(optionsData);
- }
-
- return data;
- }
-
- @Override
- public IPacket deserialize(byte[] data, int offset, int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
-
- this.options.deserialize(data, bb.position(),
- bb.limit() - bb.position());
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 5807;
- int result = super.hashCode();
- result = prime * result + this.options.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof RouterSolicitation)) {
- return false;
- }
- final RouterSolicitation other = (RouterSolicitation) obj;
- if (!this.options.equals(other.options)) {
- return false;
- }
- return true;
- }
-
- /**
- * Deserializer function for router solicitation packets.
- *
- * @return deserializer function
- */
- public static Deserializer<RouterSolicitation> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, HEADER_LENGTH);
-
- RouterSolicitation routerSolicitation = new RouterSolicitation();
-
- ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- bb.getInt();
-
- if (bb.limit() - bb.position() > 0) {
- NeighborDiscoveryOptions options = NeighborDiscoveryOptions.deserializer()
- .deserialize(data, bb.position(), bb.limit() - bb.position());
-
- for (NeighborDiscoveryOptions.Option option : options.options()) {
- routerSolicitation.addOption(option.type(), option.data());
- }
- }
-
- return routerSolicitation;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/package-info.java
deleted file mode 100644
index c62b1fba..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/ndp/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utilities for decoding and encoding packets of Neighbor Discovery Protocol
- * for IPv6 (RFC 4861).
- */
-package org.onlab.packet.ndp;
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/package-info.java
deleted file mode 100644
index e8e0cb5e..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utilities for decoding and encoding packets of various network protocols
- * and encapsulations.
- */
-package org.onlab.packet;
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java
deleted file mode 100644
index 0db82afb..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrGroup.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip6Address;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.PIM;
-
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMAddrGroup {
- private byte family;
- private byte encType;
- private byte reserved;
- private boolean bBit;
- private boolean zBit;
- private byte masklen;
- IpAddress addr;
-
- public static final int ENC_GROUP_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH;
- public static final int ENC_GROUP_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH;
-
- /**
- * PIM Encoded Group Address.
- */
- public PIMAddrGroup() {
- this.family = PIM.ADDRESS_FAMILY_IP4;
- this.encType = 0;
- this.reserved = 0;
- this.bBit = false;
- this.zBit = false;
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param addr IPv4 or IPv6
- */
- public PIMAddrGroup(String addr) {
- this.setAddr(addr);
- }
-
- /**
- * PIM Encoded Group Address.
- *
- * @param gpfx PIM encoded group address.
- */
- public PIMAddrGroup(IpPrefix gpfx) {
- this.setAddr(gpfx);
- }
-
- /**
- * PIM encoded source address.
- *
- * @param addr IPv4 or IPv6
- */
- public void setAddr(String addr) {
- setAddr(IpPrefix.valueOf(addr));
- }
-
- /**
- * Set the encoded source address.
- *
- * @param pfx address prefix
- */
- public void setAddr(IpPrefix pfx) {
- this.addr = pfx.address();
- this.masklen = (byte) pfx.prefixLength();
- this.family = (byte) ((this.addr.isIp4()) ? PIM.ADDRESS_FAMILY_IP4 : PIM.ADDRESS_FAMILY_IP6);
- }
-
- /**
- * Get the IP family of this address: 4 or 6.
- *
- * @return the IP address family
- */
- public int getFamily() {
- return this.family;
- }
-
- /**
- * Get the address of this encoded address.
- *
- * @return source address
- */
- public IpAddress getAddr() {
- return this.addr;
- }
-
- /**
- * Get the masklen of the group address.
- *
- * @return the masklen
- */
- public int getMasklen() {
- return this.masklen;
- }
-
- /**
- * Return the z bit for admin scoping. Only used for the Bootstrap router.
- *
- * @return true or false
- */
- public boolean getZBit() {
- return this.zBit;
- }
-
- /**
- * Return the bBit. Used to indicate this is a bidir
- *
- * @return return true or false.
- */
- public boolean getBBit() {
- return this.bBit;
- }
-
- /**
- * The size in bytes of a serialized address.
- *
- * @return the number of bytes when serialized
- */
- public int getByteSize() {
- int size = 4;
- size += addr.isIp4() ? 4 : 16;
- return size;
- }
-
- /**
- * Serialize this group address.
- *
- * @return the serialized address in a buffer
- */
- public byte[] serialize() {
- int len = getByteSize();
-
- final byte[] data = new byte[len];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.family);
- bb.put(this.encType);
-
- // Todo: technically we should be setting the B and Z bits, but we'll never use them.
- bb.put(reserved);
-
- bb.put(this.masklen);
- bb.put(this.addr.toOctets());
- return data;
- }
-
- /**
- * Deserialze from a ByteBuffer.
- *
- * @param bb the ByteBuffer
- * @return an encoded PIM group address
- * @throws DeserializationException if unable to deserialize the packet data
- */
- public PIMAddrGroup deserialize(ByteBuffer bb) throws DeserializationException {
-
- /*
- * We need to verify that we have enough buffer space. First we'll assume that
- * we are decoding an IPv4 address. After we read the first by (address family),
- * we'll determine if we actually need more buffer space for an IPv6 address.
- */
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_GROUP_IPV4_BYTE_LENGTH);
-
- this.family = bb.get();
- if (family != PIM.ADDRESS_FAMILY_IP4 && family != PIM.ADDRESS_FAMILY_IP6) {
- throw new DeserializationException("Illegal IP version number: " + family + "\n");
- } else if (family == PIM.ADDRESS_FAMILY_IP6) {
-
- // Check for one less by since we have already read the first byte of the packet.
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_GROUP_IPV6_BYTE_LENGTH - 1);
- }
-
- this.encType = bb.get();
- this.reserved = bb.get();
- if ((this.reserved & 0x80) != 0) {
- this.bBit = true;
- }
- if ((this.reserved & 0x01) != 0) {
- this.zBit = true;
- }
- // Remove the z and b bits from reserved
- this.reserved |= 0x7d;
-
- this.masklen = bb.get();
- if (this.family == PIM.ADDRESS_FAMILY_IP4) {
- this.addr = IpAddress.valueOf(bb.getInt());
- } else if (this.family == PIM.ADDRESS_FAMILY_IP6) {
- this.addr = Ip6Address.valueOf(bb.array(), 2);
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.family;
- result = prime * result + this.encType;
- result = prime * result + this.reserved;
- result = prime * result + this.masklen;
- result = prime * result + this.addr.hashCode();
- return result;
- }
-
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals()
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof PIMAddrGroup)) {
- return false;
- }
- final PIMAddrGroup other = (PIMAddrGroup) obj;
- if (this.family != other.family) {
- return false;
- }
-
- if (this.encType != other.encType) {
- return false;
- }
-
- if (!this.addr.equals(other.addr)) {
- return false;
- }
- return true;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java
deleted file mode 100644
index 762dad56..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrSource.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip6Address;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.PIM;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMAddrSource {
- private byte family;
- private byte encType;
- private byte reserved;
- private boolean sBit;
- private boolean wBit;
- private boolean rBit;
- private byte masklen;
- IpAddress addr;
-
- public static final int ENC_SOURCE_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH;
- public static final int ENC_SOURCE_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH;
-
- /**
- * PIM Encoded Source Address.
- *
- * @param addr IPv4 or IPv6
- */
- public PIMAddrSource(String addr) {
- this.init();
- this.setAddr(addr);
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param spfx IPv4 or IPv6
- */
- public PIMAddrSource(IpPrefix spfx) {
- this.init();
- this.setAddr(spfx);
- }
-
- /**
- * PIM Encoded Group Address.
- */
- public PIMAddrSource() {
- this.init();
- }
-
- private void init() {
- this.family = PIM.ADDRESS_FAMILY_IP4;
- this.encType = 0;
- this.reserved = 0;
- this.sBit = true;
- this.wBit = false;
- this.rBit = false;
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param addr IPv4 or IPv6
- */
- public void setAddr(String addr) {
- IpPrefix spfx = IpPrefix.valueOf(addr);
- setAddr(spfx);
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param spfx IPv4 or IPv6 address prefix
- */
- public void setAddr(IpPrefix spfx) {
- this.addr = spfx.address();
- this.masklen = (byte) spfx.prefixLength();
- this.family = (byte) ((this.addr.isIp4()) ? PIM.ADDRESS_FAMILY_IP4 : PIM.ADDRESS_FAMILY_IP6);
- }
-
- /**
- * Get the IP family of this address: 4 or 6.
- *
- * @return the IP address family
- */
- public byte getFamily() {
- return this.family;
- }
-
- /**
- * Get the address of this encoded address.
- *
- * @return source address
- */
- public IpAddress getAddr() {
- return this.addr;
- }
-
- /**
- * Get the masklen of the group address.
- *
- * @return the masklen
- */
- public int getMasklen() {
- return this.masklen;
- }
-
- /**
- * Return the sparse bit.
- *
- * @return true or false
- */
- public boolean getSBit() {
- return this.sBit;
- }
-
- /**
- * Return the wBit, used in Join/Prune messages.
- *
- * @return return true or false.
- */
- public boolean getWBit() {
- return this.wBit;
- }
-
- /**
- * Return the rBit. Used by Rendezvous Point.
- *
- * @return the rBit.
- */
- public boolean getRBit() {
- return this.rBit;
- }
-
- /**
- * The size in bytes of a serialized address.
- *
- * @return the number of bytes when serialized
- */
- public int getByteSize() {
- int size = 4;
- size += addr.isIp4() ? PIM.ADDRESS_FAMILY_IP4 : PIM.ADDRESS_FAMILY_IP6;
- return size;
- }
-
- public byte[] serialize() {
- int len = addr.isIp4() ? ENC_SOURCE_IPV4_BYTE_LENGTH : ENC_SOURCE_IPV6_BYTE_LENGTH;
-
- final byte[] data = new byte[len];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(this.family);
- bb.put(this.encType);
-
- // Todo: technically we should be setting the B and Z bits, but we'll never use them.
- byte mask = 0x0;
- if (this.sBit) {
- this.reserved |= 0x4;
- }
- if (this.wBit) {
- this.reserved |= 0x2;
- }
- if (this.rBit) {
- this.reserved |= 0x1;
- }
- bb.put(reserved);
-
- bb.put(this.masklen);
- bb.put(this.addr.toOctets());
- return data;
- }
-
- public PIMAddrSource deserialize(byte[] data, int offset, int length) throws DeserializationException {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- return deserialize(bb);
- }
-
- public PIMAddrSource deserialize(ByteBuffer bb) throws DeserializationException {
-
- /*
- * We need to verify that we have enough buffer space. First we'll assume that
- * we are decoding an IPv4 address. After we read the first by (address family),
- * we'll determine if we actually need more buffer space for an IPv6 address.
- */
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV4_BYTE_LENGTH);
-
- this.family = bb.get();
- if (family != PIM.ADDRESS_FAMILY_IP4 && family != PIM.ADDRESS_FAMILY_IP6) {
- throw new DeserializationException("Illegal IP version number: " + family + "\n");
- } else if (family == PIM.ADDRESS_FAMILY_IP6) {
-
- // Check for one less by since we have already read the first byte of the packet.
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV6_BYTE_LENGTH - 1);
- }
-
- this.encType = bb.get();
- this.reserved = bb.get();
- if ((this.reserved & 0x01) != 0) {
- this.rBit = true;
- }
- if ((this.reserved & 0x02) != 0) {
- this.wBit = true;
- }
- if ((this.reserved & 0x4) != 0) {
- this.sBit = true;
- }
-
- // Remove the s, reserved
- this.reserved &= 0xf8;
-
- this.masklen = bb.get();
- if (this.family == PIM.ADDRESS_FAMILY_IP4) {
- this.addr = IpAddress.valueOf(bb.getInt());
- } else if (this.family == PIM.ADDRESS_FAMILY_IP6) {
- this.addr = Ip6Address.valueOf(bb.array(), 2);
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.family;
- result = prime * result + this.encType;
- result = prime * result + this.reserved;
- result = prime * result + this.masklen;
- result = prime * result + this.addr.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof PIMAddrSource)) {
- return false;
- }
- final PIMAddrSource other = (PIMAddrSource) obj;
- if (this.family != other.family) {
- return false;
- }
-
- if (this.encType != other.encType) {
- return false;
- }
-
- if (!this.addr.equals(other.addr)) {
- return false;
- }
- return true;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java
deleted file mode 100644
index 3327a8e7..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMAddrUnicast.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-
-
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip6Address;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.PIM;
-
-import java.nio.ByteBuffer;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMAddrUnicast {
- private byte family;
- private byte encType;
- IpAddress addr;
-
- public static final int ENC_UNICAST_IPV4_BYTE_LENGTH = 2 + Ip4Address.BYTE_LENGTH;
- public static final int ENC_UNICAST_IPV6_BYTE_LENGTH = 2 + Ip6Address.BYTE_LENGTH;
-
- /**
- * PIM Encoded Source Address.
- */
- public PIMAddrUnicast() {
- this.family = PIM.ADDRESS_FAMILY_IP4;
- this.encType = 0;
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param addr IPv4 or IPv6
- */
- public PIMAddrUnicast(String addr) {
- this.addr = IpAddress.valueOf(addr);
- if (this.addr.isIp4()) {
- this.family = PIM.ADDRESS_FAMILY_IP4;
- } else {
- this.family = PIM.ADDRESS_FAMILY_IP6;
- }
- this.encType = 0;
- }
-
- /**
- * PIM Encoded Source Address.
- *
- * @param addr IPv4 or IPv6
- */
- public void setAddr(IpAddress addr) {
- this.addr = addr;
- if (this.addr.isIp4()) {
- this.family = PIM.ADDRESS_FAMILY_IP4;
- } else {
- this.family = PIM.ADDRESS_FAMILY_IP6;
- }
- }
-
- /**
- * Get the address of this encoded address.
- *
- * @return source address
- */
- public IpAddress getAddr() {
- return this.addr;
- }
-
- /**
- * Get the IP family of this address: 4 or 6.
- *
- * @return the IP address family
- */
- public int getFamily() {
- return this.family;
- }
-
- /**
- * The size in bytes of a serialized address.
- *
- * @return the number of bytes when serialized
- */
- public int getByteSize() {
- int size = 2;
- if (addr != null) {
- size += addr.isIp4() ? 4 : 16;
- } else {
- size += 4;
- }
- return size;
- }
-
- public byte[] serialize() {
- int len = getByteSize();
-
- final byte[] data = new byte[len];
- final ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(family);
- bb.put(encType);
- bb.put(addr.toOctets());
- return data;
- }
-
- public PIMAddrUnicast deserialize(ByteBuffer bb) throws DeserializationException {
-
- // Assume IPv4 for check length until we read the encoded family.
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV4_BYTE_LENGTH);
- this.family = bb.get();
-
- // If we have IPv6 we need to ensure we have adequate buffer space.
- if (this.family != PIM.ADDRESS_FAMILY_IP4 && this.family != PIM.ADDRESS_FAMILY_IP6) {
- throw new DeserializationException("Invalid address family: " + this.family);
- } else if (this.family == PIM.ADDRESS_FAMILY_IP6) {
- // Subtract -1 from ENC_UNICAST_IPv6 BYTE_LENGTH because we read one byte for family previously.
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV6_BYTE_LENGTH - 1);
- }
-
- this.encType = bb.get();
- if (this.family == PIM.ADDRESS_FAMILY_IP4) {
- this.addr = IpAddress.valueOf(bb.getInt());
- } else if (this.family == PIM.ADDRESS_FAMILY_IP6) {
- this.addr = Ip6Address.valueOf(bb.array(), 2);
- }
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + this.family;
- result = prime * result + this.encType;
- result = prime * result + this.addr.hashCode();
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof PIMAddrUnicast)) {
- return false;
- }
- final PIMAddrUnicast other = (PIMAddrUnicast) obj;
- if (this.family != other.family) {
- return false;
- }
-
- if (this.encType != other.encType) {
- return false;
- }
-
- if (!this.addr.equals(other.addr)) {
- return false;
- }
- return true;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java
deleted file mode 100644
index 9ad3fdbd..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IpAddress;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMHello extends BasePacket {
-
- private IpAddress nbrIpAddress;
- private boolean priorityPresent = false;
-
- private Map<Short, PIMHelloOption> options = new HashMap<>();
-
- /**
- * Create a PIM Hello packet with the most common hello options and default
- * values. The values of any options can be easily changed by modifying the value of
- * the option with the desired change.
- */
- public void createDefaultOptions() {
- options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME));
- options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY));
- options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID));
- }
-
- /**
- * Add a PIM Hello option to this hello message. Note
- *
- * @param opt the PIM Hello option we are adding
- */
- public void addOption(PIMHelloOption opt) {
- this.options.put(opt.getOptType(), opt);
- }
-
- public Map<Short, PIMHelloOption> getOptions() {
- return this.options;
- }
-
- /**
- * Sets all payloads parent packet if applicable, then serializes this
- * packet and all payloads.
- *
- * @return a byte[] containing this packet and payloads
- */
- @Override
- public byte[] serialize() {
- int totalLen = 0;
-
-
- // Since we are likely to only have 3-4 options, go head and walk the
- // hashmap twice, once to calculate the space needed to allocate a
- // buffer, the second time serialize the options into the buffer. This
- // saves us from allocating an over sized buffer the re-allocating and
- // copying.
- for (Short optType : options.keySet()) {
- PIMHelloOption opt = options.get(optType);
- totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength();
- }
-
- byte[] data = new byte[totalLen];
- ByteBuffer bb = ByteBuffer.wrap(data);
-
- // Now serialize the data.
- for (Short optType : options.keySet()) {
- PIMHelloOption opt = options.get(optType);
- bb.put(opt.serialize());
- }
- return data;
- }
-
- /**
- * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
- */
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- // TODO: throw an expection?
- return null;
- }
-
- /**
- * Deserialize this hello message.
- *
- * @return a deserialized hello message
- */
- public static Deserializer<PIMHello> deserializer() {
- return (data, offset, length) -> {
- checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES);
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- PIMHello hello = new PIMHello();
- while (bb.hasRemaining()) {
- PIMHelloOption opt = PIMHelloOption.deserialize(bb);
- hello.addOption(opt);
- }
- return hello;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java
deleted file mode 100644
index bf021fbd..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-import org.onlab.packet.DeserializationException;
-
-import java.nio.ByteBuffer;
-import java.text.MessageFormat;
-
-import static org.onlab.packet.PacketUtils.checkBufferLength;
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMHelloOption {
-
- /**
- * PIM Option types.
- */
- public static final short OPT_HOLDTIME = 1;
- public static final short OPT_PRUNEDELAY = 2;
- public static final short OPT_PRIORITY = 19;
- public static final short OPT_GENID = 20;
- public static final short OPT_ADDRLIST = 24;
-
- public static final short DEFAULT_HOLDTIME = 105;
- public static final int DEFAULT_PRUNEDELAY = 2000; // 2,000 ms
- public static final int DEFAULT_PRIORITY = 1;
- public static final int DEFAULT_GENID = 0;
-
- public static final int MINIMUM_OPTION_LEN_BYTES = 4;
-
- // Values for this particular hello option.
- private short optType;
- private short optLength;
- private byte[] optValue;
-
- public PIMHelloOption() {
- }
-
- /**
- * Set a PIM Hello option by type. The length and default value of the
- * type will be auto filled in by default.
- *
- * @param type hello option type
- */
- public PIMHelloOption(short type) {
- this.optType = type;
- switch (type) {
- case OPT_HOLDTIME:
- this.optLength = 2;
- this.optValue = new byte[optLength];
- ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME);
- break;
-
- case OPT_PRUNEDELAY:
- this.optLength = 4;
- this.optValue = new byte[this.optLength];
- ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY);
- break;
-
- case OPT_PRIORITY:
- this.optLength = 4;
- this.optValue = new byte[this.optLength];
- ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY);
- break;
-
- case OPT_GENID:
- this.optLength = 4;
- this.optValue = new byte[this.optLength];
- ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID);
- break;
-
- case OPT_ADDRLIST:
- this.optLength = 0; // We don't know what the length will be yet.
- this.optValue = null;
-
- default:
- //log.error("Unkown option type: " + type + "\n" );
- return;
- }
- }
-
- public void setOptType(short type) {
- this.optType = type;
- }
-
- public short getOptType() {
- return this.optType;
- }
-
- public void setOptLength(short len) {
- this.optLength = len;
- }
-
- public short getOptLength() {
- return this.optLength;
- }
-
- public void setValue(ByteBuffer bb) throws DeserializationException {
- this.optValue = new byte[this.optLength];
- bb.get(this.optValue, 0, this.optLength);
- }
-
- public byte[] getValue() {
- return this.optValue;
- }
-
- public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException {
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4);
-
- PIMHelloOption opt = new PIMHelloOption();
- opt.setOptType(bb.getShort());
- opt.setOptLength(bb.getShort());
-
- checkBufferLength(bb.limit(), bb.position(), opt.getOptLength());
- opt.setValue(bb);
-
- return opt;
- }
-
- public byte [] serialize() {
- int len = 4 + this.optLength;
- ByteBuffer bb = ByteBuffer.allocate(len);
- bb.putShort(this.optType);
- bb.putShort(this.optLength);
- bb.put(this.optValue);
- return bb.array();
- }
-
- public String toString() {
- return MessageFormat.format("Type: {0}, len: {1} value: {2}", this.optType, this.optLength,
- (this.optValue == null) ? "null" : this.optValue.toString());
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java
deleted file mode 100644
index 9653115b..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.pim;
-
-import org.onlab.packet.BasePacket;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import org.onlab.packet.IpPrefix;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-
-import static org.onlab.packet.PacketUtils.checkInput;
-
-public class PIMJoinPrune extends BasePacket {
-
- private PIMAddrUnicast upstreamAddr = new PIMAddrUnicast();
- private short holdTime = (short) 0xffff;
-
- private class JoinPruneGroup {
- protected IpPrefix group;
- protected HashMap<IpPrefix, IpPrefix> joins = new HashMap<>();
- protected HashMap<IpPrefix, IpPrefix> prunes = new HashMap<>();
-
- public JoinPruneGroup(IpPrefix grp) {
- group = grp;
- }
- }
- private HashMap<IpPrefix, JoinPruneGroup> joinPrunes = new HashMap<>();
-
- /**
- * Get the J/P hold time.
- *
- * @return specified in seconds.
- */
- public short getHoldTime() {
- return holdTime;
- }
-
- /**
- * Set the J/P holdtime in seconds.
- *
- * @param holdTime return the holdtime.
- */
- public void setHoldTime(short holdTime) {
- this.holdTime = holdTime;
- }
-
- /**
- * Get the upstreamAddr for this J/P request.
- *
- * @return the upstream address.
- */
- public PIMAddrUnicast getUpstreamAddr() {
- return upstreamAddr;
- }
-
- /**
- * Set the upstream address of this PIM J/P request.
- *
- * @param upstr the PIM Upstream unicast address
- */
- public void setUpstreamAddr(PIMAddrUnicast upstr) {
- this.upstreamAddr = upstr;
- }
-
- /**
- * Add the specified s,g to join field.
- *
- * @param saddr the source address of the route
- * @param gaddr the group address of the route
- * @param join true for a join, false for a prune.
- */
- public void addJoinPrune(String saddr, String gaddr, boolean join) {
- IpPrefix gpfx = IpPrefix.valueOf(gaddr);
- IpPrefix spfx = IpPrefix.valueOf(saddr);
- addJoinPrune(spfx, gpfx, join);
- }
-
- /**
- * Add the specified S, G to the join field.
- *
- * @param spfx the source prefix of the route
- * @param gpfx the group prefix of the route
- * @param join true for join, false for prune
- */
- public void addJoinPrune(IpPrefix spfx, IpPrefix gpfx, boolean join) {
- JoinPruneGroup jpg = joinPrunes.get(gpfx);
- if (jpg == null) {
- jpg = new JoinPruneGroup(gpfx);
- joinPrunes.put(gpfx, jpg);
- }
-
- HashMap<IpPrefix, IpPrefix> members = (join) ? jpg.joins : jpg.prunes;
- if (members.get(spfx) == null) {
- members.put(spfx, spfx);
- }
- }
-
- /**
- * Add a join given strings represending the source and group addresses.
- *
- * @param saddr source address
- * @param gaddr group address
- */
- public void addJoin(String saddr, String gaddr) {
- this.addJoinPrune(saddr, gaddr, true);
- }
-
- /**
- * Add a prune given strings represending the source and group addresses.
- *
- * @param saddr source address
- * @param gaddr group address
- */
- public void addPrune(String saddr, String gaddr) {
- this.addJoinPrune(saddr, gaddr, false);
- }
-
- /**
- * Sets all payloads parent packet if applicable, then serializes this
- * packet and all payloads.
- *
- * @return a byte[] containing this packet and payloads
- */
- @Override
- public byte[] serialize() {
-
- byte[] data = new byte[8096]; // Come up with something better
- ByteBuffer bb = ByteBuffer.wrap(data);
-
- bb.put(upstreamAddr.serialize());
- bb.put((byte) 0); // reserved
-
- int ngrps = joinPrunes.size();
- bb.put((byte) ngrps);
- bb.putShort(this.holdTime);
-
- // Walk the group list and input all groups
- for (JoinPruneGroup jpg : joinPrunes.values()) {
- PIMAddrGroup grp = new PIMAddrGroup(jpg.group);
- bb.put(grp.serialize());
-
- // put the number of joins and prunes
- bb.putShort((short) jpg.joins.size());
- bb.putShort((short) jpg.prunes.size());
-
- // Set all of the joins
- for (IpPrefix spfx : jpg.joins.values()) {
- PIMAddrSource src = new PIMAddrSource(spfx);
- bb.put(src.serialize());
- }
-
- // Set all of the prunes
- for (IpPrefix spfx : jpg.prunes.values()) {
- PIMAddrSource src = new PIMAddrSource(spfx);
- bb.put(src.serialize());
- }
- }
-
- int len = bb.position();
- byte[] data2 = new byte[len];
- bb = ByteBuffer.wrap(data2, 0, len);
- bb.put(data, 0, len);
- return data2;
- }
-
- // TODO: I suppose I really need to implement this?
- @Override
- public IPacket deserialize(final byte[] data, final int offset,
- final int length) {
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
- return this;
- }
-
- /**
- * Return the J/P deserializer function.
- *
- * @return a function that will deserialize a J/P message.
- */
- public static Deserializer<PIMJoinPrune> deserializer() {
- return (data, offset, length) -> {
-
- /*
- * Delay buffer checks until we read enough of the packet to know how
- * much data we will require. Each encoded address deserializer function
- * will ensure there is enough data for that address.
- */
- PIMJoinPrune jp = new PIMJoinPrune();
- final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
- // We must get a PIM encoded unicast address
- PIMAddrUnicast upstream = new PIMAddrUnicast();
- upstream.deserialize(bb);
- jp.setUpstreamAddr(upstream);
-
- // Use this boolean to determine the buffer space we need according to address sizes
- boolean ipv4 = upstream.getAddr().isIp4();
-
- // We need at minimum 4 bytes for reserved(1), ngroups(1) & holdtime(2)
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4);
-
- // get and skip the reserved byte
- bb.get();
-
- // Get the number of groups.
- int ngroups = bb.get();
-
- // Save the holdtime.
- jp.setHoldTime(bb.getShort());
-
-
- for (int i = 0; i < ngroups; i++) {
- PIMAddrGroup grp = new PIMAddrGroup();
-
- /*
- * grp.deserialize will ensure the buffer has enough data to read the group address.
- */
- grp.deserialize(bb);
-
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4);
- int njoins = bb.getShort();
- int nprunes = bb.getShort();
-
- /*
- * Now we'll verify we have enough buffer to read the next
- * group of join and prune addresses for this group.
- */
- int required = (njoins + nprunes) *
- (ipv4 ? PIMAddrSource.ENC_SOURCE_IPV4_BYTE_LENGTH : PIMAddrSource.ENC_SOURCE_IPV6_BYTE_LENGTH);
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), required);
-
- // Now iterate through the joins for this group
- for (; njoins > 0; njoins--) {
-
- PIMAddrSource src = new PIMAddrSource();
- src.deserialize(bb);
-
- jp.addJoinPrune(
- src.getAddr().toIpPrefix(),
- grp.getAddr().toIpPrefix(), true);
- }
-
- // Now iterate through the prunes for this group
- for (; nprunes > 0; nprunes--) {
-
- PIMAddrSource src = new PIMAddrSource();
- src.deserialize(bb);
- jp.addJoinPrune(
- src.getAddr().toIpPrefix(),
- grp.getAddr().toIpPrefix(), false);
- }
- }
-
- return jp;
- };
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java
deleted file mode 100755
index 88a1ad5d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Utilities for managing PIM packets.
- */
-package org.onlab.packet.pim;
-
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java
deleted file mode 100644
index 500f8d60..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.collect.Lists;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Base implementation of an item accumulator. It allows triggering based on
- * item inter-arrival time threshold, maximum batch life threshold and maximum
- * batch size.
- */
-public abstract class AbstractAccumulator<T> implements Accumulator<T> {
-
- private Logger log = LoggerFactory.getLogger(AbstractAccumulator.class);
-
- private final Timer timer;
- private final int maxItems;
- private final int maxBatchMillis;
- private final int maxIdleMillis;
-
- private volatile TimerTask idleTask = new ProcessorTask();
- private volatile TimerTask maxTask = new ProcessorTask();
-
- private List<T> items = Lists.newArrayList();
-
- /**
- * Creates an item accumulator capable of triggering on the specified
- * thresholds.
- *
- * @param timer timer to use for scheduling check-points
- * @param maxItems maximum number of items to accumulate before
- * processing is triggered
- * @param maxBatchMillis maximum number of millis allowed since the first
- * item before processing is triggered
- * @param maxIdleMillis maximum number millis between items before
- * processing is triggered
- */
- protected AbstractAccumulator(Timer timer, int maxItems,
- int maxBatchMillis, int maxIdleMillis) {
- this.timer = checkNotNull(timer, "Timer cannot be null");
-
- checkArgument(maxItems > 1, "Maximum number of items must be > 1");
- checkArgument(maxBatchMillis > 0, "Maximum millis must be positive");
- checkArgument(maxIdleMillis > 0, "Maximum idle millis must be positive");
-
- this.maxItems = maxItems;
- this.maxBatchMillis = maxBatchMillis;
- this.maxIdleMillis = maxIdleMillis;
- }
-
- @Override
- public synchronized void add(T item) {
- idleTask = cancelIfActive(idleTask);
- items.add(checkNotNull(item, "Item cannot be null"));
-
- // Did we hit the max item threshold?
- if (items.size() >= maxItems) {
- maxTask = cancelIfActive(maxTask);
- scheduleNow();
- } else {
- // Otherwise, schedule idle task and if this is a first item
- // also schedule the max batch age task.
- idleTask = schedule(maxIdleMillis);
- if (items.size() == 1) {
- maxTask = schedule(maxBatchMillis);
- }
- }
- }
-
- /**
- * Finalizes the current batch, if ready, and schedules a new processor
- * in the immediate future.
- */
- private void scheduleNow() {
- if (isReady()) {
- TimerTask task = new ProcessorTask(finalizeCurrentBatch());
- timer.schedule(task, 1);
- }
- }
-
- /**
- * Schedules a new processor task given number of millis in the future.
- * Batch finalization is deferred to time of execution.
- */
- private TimerTask schedule(int millis) {
- TimerTask task = new ProcessorTask();
- timer.schedule(task, millis);
- return task;
- }
-
- /**
- * Cancels the specified task if it is active.
- */
- private TimerTask cancelIfActive(TimerTask task) {
- if (task != null) {
- task.cancel();
- }
- return task;
- }
-
- // Task for triggering processing of accumulated items
- private class ProcessorTask extends TimerTask {
-
- private final List<T> items;
-
- // Creates a new processor task with deferred batch finalization.
- ProcessorTask() {
- this.items = null;
- }
-
- // Creates a new processor task with pre-emptive batch finalization.
- ProcessorTask(List<T> items) {
- this.items = items;
- }
-
- @Override
- public void run() {
- synchronized (AbstractAccumulator.this) {
- idleTask = cancelIfActive(idleTask);
- }
- if (isReady()) {
- try {
- synchronized (AbstractAccumulator.this) {
- maxTask = cancelIfActive(maxTask);
- }
- List<T> batch = items != null ? items : finalizeCurrentBatch();
- if (!batch.isEmpty()) {
- processItems(batch);
- }
- } catch (Exception e) {
- log.warn("Unable to process batch due to", e);
- }
- } else {
- synchronized (AbstractAccumulator.this) {
- idleTask = schedule(maxIdleMillis);
- }
- }
- }
- }
-
- // Demotes and returns the current batch of items and promotes a new one.
- private synchronized List<T> finalizeCurrentBatch() {
- List<T> toBeProcessed = items;
- items = Lists.newArrayList();
- return toBeProcessed;
- }
-
- @Override
- public boolean isReady() {
- return true;
- }
-
- /**
- * Returns the backing timer.
- *
- * @return backing timer
- */
- public Timer timer() {
- return timer;
- }
-
- /**
- * Returns the maximum number of items allowed to accumulate before
- * processing is triggered.
- *
- * @return max number of items
- */
- public int maxItems() {
- return maxItems;
- }
-
- /**
- * Returns the maximum number of millis allowed to expire since the first
- * item before processing is triggered.
- *
- * @return max number of millis a batch is allowed to last
- */
- public int maxBatchMillis() {
- return maxBatchMillis;
- }
-
- /**
- * Returns the maximum number of millis allowed to expire since the last
- * item arrival before processing is triggered.
- *
- * @return max number of millis since the last item
- */
- public int maxIdleMillis() {
- return maxIdleMillis;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Accumulator.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Accumulator.java
deleted file mode 100644
index 20b7a481..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Accumulator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.List;
-
-/**
- * Abstraction of an accumulator capable of collecting items and at some
- * point in time triggers processing of all previously accumulated items.
- *
- * @param <T> item type
- */
-public interface Accumulator<T> {
-
- /**
- * Adds an item to the current batch. This operation may, or may not
- * trigger processing of the current batch of items.
- *
- * @param item item to be added to the current batch
- */
- void add(T item);
-
- /**
- * Processes the specified list of accumulated items.
- *
- * @param items list of accumulated items
- */
- void processItems(List<T> items);
-
- /**
- * Indicates whether the accumulator is ready to process items.
- *
- * @return true if ready to process
- */
- boolean isReady();
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Bandwidth.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Bandwidth.java
deleted file mode 100644
index 60806568..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Bandwidth.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.collect.ComparisonChain;
-
-import java.util.Objects;
-
-/**
- * Representation of bandwidth.
- * Use the static factory method corresponding to the unit (like Kbps) you desire on instantiation.
- */
-public final class Bandwidth implements RichComparable<Bandwidth> {
-
- private final double bps;
-
- /**
- * Creates a new instance with given bandwidth.
- *
- * @param bps bandwidth value to be assigned
- */
- private Bandwidth(double bps) {
- this.bps = bps;
- }
-
- // Constructor for serialization
- private Bandwidth() {
- this.bps = 0;
- }
-
- /**
- * Creates a new instance with given bandwidth.
- *
- * @param v bandwidth value
- * @param unit {@link DataRateUnit} of {@code v}
- * @return {@link Bandwidth} instance with given bandwidth
- */
- public static Bandwidth of(double v, DataRateUnit unit) {
- return new Bandwidth(unit.toBitsPerSecond(v));
- }
-
- /**
- * Creates a new instance with given bandwidth in bps.
- *
- * @param bps bandwidth value to be assigned
- * @return {@link Bandwidth} instance with given bandwidth
- */
- public static Bandwidth bps(double bps) {
- return new Bandwidth(bps);
- }
-
- /**
- * Creates a new instance with given bandwidth in Kbps.
- *
- * @param kbps bandwidth value to be assigned
- * @return {@link Bandwidth} instance with given bandwidth
- */
- public static Bandwidth kbps(double kbps) {
- return bps(kbps * 1_000L);
- }
-
- /**
- * Creates a new instance with given bandwidth in Mbps.
- *
- * @param mbps bandwidth value to be assigned
- * @return {@link Bandwidth} instance with given bandwidth
- */
- public static Bandwidth mbps(double mbps) {
- return bps(mbps * 1_000_000L);
- }
-
- /**
- * Creates a new instance with given bandwidth in Gbps.
- *
- * @param gbps bandwidth value to be assigned
- * @return {@link Bandwidth} instance with given bandwidth
- */
- public static Bandwidth gbps(double gbps) {
- return bps(gbps * 1_000_000_000L);
- }
-
- /**
- * Returns bandwidth in bps.
- *
- * @return bandwidth in bps.
- */
- public double bps() {
- return bps;
- }
-
- /**
- * Returns a Bandwidth whose value is (this + value).
- *
- * @param value value to be added to this Frequency
- * @return this + value
- */
- public Bandwidth add(Bandwidth value) {
- return bps(this.bps + value.bps);
- }
-
- /**
- * Returns a Bandwidth whose value is (this - value).
- *
- * @param value value to be added to this Frequency
- * @return this - value
- */
- public Bandwidth subtract(Bandwidth value) {
- return bps(this.bps - value.bps);
- }
-
- @Override
- public int compareTo(Bandwidth other) {
- return ComparisonChain.start()
- .compare(this.bps, other.bps)
- .result();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Bandwidth) {
- Bandwidth that = (Bandwidth) obj;
- return Objects.equals(this.bps, that.bps);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(Double.doubleToLongBits(bps));
- }
-
- @Override
- public String toString() {
- return String.valueOf(this.bps);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BlockingBoolean.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BlockingBoolean.java
deleted file mode 100644
index f3049c31..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BlockingBoolean.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.AbstractQueuedSynchronizer;
-
-/**
- * Mutable boolean that allows threads to wait for a specified value.
- */
-public class BlockingBoolean extends AbstractQueuedSynchronizer {
-
- private static final int TRUE = 1;
- private static final int FALSE = 0;
-
- /**
- * Creates a new blocking boolean with the specified value.
- *
- * @param value the starting value
- */
- public BlockingBoolean(boolean value) {
- setState(value ? TRUE : FALSE);
- }
-
- /**
- * Causes the current thread to wait until the boolean equals the specified
- * value unless the thread is {@linkplain Thread#interrupt interrupted}.
- *
- * @param value specified value
- * @throws InterruptedException if interrupted while waiting
- */
- public void await(boolean value) throws InterruptedException {
- acquireSharedInterruptibly(value ? TRUE : FALSE);
- }
-
- /**
- * Causes the current thread to wait until the boolean equals the specified
- * value unless the thread is {@linkplain Thread#interrupt interrupted},
- * or the specified waiting time elapses.
- *
- * @param value specified value
- * @param timeout the maximum time to wait
- * @param unit the time unit of the {@code timeout} argument
- * @return {@code true} if the count reached zero and {@code false}
- * if the waiting time elapsed before the count reached zero
- * @throws InterruptedException if interrupted while waiting
- */
- public boolean await(boolean value, long timeout, TimeUnit unit)
- throws InterruptedException {
- return tryAcquireSharedNanos(value ? TRUE : FALSE, unit.toNanos(timeout));
- }
-
- protected int tryAcquireShared(int acquires) {
- return (getState() == acquires) ? 1 : -1;
- }
-
- /**
- * Sets the value of the blocking boolean.
- *
- * @param value new value
- */
- public void set(boolean value) {
- releaseShared(value ? TRUE : FALSE);
- }
-
- /**
- * Gets the value of the blocking boolean.
- *
- * @return current value
- */
- public boolean get() {
- return getState() == TRUE;
- }
-
- protected boolean tryReleaseShared(int releases) {
- // Signal on state change only
- int state = getState();
- if (state == releases) {
- return false;
- }
- return compareAndSetState(state, releases);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BoundedThreadPool.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BoundedThreadPool.java
deleted file mode 100644
index 9eef6609..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/BoundedThreadPool.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Implementation of ThreadPoolExecutor that bounds the work queue.
- * <p>
- * When a new job would exceed the queue bound, the job is run on the caller's
- * thread rather than on a thread from the pool.
- * </p>
- */
-public final class BoundedThreadPool extends ThreadPoolExecutor {
-
- private static final org.slf4j.Logger log = LoggerFactory.getLogger(BoundedThreadPool.class);
-
- protected static int maxQueueSize = 80_000; //TODO tune this value
- //private static final RejectedExecutionHandler DEFAULT_HANDLER = new CallerFeedbackPolicy();
- private static final long STATS_INTERVAL = 5_000; //ms
-
- private final BlockingBoolean underHighLoad;
-
- private BoundedThreadPool(int numberOfThreads,
- ThreadFactory threadFactory) {
- super(numberOfThreads, numberOfThreads,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<>(maxQueueSize),
- threadFactory,
- new CallerFeedbackPolicy());
- underHighLoad = ((CallerFeedbackPolicy) getRejectedExecutionHandler()).load();
- }
-
- /**
- * Returns a single-thread, bounded executor service.
- *
- * @param threadFactory thread factory for the worker thread.
- * @return the bounded thread pool
- */
- public static BoundedThreadPool newSingleThreadExecutor(ThreadFactory threadFactory) {
- return new BoundedThreadPool(1, threadFactory);
- }
-
- /**
- * Returns a fixed-size, bounded executor service.
- *
- * @param numberOfThreads number of threads in the pool
- * @param threadFactory thread factory for the worker threads.
- * @return the bounded thread pool
- */
- public static BoundedThreadPool newFixedThreadPool(int numberOfThreads, ThreadFactory threadFactory) {
- return new BoundedThreadPool(numberOfThreads, threadFactory);
- }
-
- //TODO Might want to switch these to use Metrics class Meter and/or Gauge instead.
- private final Counter submitted = new Counter();
- private final Counter taken = new Counter();
-
- @Override
- public Future<?> submit(Runnable task) {
- submitted.add(1);
- return super.submit(task);
- }
-
- @Override
- public <T> Future<T> submit(Runnable task, T result) {
- submitted.add(1);
- return super.submit(task, result);
- }
-
- @Override
- public void execute(Runnable command) {
- submitted.add(1);
- super.execute(command);
- }
-
- @Override
- public <T> Future<T> submit(Callable<T> task) {
- submitted.add(1);
- return super.submit(task);
- }
-
-
- @Override
- protected void beforeExecute(Thread t, Runnable r) {
- super.beforeExecute(t, r);
- taken.add(1);
- periodicallyPrintStats();
- updateLoad();
- }
-
- // TODO schedule this with a fixed delay from a scheduled executor
- private final AtomicLong lastPrinted = new AtomicLong(0L);
-
- private void periodicallyPrintStats() {
- long now = System.currentTimeMillis();
- long prev = lastPrinted.get();
- if (now - prev > STATS_INTERVAL) {
- if (lastPrinted.compareAndSet(prev, now)) {
- log.debug("queue size: {} jobs, submitted: {} jobs/s, taken: {} jobs/s",
- getQueue().size(),
- submitted.throughput(), taken.throughput());
- submitted.reset();
- taken.reset();
- }
- }
- }
-
- // TODO consider updating load whenever queue changes
- private void updateLoad() {
- underHighLoad.set(getQueue().remainingCapacity() / (double) maxQueueSize < 0.2);
- }
-
- /**
- * Feedback policy that delays the caller's thread until the executor's work
- * queue falls below a threshold, then runs the job on the caller's thread.
- */
- private static final class CallerFeedbackPolicy implements RejectedExecutionHandler {
-
- private final BlockingBoolean underLoad = new BlockingBoolean(false);
-
- public BlockingBoolean load() {
- return underLoad;
- }
-
- /**
- * Executes task r in the caller's thread, unless the executor
- * has been shut down, in which case the task is discarded.
- *
- * @param r the runnable task requested to be executed
- * @param e the executor attempting to execute this task
- */
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- if (!e.isShutdown()) {
- // Wait for up to 1 second while the queue drains...
- boolean notified = false;
- try {
- notified = underLoad.await(false, 1, TimeUnit.SECONDS);
- } catch (InterruptedException exception) {
- log.debug("Got exception waiting for notification:", exception);
- } finally {
- if (!notified) {
- log.info("Waited for 1 second on {}. Proceeding with work...",
- Thread.currentThread().getName());
- } else {
- log.info("FIXME we got a notice");
- }
- }
- // Do the work on the submitter's thread
- r.run();
- }
- }
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ByteArraySizeHashPrinter.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ByteArraySizeHashPrinter.java
deleted file mode 100644
index cc39ce28..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ByteArraySizeHashPrinter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import java.util.Arrays;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Helper to print byte[] length and hashCode.
- */
-public final class ByteArraySizeHashPrinter {
-
- private final byte[] bytes;
-
- /**
- * Returns ByteArraySizeHashPrinter wrapping given byte[].
- *
- * @param bytes bytes to wrap around
- * @return ByteArraySizeHashPrinter
- */
- public static ByteArraySizeHashPrinter of(byte[] bytes) {
- return new ByteArraySizeHashPrinter(bytes);
- }
-
- /**
- * Returns ByteArraySizeHashPrinter wrapping given byte[].
- *
- * @param bytes bytes to wrap around
- * @return null if {@code bytes == null}, ByteArraySizeHashPrinter otherwise
- */
- public static ByteArraySizeHashPrinter orNull(byte[] bytes) {
- if (bytes == null) {
- return null;
- }
- return new ByteArraySizeHashPrinter(bytes);
- }
-
- public ByteArraySizeHashPrinter(byte[] bytes) {
- this.bytes = bytes;
- }
-
- @Override
- public String toString() {
- ToStringHelper helper = MoreObjects.toStringHelper("byte[]");
- if (bytes != null) {
- helper.add("length", bytes.length)
- .add("hash", Arrays.hashCode(bytes));
- } else {
- helper.addValue(bytes);
- }
- return helper.toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Counter.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Counter.java
deleted file mode 100644
index bde28783..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Counter.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * Counting mechanism capable of tracking occurrences and rates.
- */
-public class Counter {
-
- private long total = 0;
- private long start = System.currentTimeMillis();
- private long end = 0;
-
- /**
- * Creates a new counter.
- */
- public Counter() {
- }
-
- /**
- * Creates a new counter in a specific state. If non-zero end time is
- * specified, the counter will be frozen.
- *
- * @param start start time
- * @param total total number of items to start with
- * @param end end time; if non-ze
- */
- public Counter(long start, long total, long end) {
- checkArgument(start <= end, "Malformed interval: start > end");
- checkArgument(total >= 0, "Total must be non-negative");
- this.start = start;
- this.total = total;
- this.end = end;
- }
-
- /**
- * Resets the counter, by zeroing out the count and restarting the timer.
- */
- public synchronized void reset() {
- end = 0;
- total = 0;
- start = System.currentTimeMillis();
- }
-
- /**
- * Freezes the counter in the current state including the counts and times.
- */
- public synchronized void freeze() {
- end = System.currentTimeMillis();
- }
-
- /**
- * Adds the specified number of occurrences to the counter. No-op if the
- * counter has been frozen.
- *
- * @param count number of occurrences
- */
- public synchronized void add(long count) {
- checkArgument(count >= 0, "Count must be non-negative");
- if (end == 0L) {
- total += count;
- }
- }
-
- /**
- * Returns the number of occurrences per second.
- *
- * @return throughput in occurrences per second
- */
- public synchronized double throughput() {
- return total / duration();
- }
-
- /**
- * Returns the total number of occurrences counted.
- *
- * @return number of counted occurrences
- */
- public synchronized long total() {
- return total;
- }
-
- /**
- * Returns the duration expressed in fractional number of seconds.
- *
- * @return fractional number of seconds since the last reset
- */
- public synchronized double duration() {
- // Protect against 0 return by artificially setting duration to 1ms
- long duration = (end == 0L ? System.currentTimeMillis() : end) - start;
- return (duration == 0 ? 1 : duration) / 1000.0;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(total, start, end);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Counter) {
- final Counter other = (Counter) obj;
- return Objects.equals(this.total, other.total) &&
- Objects.equals(this.start, other.start) &&
- Objects.equals(this.end, other.end);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this)
- .add("total", total)
- .add("start", start)
- .add("end", end)
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DataRateUnit.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DataRateUnit.java
deleted file mode 100644
index d49ed7b5..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DataRateUnit.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.onlab.util;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Data rate unit.
- */
-@Beta
-public enum DataRateUnit {
- /**
- * Bit per second.
- */
- BPS(1L),
- /**
- * Kilobit per second.
- * (Decimal/SI)
- */
- KBPS(1_000L),
- /**
- * Megabit per second.
- * (Decimal/SI)
- */
- MBPS(1_000_000L),
- /**
- * Gigabit per second.
- * (Decimal/SI)
- */
- GBPS(1_000_000_000L);
-
- private final long multiplier;
-
- DataRateUnit(long multiplier) {
- this.multiplier = multiplier;
- }
-
- /**
- * Returns the multiplier to use, when converting value of this unit to bps.
- *
- * @return multiplier
- */
- public long multiplier() {
- return multiplier;
- }
-
- /**
- * Converts given value in this unit to bits per seconds.
- *
- * @param v data rate value
- * @return {@code v} in bits per seconds
- */
- public long toBitsPerSecond(long v) {
- return v * multiplier;
- }
-
- /**
- * Converts given value in this unit to bits per seconds.
- *
- * @param v data rate value
- * @return {@code v} in bits per seconds
- */
- public double toBitsPerSecond(double v) {
- return v * multiplier;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DefaultHashMap.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DefaultHashMap.java
deleted file mode 100644
index d6ddbd56..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/DefaultHashMap.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import java.util.HashMap;
-
-/**
- * HashMap that returns a default value for unmapped keys.
- */
-public final class DefaultHashMap<K, V> extends HashMap<K, V> {
-
- /** Default value to return when no key binding exists. */
- protected final V defaultValue;
-
- /**
- * Constructs an empty map with the given default value.
- *
- * @param defaultValue the default value
- */
- public DefaultHashMap(V defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- @Override
- public V get(Object k) {
- return containsKey(k) ? super.get(k) : defaultValue;
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Frequency.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Frequency.java
deleted file mode 100644
index 1ef71130..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Frequency.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ComparisonChain;
-
-/**
- * Class representing frequency. This class is intended to be used for a value whose unit is Hz
- * and its family (KHz, MHz, etc.).
- *
- * <p>
- * Note: this class is mainly intended to be used for lambda, which
- * represents THz order. Long has enough space to represent over THz frequency as Hz,
- * and the underlying value is long as Hz. This means this class can't represent
- * sub-Hz accuracy.
- * </p>
- */
-public final class Frequency implements RichComparable<Frequency> {
-
- private static final long KHZ = 1_000L;
- private static final long MHZ = 1_000_000L;
- private static final long GHZ = 1_000_000_000L;
- private static final long THZ = 1_000_000_000_000L;
-
- private final long frequency; // frequency in Hz
-
- /**
- * Creates an instance representing the specified frequency in Hz.
- *
- * @param frequency frequency in Hz
- */
- private Frequency(long frequency) {
- this.frequency = frequency;
- }
-
- /**
- * Return the value this instance represents as Hz.
- *
- * @return frequency in Hz
- */
- public long asHz() {
- return frequency;
- }
-
- /**
- * Returns an instance representing the specified value in Hz.
- *
- * @param value frequency in Hz
- * @return instance representing the given frequency
- */
- public static Frequency ofHz(long value) {
- return new Frequency(value);
- }
-
- /**
- * Returns an instance representing the specified value in KHz.
- *
- * @param value frequency in KHz
- * @return instance representing the given frequency
- */
- public static Frequency ofKHz(double value) {
- return new Frequency((long) (value * KHZ));
- }
-
- /**
- * Returns an instance representing the specified value in MHz.
- *
- * @param value frequency in MHz
- * @return instance representing the given frequency
- */
- public static Frequency ofMHz(double value) {
- return new Frequency((long) (value * MHZ));
- }
-
- /**
- * Returns an instance representing the specified value in GHz.
- *
- * @param value frequency in GHz
- * @return instance representing the given frequency
- */
- public static Frequency ofGHz(double value) {
- return new Frequency((long) (value * GHZ));
- }
-
- /**
- * Returns an instance representing the specified value in THz.
- *
- * @param value frequency in THz
- * @return instance representing the given frequency
- */
- public static Frequency ofTHz(double value) {
- return new Frequency((long) (value * THZ));
- }
-
- /**
- * Returns a Frequency whose value is (this + value).
- *
- * @param value value to be added to this Frequency
- * @return this + value
- */
- public Frequency add(Frequency value) {
- return new Frequency(this.frequency + value.frequency);
- }
-
- /**
- * Returns a Frequency whose value is (this - value).
- *
- * @param value value to be subtracted from this Frequency
- * @return this - value
- */
- public Frequency subtract(Frequency value) {
- return new Frequency(this.frequency - value.frequency);
- }
-
- /**
- * Returns a Frequency whose value is (this * value).
- *
- * @param value value to be multiplied by this Frequency
- * @return this * value
- */
- public Frequency multiply(long value) {
- return new Frequency(this.frequency * value);
- }
-
- /**
- * Returns a Frequency whose value is Math.floorDiv(this, value).
- *
- * @param value value to be divided by this Frequency
- * @return Math.floorDiv(this, value)
- */
- public Frequency floorDivision(long value) {
- return new Frequency(Math.floorDiv(this.frequency, value));
- }
-
- @Override
- public int compareTo(Frequency other) {
- return ComparisonChain.start()
- .compare(this.frequency, other.frequency)
- .result();
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(frequency);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (!(obj instanceof Frequency)) {
- return false;
- }
-
- final Frequency other = (Frequency) obj;
- return this.frequency == other.frequency;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("frequency", frequency + "Hz")
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GeoLocation.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GeoLocation.java
deleted file mode 100644
index 7e546531..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GeoLocation.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Geo location specified in terms of longitude and latitude.
- */
-public class GeoLocation {
-
- public static final double EARTH_RADIUS_KM = 6378.1370D;
-
- private final double latitude;
- private final double longitude;
-
- /**
- * Creates a new location using the specified coordinates.
- *
- * @param latitude latitude line
- * @param longitude longitude line
- */
- public GeoLocation(double latitude, double longitude) {
- this.latitude = latitude;
- this.longitude = longitude;
- }
-
- /**
- * Returns the latitude of this location.
- *
- * @return latitude
- */
- public double latitude() {
- return latitude;
- }
-
- /**
- * Returns the longitude of this location.
- *
- * @return longitude
- */
- public double longitude() {
- return longitude;
- }
-
- /**
- * Returns the distance in kilometers, between this location and another.
- *
- * @param other other geo location
- * @return distance in kilometers
- */
- public double kilometersTo(GeoLocation other) {
- double hereLat = Math.toRadians(latitude);
- double hereLon = Math.toRadians(longitude);
- double thereLat = Math.toRadians(other.latitude);
- double thereLon = Math.toRadians(other.longitude);
-
- double cos = Math.sin(hereLat) * Math.sin(thereLat) +
- Math.cos(hereLat) * Math.cos(thereLat) * Math.cos(hereLon - thereLon);
- return Math.acos(cos) * EARTH_RADIUS_KM;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("latitude", latitude)
- .add("longitude", longitude)
- .toString();
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GroupedThreadFactory.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GroupedThreadFactory.java
deleted file mode 100644
index 9001cf5f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/GroupedThreadFactory.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.apache.commons.lang3.concurrent.ConcurrentUtils;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ThreadFactory;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Thread factory for creating threads that belong to the specified thread group.
- */
-public final class GroupedThreadFactory implements ThreadFactory {
-
- public static final String DELIMITER = "/";
-
- private final ThreadGroup group;
-
- // Cache of created thread factories.
- private static final ConcurrentHashMap<String, GroupedThreadFactory> FACTORIES =
- new ConcurrentHashMap<>();
-
- /**
- * Returns thread factory for producing threads associated with the specified
- * group name. The group name-space is hierarchical, based on slash-delimited
- * name segments, e.g. {@code onos/intent}.
- *
- * @param groupName group name
- * @return thread factory
- */
- public static GroupedThreadFactory groupedThreadFactory(String groupName) {
- GroupedThreadFactory factory = FACTORIES.get(groupName);
- if (factory != null) {
- return factory;
- }
-
- // Find the parent group or root the group hierarchy under default group.
- int i = groupName.lastIndexOf(DELIMITER);
- if (i > 0) {
- String name = groupName.substring(0, i);
- ThreadGroup parentGroup = groupedThreadFactory(name).threadGroup();
- factory = new GroupedThreadFactory(new ThreadGroup(parentGroup, groupName));
- } else {
- factory = new GroupedThreadFactory(new ThreadGroup(groupName));
- }
-
- return ConcurrentUtils.putIfAbsent(FACTORIES, groupName, factory);
- }
-
- // Creates a new thread group
- private GroupedThreadFactory(ThreadGroup group) {
- this.group = group;
- }
-
- /**
- * Returns the thread group associated with the factory.
- *
- * @return thread group
- */
- public ThreadGroup threadGroup() {
- return group;
- }
-
- @Override
- public Thread newThread(Runnable r) {
- return new Thread(group, r);
- }
-
- @Override
- public String toString() {
- return toStringHelper(this).add("group", group).toString();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexDump.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexDump.java
deleted file mode 100755
index cfb79390..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexDump.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * HexDump class an utility to dump buffer in hex format.
- */
-public final class HexDump {
- protected static final Logger log = LoggerFactory.getLogger(HexDump.class);
-
- private HexDump() {
- }
-
- /**
- * Dump the buffer content in hex format.
- *
- * @param buff buffer content to dump in hex format
- */
- public static void dump(ChannelBuffer buff) {
- try {
- byte[] yTemp;
- yTemp = buff.array();
-
- int iStartIndex = buff.readerIndex();
- int iEndIndex = buff.writerIndex();
- do {
- StringBuilder sb = new StringBuilder();
- for (int k = 0; (k < 16) && (iStartIndex < iEndIndex); ++k) {
- if (0 == k % 4) {
- sb.append(String.format(" ")); // blank after 4 bytes
- }
- sb.append(String.format("%02X ", yTemp[iStartIndex++]));
- }
- log.debug(sb.toString());
- } while (iStartIndex < iEndIndex);
- } catch (Exception e) {
- log.error("[HexDump] Invalid buffer: " + e.toString());
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexString.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexString.java
deleted file mode 100644
index 962e1119..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/HexString.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-public final class HexString {
-
- private HexString() {
- }
-
- /**
- * Convert a byte array to a colon-separated hex string.
- *
- * @param bytes byte array to be converted
- * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef",
- * or "(null)" if given byte array is null
- */
- public static String toHexString(final byte[] bytes) {
- return toHexString(bytes, ":");
- }
-
- /**
- * Convert a byte array to a hex string separated by given separator.
- *
- * @param bytes byte array to be converted
- * @param separator the string use to separate each byte
- * @return converted hex string, or "(null)" if given byte array is null
- */
- public static String toHexString(final byte[] bytes, String separator) {
- if (bytes == null) {
- return "(null)";
- }
- if (separator == null) {
- separator = "";
- }
- int i;
- StringBuilder ret = new StringBuilder(bytes.length * 3 - 1);
- String tmp;
- for (i = 0; i < bytes.length; i++) {
- if (i > 0) {
- ret.append(separator);
- }
- tmp = Integer.toHexString((bytes[i] & 0xff));
- if (tmp.length() == 1) {
- ret.append('0');
- }
- ret.append(tmp);
- }
- return ret.toString();
- }
-
- /**
- * Convert a long number to colon-separated hex string.
- * Prepend zero padding until given length.
- *
- * @param val long number to be converted
- * @param padTo prepend zeros until this length
- * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef"
- */
- public static String toHexString(final long val, final int padTo) {
- char[] arr = Long.toHexString(val).toCharArray();
- StringBuilder ret = new StringBuilder(padTo * 3 - 1);
- // prepend the right number of leading zeros
- int i = 0;
- for (; i < (padTo * 2 - arr.length); i++) {
- ret.append('0');
- if ((i % 2) != 0) {
- ret.append(':');
- }
- }
- for (int j = 0; j < arr.length; j++) {
- ret.append(arr[j]);
- if ((((i + j) % 2) != 0) && (j < (arr.length - 1))) {
- ret.append(':');
- }
- }
- return ret.toString();
- }
-
- /**
- * Convert a long number to colon-separated hex string.
- * Prepend zero padding until 8 bytes.
- *
- * @param val long number to be converted
- * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef"
- */
- public static String toHexString(final long val) {
- return toHexString(val, 8);
- }
-
- /**
- * Convert a colon-separated hex string to byte array.
- *
- * @param values colon-separated hex string to be converted,
- * e.g. "0f:ca:fe:de:ad:be:ef"
- * @return converted byte array
- * @throws NumberFormatException if input hex string cannot be parsed
- */
- public static byte[] fromHexString(final String values) {
- String[] octets = values.split(":");
- byte[] ret = new byte[octets.length];
-
- for (int i = 0; i < octets.length; i++) {
- if (octets[i].length() > 2) {
- throw new NumberFormatException("Invalid octet length");
- }
- ret[i] = Integer.valueOf(octets[i], 16).byteValue();
- }
- return ret;
- }
-
- /**
- * Convert a colon-separated hex string to long.
- *
- * @param value colon-separated hex string to be converted,
- * e.g. "00:0f:ca:fe:de:ad:be:ef"
- * @return converted long number
- * @throws NumberFormatException if input hex string cannot be parsed
- */
- public static long toLong(String value) {
- String[] octets = value.split(":");
- if (octets.length > 8) {
- throw new NumberFormatException("Input string is too big to fit in long: " + value);
- }
- long l = 0;
- for (String octet: octets) {
- if (octet.length() > 2) {
- throw new NumberFormatException(
- "Each colon-separated byte component must consist of 1 or 2 hex digits: " + value);
- }
- short s = Short.parseShort(octet, 16);
- l = (l << 8) + s;
- }
- return l;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ItemNotFoundException.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ItemNotFoundException.java
deleted file mode 100644
index 01440abf..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/ItemNotFoundException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-/**
- * Represents condition where an item is not found or not available.
- */
-public class ItemNotFoundException extends RuntimeException {
-
- /**
- * Creates a new exception with no message.
- */
- public ItemNotFoundException() {
- }
-
- /**
- * Creates a new exception with the supplied message.
- * @param message error message
- */
- public ItemNotFoundException(String message) {
- super(message);
- }
-
- /**
- * Creates a new exception with the supplied message and cause.
- * @param message error message
- * @param cause cause of the error
- */
- public ItemNotFoundException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java
deleted file mode 100644
index 9977e35d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.lang3.tuple.Pair;
-
-import com.esotericsoftware.kryo.Kryo;
-import com.esotericsoftware.kryo.Serializer;
-import com.esotericsoftware.kryo.io.ByteBufferInput;
-import com.esotericsoftware.kryo.io.ByteBufferOutput;
-import com.esotericsoftware.kryo.io.Input;
-import com.esotericsoftware.kryo.pool.KryoCallback;
-import com.esotericsoftware.kryo.pool.KryoFactory;
-import com.esotericsoftware.kryo.pool.KryoPool;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
-
-/**
- * Pool of Kryo instances, with classes pre-registered.
- */
-//@ThreadSafe
-public final class KryoNamespace implements KryoFactory, KryoPool {
-
- /**
- * Default buffer size used for serialization.
- *
- * @see #serialize(Object)
- */
- public static final int DEFAULT_BUFFER_SIZE = 4096;
- public static final int MAX_BUFFER_SIZE = 100 * 1000 * 1000;
-
- /**
- * ID to use if this KryoNamespace does not define registration id.
- */
- public static final int FLOATING_ID = -1;
-
- /**
- * Smallest ID free to use for user defined registrations.
- */
- public static final int INITIAL_ID = 11;
-
-
- private final KryoPool pool = new KryoPool.Builder(this)
- .softReferences()
- .build();
-
- private final ImmutableList<RegistrationBlock> registeredBlocks;
-
- private final boolean registrationRequired;
-
-
- /**
- * KryoNamespace builder.
- */
- //@NotThreadSafe
- public static final class Builder {
-
- private int blockHeadId = INITIAL_ID;
- private List<Pair<Class<?>, Serializer<?>>> types = new ArrayList<>();
- private List<RegistrationBlock> blocks = new ArrayList<>();
- private boolean registrationRequired = true;
-
- /**
- * Builds a {@link KryoNamespace} instance.
- *
- * @return KryoNamespace
- */
- public KryoNamespace build() {
- if (!types.isEmpty()) {
- blocks.add(new RegistrationBlock(this.blockHeadId, types));
- }
- return new KryoNamespace(blocks, registrationRequired).populate(1);
- }
-
- /**
- * Sets the next Kryo registration Id for following register entries.
- *
- * @param id Kryo registration Id
- * @return this
- *
- * @see Kryo#register(Class, Serializer, int)
- */
- public Builder nextId(final int id) {
- if (!types.isEmpty()) {
- blocks.add(new RegistrationBlock(this.blockHeadId, types));
- types = new ArrayList<>();
- }
- this.blockHeadId = id;
- return this;
- }
-
- /**
- * Registers classes to be serialized using Kryo default serializer.
- *
- * @param expectedTypes list of classes
- * @return this
- */
- public Builder register(final Class<?>... expectedTypes) {
- for (Class<?> clazz : expectedTypes) {
- types.add(Pair.of(clazz, null));
- }
- return this;
- }
-
- /**
- * Registers a class and it's serializer.
- *
- * @param classes list of classes to register
- * @param serializer serializer to use for the class
- * @return this
- */
- public Builder register(Serializer<?> serializer, final Class<?>... classes) {
- for (Class<?> clazz : classes) {
- types.add(Pair.of(clazz, serializer));
- }
- return this;
- }
-
- private Builder register(RegistrationBlock block) {
- if (block.begin() != FLOATING_ID) {
- // flush pending types
- nextId(block.begin());
- blocks.add(block);
- nextId(block.begin() + block.types().size());
- } else {
- // flush pending types
- final int addedBlockBegin = blockHeadId + types.size();
- nextId(addedBlockBegin);
- blocks.add(new RegistrationBlock(addedBlockBegin, block.types()));
- nextId(addedBlockBegin + block.types().size());
- }
- return this;
- }
-
- /**
- * Registers all the class registered to given KryoNamespace.
- *
- * @param ns KryoNamespace
- * @return this
- */
- public Builder register(final KryoNamespace ns) {
- for (RegistrationBlock block : ns.registeredBlocks) {
- this.register(block);
- }
- return this;
- }
-
- /**
- * Sets the registrationRequired flag.
- *
- * @param registrationRequired Kryo's registrationRequired flag
- * @return this
- *
- * @see Kryo#setRegistrationRequired(boolean)
- */
- public Builder setRegistrationRequired(boolean registrationRequired) {
- this.registrationRequired = registrationRequired;
- return this;
- }
- }
-
- /**
- * Creates a new {@link KryoNamespace} builder.
- *
- * @return builder
- */
- public static Builder newBuilder() {
- return new Builder();
- }
-
- /**
- * Creates a Kryo instance pool.
- *
- * @param registeredTypes types to register
- * @param registrationRequired
- */
- private KryoNamespace(final List<RegistrationBlock> registeredTypes, boolean registrationRequired) {
- this.registeredBlocks = ImmutableList.copyOf(registeredTypes);
- this.registrationRequired = registrationRequired;
- }
-
- /**
- * Populates the Kryo pool.
- *
- * @param instances to add to the pool
- * @return this
- */
- public KryoNamespace populate(int instances) {
-
- for (int i = 0; i < instances; ++i) {
- release(create());
- }
- return this;
- }
-
- /**
- * Serializes given object to byte array using Kryo instance in pool.
- * <p>
- * Note: Serialized bytes must be smaller than {@link #MAX_BUFFER_SIZE}.
- *
- * @param obj Object to serialize
- * @return serialized bytes
- */
- public byte[] serialize(final Object obj) {
- return serialize(obj, DEFAULT_BUFFER_SIZE);
- }
-
- /**
- * Serializes given object to byte array using Kryo instance in pool.
- *
- * @param obj Object to serialize
- * @param bufferSize maximum size of serialized bytes
- * @return serialized bytes
- */
- public byte[] serialize(final Object obj, final int bufferSize) {
- ByteBufferOutput out = new ByteBufferOutput(bufferSize, MAX_BUFFER_SIZE);
- try {
- Kryo kryo = borrow();
- try {
- kryo.writeClassAndObject(out, obj);
- out.flush();
- return out.toBytes();
- } finally {
- release(kryo);
- }
- } finally {
- out.release();
- }
- }
-
- /**
- * Serializes given object to byte buffer using Kryo instance in pool.
- *
- * @param obj Object to serialize
- * @param buffer to write to
- */
- public void serialize(final Object obj, final ByteBuffer buffer) {
- ByteBufferOutput out = new ByteBufferOutput(buffer);
- Kryo kryo = borrow();
- try {
- kryo.writeClassAndObject(out, obj);
- out.flush();
- } finally {
- release(kryo);
- }
- }
-
- /**
- * Serializes given object to OutputStream using Kryo instance in pool.
- *
- * @param obj Object to serialize
- * @param stream to write to
- */
- public void serialize(final Object obj, final OutputStream stream) {
- serialize(obj, stream, DEFAULT_BUFFER_SIZE);
- }
-
- /**
- * Serializes given object to OutputStream using Kryo instance in pool.
- *
- * @param obj Object to serialize
- * @param stream to write to
- * @param bufferSize size of the buffer in front of the stream
- */
- public void serialize(final Object obj, final OutputStream stream, final int bufferSize) {
- ByteBufferOutput out = new ByteBufferOutput(stream, bufferSize);
- Kryo kryo = borrow();
- try {
- kryo.writeClassAndObject(out, obj);
- out.flush();
- } finally {
- release(kryo);
- }
- }
-
- /**
- * Deserializes given byte array to Object using Kryo instance in pool.
- *
- * @param bytes serialized bytes
- * @param <T> deserialized Object type
- * @return deserialized Object
- */
- public <T> T deserialize(final byte[] bytes) {
- Input in = new Input(bytes);
- Kryo kryo = borrow();
- try {
- @SuppressWarnings("unchecked")
- T obj = (T) kryo.readClassAndObject(in);
- return obj;
- } finally {
- release(kryo);
- }
- }
-
- /**
- * Deserializes given byte buffer to Object using Kryo instance in pool.
- *
- * @param buffer input with serialized bytes
- * @param <T> deserialized Object type
- * @return deserialized Object
- */
- public <T> T deserialize(final ByteBuffer buffer) {
- ByteBufferInput in = new ByteBufferInput(buffer);
- Kryo kryo = borrow();
- try {
- @SuppressWarnings("unchecked")
- T obj = (T) kryo.readClassAndObject(in);
- return obj;
- } finally {
- release(kryo);
- }
- }
-
- /**
- * Deserializes given InputStream to an Object using Kryo instance in pool.
- *
- * @param stream input stream
- * @param <T> deserialized Object type
- * @return deserialized Object
- */
- public <T> T deserialize(final InputStream stream) {
- return deserialize(stream, DEFAULT_BUFFER_SIZE);
- }
-
- /**
- * Deserializes given InputStream to an Object using Kryo instance in pool.
- *
- * @param stream input stream
- * @param <T> deserialized Object type
- * @return deserialized Object
- * @param bufferSize size of the buffer in front of the stream
- */
- public <T> T deserialize(final InputStream stream, final int bufferSize) {
- ByteBufferInput in = new ByteBufferInput(stream, bufferSize);
- Kryo kryo = borrow();
- try {
- @SuppressWarnings("unchecked")
- T obj = (T) kryo.readClassAndObject(in);
- return obj;
- } finally {
- release(kryo);
- }
- }
-
- /**
- * Creates a Kryo instance.
- *
- * @return Kryo instance
- */
- @Override
- public Kryo create() {
- Kryo kryo = new Kryo();
- kryo.setRegistrationRequired(registrationRequired);
- for (RegistrationBlock block : registeredBlocks) {
- int id = block.begin();
- if (id == FLOATING_ID) {
- id = kryo.getNextRegistrationId();
- }
- for (Pair<Class<?>, Serializer<?>> entry : block.types()) {
- final Serializer<?> serializer = entry.getRight();
- if (serializer == null) {
- kryo.register(entry.getLeft(), id++);
- } else {
- kryo.register(entry.getLeft(), serializer, id++);
- }
- }
- }
- return kryo;
- }
-
- @Override
- public Kryo borrow() {
- return pool.borrow();
- }
-
- @Override
- public void release(Kryo kryo) {
- pool.release(kryo);
- }
-
- @Override
- public <T> T run(KryoCallback<T> callback) {
- return pool.run(callback);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("registeredBlocks", registeredBlocks)
- .toString();
- }
-
- static final class RegistrationBlock {
- private final int begin;
- private final ImmutableList<Pair<Class<?>, Serializer<?>>> types;
-
- public RegistrationBlock(int begin, List<Pair<Class<?>, Serializer<?>>> types) {
- this.begin = begin;
- this.types = ImmutableList.copyOf(types);
- }
-
- public int begin() {
- return begin;
- }
-
- public ImmutableList<Pair<Class<?>, Serializer<?>>> types() {
- return types;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("begin", begin)
- .add("types", types)
- .toString();
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/NewConcurrentHashMap.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/NewConcurrentHashMap.java
deleted file mode 100644
index 2d222eac..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/NewConcurrentHashMap.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.commons.lang3.concurrent.ConcurrentInitializer;
-
-/**
- * Creates an instance of new ConcurrentHashMap on each {@link #get()} call.
- * <p>
- * To be used with
- * {@link org.apache.commons.lang3.concurrent.ConcurrentUtils#createIfAbsent}
- * </p>
- *
- * @param <K> ConcurrentHashMap key type
- * @param <V> ConcurrentHashMap value type
- */
-public final class NewConcurrentHashMap<K, V>
- implements ConcurrentInitializer<ConcurrentMap<K, V>> {
-
- public static final NewConcurrentHashMap<?, ?> INSTANCE = new NewConcurrentHashMap<>();
-
- @SuppressWarnings("unchecked")
- public static <K, V> NewConcurrentHashMap<K, V> ifNeeded() {
- return (NewConcurrentHashMap<K, V>) INSTANCE;
- }
-
- @Override
- public ConcurrentMap<K, V> get() {
- return new ConcurrentHashMap<>();
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/PositionalParameterStringFormatter.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/PositionalParameterStringFormatter.java
deleted file mode 100644
index 647e0c0d..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/PositionalParameterStringFormatter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-/**
- * Allows slf4j style formatting of parameters into a string.
- */
-public final class PositionalParameterStringFormatter {
-
- /**
- * Hide default constructor.
- */
- private PositionalParameterStringFormatter() {
- }
-
- /**
- * Formats a string using slf4j style positional parameter replacement.
- * Instances of "{}" in the source string are replaced in order by the
- * specified parameter values as strings.
- *
- * @param source original string to format
- * @param parameters list of parameters that will be substituted
- * @return formatted string
- */
- public static String format(String source, Object... parameters) {
- String current = source;
- for (Object parameter : parameters) {
- if (!current.contains("{}")) {
- return current;
- }
- current = current.replaceFirst("\\{\\}", String.valueOf(parameter));
- }
- return current;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RetryingFunction.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RetryingFunction.java
deleted file mode 100644
index 484e236f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RetryingFunction.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.function.Function;
-
-import com.google.common.base.Throwables;
-
-/**
- * Function that retries execution on failure.
- *
- * @param <U> input type
- * @param <V> output type
- */
-public class RetryingFunction<U, V> implements Function<U, V> {
-
- private final Function<U, V> baseFunction;
- private final Class<? extends Throwable> exceptionClass;
- private final int maxRetries;
- private final int maxDelayBetweenRetries;
-
- public RetryingFunction(Function<U, V> baseFunction,
- Class<? extends Throwable> exceptionClass,
- int maxRetries,
- int maxDelayBetweenRetries) {
- this.baseFunction = baseFunction;
- this.exceptionClass = exceptionClass;
- this.maxRetries = maxRetries;
- this.maxDelayBetweenRetries = maxDelayBetweenRetries;
- }
-
- @Override
- public V apply(U input) {
- int retryAttempts = 0;
- while (true) {
- try {
- return baseFunction.apply(input);
- } catch (Throwable t) {
- if (!exceptionClass.isAssignableFrom(t.getClass()) || retryAttempts == maxRetries) {
- Throwables.propagate(t);
- }
- Tools.randomDelay(maxDelayBetweenRetries);
- retryAttempts++;
- }
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RichComparable.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RichComparable.java
deleted file mode 100644
index 8a49bba9..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/RichComparable.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Extends useful methods for comparison to {@link Comparable} interface.
- *
- * @param <T> type of instance to be compared
- */
-public interface RichComparable<T> extends Comparable<T> {
- /**
- * Compares if this object is less than the specified object.
- *
- * @param other the object to be compared
- * @return true if this object is less than the specified object
- */
- default boolean isLessThan(T other) {
- return compareTo(checkNotNull(other)) < 0;
- }
-
- /**
- * Compares if this object is greater than the specified object.
- *
- * @param other the object to be compared
- * @return true if this object is less thant the specified object
- */
- default boolean isGreaterThan(T other) {
- return compareTo(checkNotNull(other)) > 0;
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutorService.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutorService.java
deleted file mode 100644
index 051155ce..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutorService.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Executor service wrapper for shared executors with safeguards on shutdown
- * to prevent inadvertent shutdown.
- */
-class SharedExecutorService implements ExecutorService {
-
- private static final String NOT_ALLOWED = "Shutdown of shared executor is not allowed";
-
- private ExecutorService executor;
-
- /**
- * Creates a wrapper for the given executor service.
- *
- * @param executor executor service to wrap
- */
- SharedExecutorService(ExecutorService executor) {
- this.executor = executor;
- }
-
- /**
- * Returns the backing executor service.
- *
- * @return backing executor service
- */
- ExecutorService backingExecutor() {
- return executor;
- }
-
- /**
- * Swaps the backing executor with a new one and shuts down the old one.
- *
- * @param executor new executor service
- */
- void setBackingExecutor(ExecutorService executor) {
- ExecutorService oldExecutor = this.executor;
- this.executor = executor;
- oldExecutor.shutdown();
- }
-
- @Override
- public void shutdown() {
- throw new UnsupportedOperationException(NOT_ALLOWED);
- }
-
- @Override
- public List<Runnable> shutdownNow() {
- throw new UnsupportedOperationException(NOT_ALLOWED);
- }
-
- @Override
- public boolean isShutdown() {
- return executor.isShutdown();
- }
-
- @Override
- public boolean isTerminated() {
- return executor.isTerminated();
- }
-
- @Override
- public boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException {
- return executor.awaitTermination(timeout, unit);
- }
-
- @Override
- public <T> Future<T> submit(Callable<T> task) {
- return executor.submit(task);
- }
-
- @Override
- public <T> Future<T> submit(Runnable task, T result) {
- return executor.submit(task, result);
- }
-
- @Override
- public Future<?> submit(Runnable task) {
- return executor.submit(task);
- }
-
- @Override
- public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
- throws InterruptedException {
- return executor.invokeAll(tasks);
- }
-
- @Override
- public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException {
- return executor.invokeAll(tasks, timeout, unit);
- }
-
- @Override
- public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
- throws InterruptedException, ExecutionException {
- return executor.invokeAny(tasks);
- }
-
- @Override
- public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
- long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException {
- return executor.invokeAny(tasks, timeout, unit);
- }
-
- @Override
- public void execute(Runnable command) {
- executor.execute(command);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutors.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutors.java
deleted file mode 100644
index 0dadce85..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SharedExecutors.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import java.util.Timer;
-import java.util.concurrent.ExecutorService;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.concurrent.Executors.newFixedThreadPool;
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-
-/**
- * Utility for managing a set of shared execution resources, such as a timer,
- * single thread executor and thread pool executor for use by various parts of
- * the platform or by applications.
- * <p>
- * Whenever possible, use of these shared resources is encouraged over creating
- * separate ones.
- * </p>
- */
-public final class SharedExecutors {
-
- public static final int DEFAULT_POOL_SIZE = 30;
-
- private static SharedExecutorService singleThreadExecutor =
- new SharedExecutorService(
- newSingleThreadExecutor(groupedThreads("onos/shared",
- "onos-single-executor")));
-
- private static SharedExecutorService poolThreadExecutor =
- new SharedExecutorService(
- newFixedThreadPool(DEFAULT_POOL_SIZE,
- groupedThreads("onos/shared",
- "onos-pool-executor-%d")));
-
- private static SharedTimer sharedTimer = new SharedTimer();
-
- // Ban public construction
- private SharedExecutors() {
- }
-
- /**
- * Returns the shared single thread executor.
- *
- * @return shared single thread executor
- */
- public static ExecutorService getSingleThreadExecutor() {
- return singleThreadExecutor;
- }
-
- /**
- * Returns the shared thread pool executor.
- *
- * @return shared executor pool
- */
- public static ExecutorService getPoolThreadExecutor() {
- return poolThreadExecutor;
- }
-
- /**
- * Returns the shared timer.
- *
- * @return shared timer
- */
- public static Timer getTimer() {
- return sharedTimer;
- }
-
- /**
- * Sets the shared thread pool size.
- *
- * @param poolSize new pool size
- */
- public static void setPoolSize(int poolSize) {
- checkArgument(poolSize > 0, "Shared pool size size must be greater than 0");
- poolThreadExecutor.setBackingExecutor(
- newFixedThreadPool(poolSize, groupedThreads("onos/shared",
- "onos-pool-executor-%d")));
- }
-
- /**
- * Shuts down all shared timers and executors and therefore should be
- * called only by the framework.
- */
- public static void shutdown() {
- sharedTimer.shutdown();
- singleThreadExecutor.backingExecutor().shutdown();
- poolThreadExecutor.backingExecutor().shutdown();
- }
-
- // Timer extension which does not allow outside cancel method.
- private static class SharedTimer extends Timer {
-
- public SharedTimer() {
- super("onos-shared-timer");
- }
-
- @Override
- public void cancel() {
- throw new UnsupportedOperationException("Cancel of shared timer is not allowed");
- }
-
- private void shutdown() {
- super.cancel();
- }
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java
deleted file mode 100644
index 4f0093c0..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * Maintains a sliding window of value counts. The sliding window counter is
- * initialized with a number of window slots. Calls to #incrementCount() will
- * increment the value in the current window slot. Periodically the window
- * slides and the oldest value count is dropped. Calls to #get() will get the
- * total count for the last N window slots.
- */
-public final class SlidingWindowCounter {
-
- private volatile int headSlot;
- private final int windowSlots;
-
- private final List<AtomicLong> counters;
-
- private final ScheduledExecutorService background;
-
- private static final int SLIDE_WINDOW_PERIOD_SECONDS = 1;
-
- /**
- * Creates a new sliding window counter with the given total number of
- * window slots.
- *
- * @param windowSlots total number of window slots
- */
- public SlidingWindowCounter(int windowSlots) {
- checkArgument(windowSlots > 0, "Window size must be a positive integer");
-
- this.windowSlots = windowSlots;
- this.headSlot = 0;
-
- // Initialize each item in the list to an AtomicLong of 0
- this.counters = Collections.nCopies(windowSlots, 0)
- .stream()
- .map(AtomicLong::new)
- .collect(Collectors.toCollection(ArrayList::new));
-
- background = Executors.newSingleThreadScheduledExecutor();
- background.scheduleWithFixedDelay(this::advanceHead, 0,
- SLIDE_WINDOW_PERIOD_SECONDS, TimeUnit.SECONDS);
- }
-
- /**
- * Releases resources used by the SlidingWindowCounter.
- */
- public void destroy() {
- background.shutdownNow();
- }
-
- /**
- * Increments the count of the current window slot by 1.
- */
- public void incrementCount() {
- incrementCount(headSlot, 1);
- }
-
- /**
- * Increments the count of the current window slot by the given value.
- *
- * @param value value to increment by
- */
- public void incrementCount(long value) {
- incrementCount(headSlot, value);
- }
-
- private void incrementCount(int slot, long value) {
- counters.get(slot).addAndGet(value);
- }
-
- /**
- * Gets the total count for the last N window slots.
- *
- * @param slots number of slots to include in the count
- * @return total count for last N slots
- */
- public long get(int slots) {
- checkArgument(slots <= windowSlots,
- "Requested window must be less than the total window slots");
-
- long sum = 0;
-
- for (int i = 0; i < slots; i++) {
- int currentIndex = headSlot - i;
- if (currentIndex < 0) {
- currentIndex = counters.size() + currentIndex;
- }
- sum += counters.get(currentIndex).get();
- }
-
- return sum;
- }
-
- void advanceHead() {
- counters.get(slotAfter(headSlot)).set(0);
- headSlot = slotAfter(headSlot);
- }
-
- private int slotAfter(int slot) {
- return (slot + 1) % windowSlots;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Spectrum.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Spectrum.java
deleted file mode 100644
index ca01c6e3..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Spectrum.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-/**
- * Telecom optical wavelength bands: O, E, S, C, L and U bands.
- *
- * See ITU-T G-Series Recommendations, Supplement 39
- * See ITU-T G.694.1 for center frequency definition.
- */
-public final class Spectrum {
-
- // Center frequency
- public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1);
-
- // O band (original): 1260 to 1360 nm
- public static final Frequency O_BAND_MIN = Frequency.ofTHz(220.436);
- public static final Frequency O_BAND_MAX = Frequency.ofTHz(237.931);
-
- // E band (extended): 1360 to 1460 nm
- public static final Frequency E_BAND_MIN = Frequency.ofTHz(205.337);
- public static final Frequency E_BAND_MAX = Frequency.ofTHz(220.436);
-
- // S band (short wavelength): 1460 to 1530 nm
- public static final Frequency S_BAND_MIN = Frequency.ofTHz(195.943);
- public static final Frequency S_BAND_MAX = Frequency.ofTHz(205.337);
-
- // C band (conventional): 1530 to 1565 nm
- public static final Frequency C_BAND_MIN = Frequency.ofTHz(191.561);
- public static final Frequency C_BAND_MAX = Frequency.ofTHz(195.943);
-
- // L band (long wavelength): 1565 to 1625 nm
- public static final Frequency L_BAND_MIN = Frequency.ofTHz(184.488);
- public static final Frequency L_BAND_MAX = Frequency.ofTHz(191.561);
-
- // U band (ultra-long wavelength): 1625 to 1675 nm
- public static final Frequency U_BAND_MIN = Frequency.ofTHz(178.981);
- public static final Frequency U_BAND_MAX = Frequency.ofTHz(184.488);
-
- private Spectrum() {
- }
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Timer.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Timer.java
deleted file mode 100644
index fe508839..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Timer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.jboss.netty.util.HashedWheelTimer;
-
-/**
- * Hashed-wheel timer singleton. Care must be taken to shutdown the timer
- * only when the VM is ready to exit.
- */
-public final class Timer {
-
- private static volatile HashedWheelTimer timer;
-
- // Ban public construction
- private Timer() {
- }
-
- /**
- * Returns the singleton hashed-wheel timer.
- *
- * @return hashed-wheel timer
- */
- public static HashedWheelTimer getTimer() {
- if (Timer.timer == null) {
- initTimer();
- }
- return Timer.timer;
- }
-
- private static synchronized void initTimer() {
- if (Timer.timer == null) {
- HashedWheelTimer hwTimer = new HashedWheelTimer();
- hwTimer.start();
- Timer.timer = hwTimer;
- }
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Tools.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Tools.java
deleted file mode 100644
index ffefbfd4..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/Tools.java
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import static java.nio.file.Files.delete;
-import static java.nio.file.Files.walkFileTree;
-import static org.onlab.util.GroupedThreadFactory.groupedThreadFactory;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-import org.slf4j.Logger;
-
-import com.google.common.base.Strings;
-import com.google.common.primitives.UnsignedLongs;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
-/**
- * Miscellaneous utility methods.
- */
-public abstract class Tools {
-
- private Tools() {
- }
-
- private static final Logger log = getLogger(Tools.class);
-
- private static Random random = new Random();
-
- /**
- * Returns a thread factory that produces threads named according to the
- * supplied name pattern.
- *
- * @param pattern name pattern
- * @return thread factory
- */
- public static ThreadFactory namedThreads(String pattern) {
- return new ThreadFactoryBuilder()
- .setNameFormat(pattern)
- .setUncaughtExceptionHandler((t, e) -> log.error("Uncaught exception on " + t.getName(), e))
- .build();
- }
-
- /**
- * Returns a thread factory that produces threads named according to the
- * supplied name pattern and from the specified thread-group. The thread
- * group name is expected to be specified in slash-delimited format, e.g.
- * {@code onos/intent}. The thread names will be produced by converting
- * the thread group name into dash-delimited format and pre-pended to the
- * specified pattern.
- *
- * @param groupName group name in slash-delimited format to indicate hierarchy
- * @param pattern name pattern
- * @return thread factory
- */
- public static ThreadFactory groupedThreads(String groupName, String pattern) {
- return new ThreadFactoryBuilder()
- .setThreadFactory(groupedThreadFactory(groupName))
- .setNameFormat(groupName.replace(GroupedThreadFactory.DELIMITER, "-") + "-" + pattern)
- .setUncaughtExceptionHandler((t, e) -> log.error("Uncaught exception on " + t.getName(), e))
- .build();
- }
-
- /**
- * Returns a thread factory that produces threads with MIN_PRIORITY.
- *
- * @param factory backing ThreadFactory
- * @return thread factory
- */
- public static ThreadFactory minPriority(ThreadFactory factory) {
- return new ThreadFactoryBuilder()
- .setThreadFactory(factory)
- .setPriority(Thread.MIN_PRIORITY)
- .build();
- }
-
- /**
- * Returns true if the collection is null or is empty.
- *
- * @param collection collection to test
- * @return true if null or empty; false otherwise
- */
- public static boolean isNullOrEmpty(Collection collection) {
- return collection == null || collection.isEmpty();
- }
-
- /**
- * Returns the specified item if that item is not null; otherwise throws
- * not found exception.
- *
- * @param item item to check
- * @param message not found message
- * @param <T> item type
- * @return item if not null
- * @throws org.onlab.util.ItemNotFoundException if item is null
- */
- public static <T> T nullIsNotFound(T item, String message) {
- if (item == null) {
- throw new ItemNotFoundException(message);
- }
- return item;
- }
-
- /**
- * Returns the specified set if the set is not null and not empty;
- * otherwise throws a not found exception.
- *
- * @param item set to check
- * @param message not found message
- * @param <T> Set item type
- * @return item if not null and not empty
- * @throws org.onlab.util.ItemNotFoundException if set is null or empty
- */
- public static <T> Set<T> emptyIsNotFound(Set<T> item, String message) {
- if (item == null || item.isEmpty()) {
- throw new ItemNotFoundException(message);
- }
- return item;
- }
-
- /**
- * Returns the specified item if that item is not null; otherwise throws
- * bad argument exception.
- *
- * @param item item to check
- * @param message not found message
- * @param <T> item type
- * @return item if not null
- * @throws IllegalArgumentException if item is null
- */
- public static <T> T nullIsIllegal(T item, String message) {
- if (item == null) {
- throw new IllegalArgumentException(message);
- }
- return item;
- }
-
- /**
- * Converts a string from hex to long.
- *
- * @param string hex number in string form; sans 0x
- * @return long value
- */
- public static long fromHex(String string) {
- return UnsignedLongs.parseUnsignedLong(string, 16);
- }
-
- /**
- * Converts a long value to hex string; 16 wide and sans 0x.
- *
- * @param value long value
- * @return hex string
- */
- public static String toHex(long value) {
- return Strings.padStart(UnsignedLongs.toString(value, 16), 16, '0');
- }
-
- /**
- * Converts a long value to hex string; 16 wide and sans 0x.
- *
- * @param value long value
- * @param width string width; zero padded
- * @return hex string
- */
- public static String toHex(long value, int width) {
- return Strings.padStart(UnsignedLongs.toString(value, 16), width, '0');
- }
-
- /**
- * Returns a copy of the input byte array.
- *
- * @param original input
- * @return copy of original
- */
- public static byte[] copyOf(byte[] original) {
- return Arrays.copyOf(original, original.length);
- }
-
- /**
- * Get property as a string value.
- *
- * @param properties properties to be looked up
- * @param propertyName the name of the property to look up
- * @return value when the propertyName is defined or return null
- */
- public static String get(Dictionary<?, ?> properties, String propertyName) {
- Object v = properties.get(propertyName);
- String s = (v instanceof String) ? (String) v :
- v != null ? v.toString() : null;
- return Strings.isNullOrEmpty(s) ? null : s.trim();
- }
-
- /**
- * Suspends the current thread for a specified number of millis.
- *
- * @param ms number of millis
- */
- public static void delay(int ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted", e);
- }
- }
-
- /**
- * Returns a function that retries execution on failure.
- * @param base base function
- * @param exceptionClass type of exception for which to retry
- * @param maxRetries max number of retries before giving up
- * @param maxDelayBetweenRetries max delay between successive retries. The actual delay is randomly picked from
- * the interval (0, maxDelayBetweenRetries]
- * @return function
- * @param <U> type of function input
- * @param <V> type of function output
- */
- public static <U, V> Function<U, V> retryable(Function<U, V> base,
- Class<? extends Throwable> exceptionClass,
- int maxRetries,
- int maxDelayBetweenRetries) {
- return new RetryingFunction<>(base, exceptionClass, maxRetries, maxDelayBetweenRetries);
- }
-
- /**
- * Returns a Supplier that retries execution on failure.
- * @param base base supplier
- * @param exceptionClass type of exception for which to retry
- * @param maxRetries max number of retries before giving up
- * @param maxDelayBetweenRetries max delay between successive retries. The actual delay is randomly picked from
- * the interval (0, maxDelayBetweenRetries]
- * @return supplier
- * @param <V> type of supplied result
- */
- public static <V> Supplier<V> retryable(Supplier<V> base,
- Class<? extends Throwable> exceptionClass,
- int maxRetries,
- int maxDelayBetweenRetries) {
- return () -> new RetryingFunction<>(v -> base.get(),
- exceptionClass,
- maxRetries,
- maxDelayBetweenRetries).apply(null);
- }
-
- /**
- * Suspends the current thread for a random number of millis between 0 and
- * the indicated limit.
- *
- * @param ms max number of millis
- */
- public static void randomDelay(int ms) {
- try {
- Thread.sleep(random.nextInt(ms));
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted", e);
- }
- }
-
- /**
- * Suspends the current thread for a specified number of millis and nanos.
- *
- * @param ms number of millis
- * @param nanos number of nanos
- */
- public static void delay(int ms, int nanos) {
- try {
- Thread.sleep(ms, nanos);
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted", e);
- }
- }
-
- /**
- * Slurps the contents of a file into a list of strings, one per line.
- *
- * @param path file path
- * @return file contents
- * @deprecated in Emu release
- */
- @Deprecated
- public static List<String> slurp(File path) {
- try (
- BufferedReader br = new BufferedReader(
- new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8));
- ) {
- List<String> lines = new ArrayList<>();
- String line;
- while ((line = br.readLine()) != null) {
- lines.add(line);
- }
- return lines;
-
- } catch (IOException e) {
- return null;
- }
- }
-
- /**
- * Purges the specified directory path.&nbsp;Use with great caution since
- * no attempt is made to check for symbolic links, which could result in
- * deletion of unintended files.
- *
- * @param path directory to be removed
- * @throws java.io.IOException if unable to remove contents
- */
- public static void removeDirectory(String path) throws IOException {
- DirectoryDeleter visitor = new DirectoryDeleter();
- File dir = new File(path);
- if (dir.exists() && dir.isDirectory()) {
- walkFileTree(Paths.get(path), visitor);
- if (visitor.exception != null) {
- throw visitor.exception;
- }
- }
- }
-
- /**
- * Purges the specified directory path.&nbsp;Use with great caution since
- * no attempt is made to check for symbolic links, which could result in
- * deletion of unintended files.
- *
- * @param dir directory to be removed
- * @throws java.io.IOException if unable to remove contents
- */
- public static void removeDirectory(File dir) throws IOException {
- DirectoryDeleter visitor = new DirectoryDeleter();
- if (dir.exists() && dir.isDirectory()) {
- walkFileTree(Paths.get(dir.getAbsolutePath()), visitor);
- if (visitor.exception != null) {
- throw visitor.exception;
- }
- }
- }
-
- // Auxiliary path visitor for recursive directory structure removal.
- private static class DirectoryDeleter extends SimpleFileVisitor<Path> {
-
- private IOException exception;
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attributes)
- throws IOException {
- if (attributes.isRegularFile()) {
- delete(file);
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path directory, IOException ioe)
- throws IOException {
- delete(directory);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFileFailed(Path file, IOException ioe)
- throws IOException {
- this.exception = ioe;
- return FileVisitResult.TERMINATE;
- }
- }
-
- /**
- * Returns a human friendly time ago string for a specified system time.
- *
- * @param unixTime system time in millis
- * @return human friendly time ago
- */
- public static String timeAgo(long unixTime) {
- long deltaMillis = System.currentTimeMillis() - unixTime;
- long secondsSince = (long) (deltaMillis / 1000.0);
- long minsSince = (long) (deltaMillis / (1000.0 * 60));
- long hoursSince = (long) (deltaMillis / (1000.0 * 60 * 60));
- long daysSince = (long) (deltaMillis / (1000.0 * 60 * 60 * 24));
- if (daysSince > 0) {
- return String.format("%dd ago", daysSince);
- } else if (hoursSince > 0) {
- return String.format("%dh ago", hoursSince);
- } else if (minsSince > 0) {
- return String.format("%dm ago", minsSince);
- } else if (secondsSince > 0) {
- return String.format("%ds ago", secondsSince);
- } else {
- return "just now";
- }
- }
-
- /**
- * Copies the specified directory path.&nbsp;Use with great caution since
- * no attempt is made to check for symbolic links, which could result in
- * copy of unintended files.
- *
- * @param src directory to be copied
- * @param dst destination directory to be removed
- * @throws java.io.IOException if unable to remove contents
- */
- public static void copyDirectory(String src, String dst) throws IOException {
- walkFileTree(Paths.get(src), new DirectoryCopier(src, dst));
- }
-
- /**
- * Copies the specified directory path.&nbsp;Use with great caution since
- * no attempt is made to check for symbolic links, which could result in
- * copy of unintended files.
- *
- * @param src directory to be copied
- * @param dst destination directory to be removed
- * @throws java.io.IOException if unable to remove contents
- */
- public static void copyDirectory(File src, File dst) throws IOException {
- walkFileTree(Paths.get(src.getAbsolutePath()),
- new DirectoryCopier(src.getAbsolutePath(),
- dst.getAbsolutePath()));
- }
-
- /**
- * Returns the future value when complete or if future
- * completes exceptionally returns the defaultValue.
- *
- * @param future future
- * @param defaultValue default value
- * @param <T> future value type
- * @return future value when complete or if future
- * completes exceptionally returns the defaultValue.
- */
- public static <T> T futureGetOrElse(Future<T> future, T defaultValue) {
- try {
- return future.get();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return defaultValue;
- } catch (ExecutionException e) {
- return defaultValue;
- }
- }
-
- /**
- * Returns the future value when complete or if future
- * completes exceptionally returns the defaultValue.
- *
- * @param future future
- * @param timeout time to wait for successful completion
- * @param timeUnit time unit
- * @param defaultValue default value
- * @param <T> future value type
- * @return future value when complete or if future
- * completes exceptionally returns the defaultValue.
- */
- public static <T> T futureGetOrElse(Future<T> future,
- long timeout,
- TimeUnit timeUnit,
- T defaultValue) {
- try {
- return future.get(timeout, timeUnit);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return defaultValue;
- } catch (ExecutionException | TimeoutException e) {
- return defaultValue;
- }
- }
-
- /**
- * Returns a future that is completed exceptionally.
- *
- * @param t exception
- * @param <T> future value type
- * @return future
- */
- public static <T> CompletableFuture<T> exceptionalFuture(Throwable t) {
- CompletableFuture<T> future = new CompletableFuture<>();
- future.completeExceptionally(t);
- return future;
- }
-
- /**
- * Returns the contents of {@code ByteBuffer} as byte array.
- * <p>
- * WARNING: There is a performance cost due to array copy
- * when using this method.
- *
- * @param buffer byte buffer
- * @return byte array containing the byte buffer contents
- */
- public static byte[] byteBuffertoArray(ByteBuffer buffer) {
- int length = buffer.remaining();
- if (buffer.hasArray()) {
- int offset = buffer.arrayOffset() + buffer.position();
- return Arrays.copyOfRange(buffer.array(), offset, offset + length);
- }
- byte[] bytes = new byte[length];
- buffer.duplicate().get(bytes);
- return bytes;
- }
-
- /**
- * Converts an iterable to a stream.
- *
- * @param it iterable to convert
- * @param <T> type if item
- * @return iterable as a stream
- */
- public static <T> Stream<T> stream(Iterable<T> it) {
- return StreamSupport.stream(it.spliterator(), false);
- }
-
- // Auxiliary path visitor for recursive directory structure copying.
- private static class DirectoryCopier extends SimpleFileVisitor<Path> {
- private Path src;
- private Path dst;
- private StandardCopyOption copyOption = StandardCopyOption.REPLACE_EXISTING;
-
- DirectoryCopier(String src, String dst) {
- this.src = Paths.get(src);
- this.dst = Paths.get(dst);
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
- Path targetPath = dst.resolve(src.relativize(dir));
- if (!Files.exists(targetPath)) {
- Files.createDirectory(targetPath);
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Files.copy(file, dst.resolve(src.relativize(file)), copyOption);
- return FileVisitResult.CONTINUE;
- }
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/TriConsumer.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/TriConsumer.java
deleted file mode 100644
index d1963c46..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/TriConsumer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-/**
- * A consumer that accepts three arguments.
- *
- * @param <U> type of first argument
- * @param <V> type of second argument
- * @param <W> type of third argument
- */
-public interface TriConsumer<U, V, W> {
-
- /**
- * Applies the given arguments to the function.
- * @param arg1 first argument
- * @param arg2 second argument
- * @param arg3 third argument
- */
- void accept(U arg1, V arg2, W arg3);
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/package-info.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/util/package-info.java
deleted file mode 100644
index 06cc394f..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/util/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Miscellaneous domain-agnostic utilities.
- */
-package org.onlab.util;
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractEdgeTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractEdgeTest.java
deleted file mode 100644
index 6e8635dd..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractEdgeTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-/**
- * Test of the base edge implementation.
- */
-public class AbstractEdgeTest {
-
- @Test
- public void equality() {
- TestVertex v1 = new TestVertex("1");
- TestVertex v2 = new TestVertex("2");
- new EqualsTester()
- .addEqualityGroup(new TestEdge(v1, v2, 1),
- new TestEdge(v1, v2, 1))
- .addEqualityGroup(new TestEdge(v2, v1, 1))
- .testEquals();
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractGraphPathSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractGraphPathSearchTest.java
deleted file mode 100644
index b42cacf6..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AbstractGraphPathSearchTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Base for all graph search tests.
- */
-public abstract class AbstractGraphPathSearchTest extends GraphTest {
-
- /**
- * Creates a test-specific graph search to exercise.
- *
- * @return graph search
- */
- protected abstract AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch();
-
- @Test(expected = IllegalArgumentException.class)
- public void noSuchSourceArgument() {
- graphSearch().search(new AdjacencyListsGraph<>(of(B, C),
- of(new TestEdge(B, C, 1))),
- A, H, weight, 1);
- }
-
- @Test(expected = NullPointerException.class)
- public void nullGraphArgument() {
- graphSearch().search(null, A, H, weight, 1);
- }
-
- @Test(expected = NullPointerException.class)
- public void nullSourceArgument() {
- graphSearch().search(new AdjacencyListsGraph<>(of(B, C),
- of(new TestEdge(B, C, 1))),
- null, H, weight, 1);
- }
-
- @Test
- public void samenessThreshold() {
- AbstractGraphPathSearch<TestVertex, TestEdge> search = graphSearch();
- search.setSamenessThreshold(0.3);
- assertEquals("incorrect threshold", 0.3, search.samenessThreshold(), 0.01);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AdjacencyListsGraphTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AdjacencyListsGraphTest.java
deleted file mode 100644
index 1f22b5c4..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/AdjacencyListsGraphTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests of the graph implementation.
- */
-public class AdjacencyListsGraphTest {
-
- private static final TestVertex A = new TestVertex("A");
- private static final TestVertex B = new TestVertex("B");
- private static final TestVertex C = new TestVertex("C");
- private static final TestVertex D = new TestVertex("D");
- private static final TestVertex E = new TestVertex("E");
- private static final TestVertex F = new TestVertex("F");
- private static final TestVertex G = new TestVertex("G");
-
- private final Set<TestEdge> edges =
- ImmutableSet.of(new TestEdge(A, B, 1), new TestEdge(B, C, 1),
- new TestEdge(C, D, 1), new TestEdge(D, A, 1),
- new TestEdge(B, D, 1));
-
- @Test
- public void equality() {
- Set<TestVertex> vertexes = ImmutableSet.of(A, B, C, D, E, F);
- Set<TestVertex> vertexes2 = ImmutableSet.of(A, B, C, D, E, F, G);
-
- AdjacencyListsGraph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(vertexes, edges);
- AdjacencyListsGraph<TestVertex, TestEdge> same = new AdjacencyListsGraph<>(vertexes, edges);
- AdjacencyListsGraph<TestVertex, TestEdge> different = new AdjacencyListsGraph<>(vertexes2, edges);
-
- new EqualsTester()
- .addEqualityGroup(graph, same)
- .addEqualityGroup(different)
- .testEquals();
- }
-
- @Test
- public void basics() {
- Set<TestVertex> vertexes = ImmutableSet.of(A, B, C, D, E, F);
- AdjacencyListsGraph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(vertexes, edges);
- assertEquals("incorrect vertex count", 6, graph.getVertexes().size());
- assertEquals("incorrect edge count", 5, graph.getEdges().size());
-
- assertEquals("incorrect egress edge count", 1, graph.getEdgesFrom(A).size());
- assertEquals("incorrect ingress edge count", 1, graph.getEdgesTo(A).size());
- assertEquals("incorrect ingress edge count", 1, graph.getEdgesTo(C).size());
- assertEquals("incorrect egress edge count", 2, graph.getEdgesFrom(B).size());
- assertEquals("incorrect ingress edge count", 2, graph.getEdgesTo(D).size());
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BellmanFordGraphSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BellmanFordGraphSearchTest.java
deleted file mode 100644
index ff363bfb..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BellmanFordGraphSearchTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * Test of the Bellman-Ford algorithm.
- */
-public class BellmanFordGraphSearchTest extends BreadthFirstSearchTest {
-
- @Override
- protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
- return new BellmanFordGraphSearch<>();
- }
-
- @Test
- @Override
- public void defaultGraphTest() {
- executeDefaultTest(7, 5, 5.0);
- }
-
- @Test
- public void defaultHopCountWeight() {
- weight = null;
- executeDefaultTest(10, 3, 3.0);
- }
-
- @Test
- public void searchGraphWithNegativeCycles() {
- Set<TestVertex> vertexes = new HashSet<>(vertexes());
- vertexes.add(Z);
-
- Set<TestEdge> edges = new HashSet<>(edges());
- edges.add(new TestEdge(G, Z, 1.0));
- edges.add(new TestEdge(Z, G, -2.0));
-
- graph = new AdjacencyListsGraph<>(vertexes, edges);
-
- GraphPathSearch<TestVertex, TestEdge> search = graphSearch();
- Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, H, weight, ALL_PATHS).paths();
- assertEquals("incorrect paths count", 1, paths.size());
-
- Path p = paths.iterator().next();
- assertEquals("incorrect src", A, p.src());
- assertEquals("incorrect dst", H, p.dst());
- assertEquals("incorrect path length", 5, p.edges().size());
- assertEquals("incorrect path cost", 5.0, p.cost(), 0.1);
-
- paths = search.search(graph, A, G, weight, ALL_PATHS).paths();
- assertEquals("incorrect paths count", 0, paths.size());
-
- paths = search.search(graph, A, null, weight, ALL_PATHS).paths();
- printPaths(paths);
- assertEquals("incorrect paths count", 6, paths.size());
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BreadthFirstSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BreadthFirstSearchTest.java
deleted file mode 100644
index 0b574aff..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/BreadthFirstSearchTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * Test of the BFS and similar path search algorithms.
- */
-public class BreadthFirstSearchTest extends AbstractGraphPathSearchTest {
-
- @Override
- protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
- return new BreadthFirstSearch<>();
- }
-
- @Test
- public void defaultGraphTest() {
- executeDefaultTest(7, 3, 8.0);
- }
-
- @Test
- public void defaultHopCountWeight() {
- weight = null;
- executeDefaultTest(7, 3, 3.0);
- }
-
- // Executes the default test
- protected void executeDefaultTest(int pathCount, int pathLength, double pathCost) {
- graph = new AdjacencyListsGraph<>(vertexes(), edges());
-
- GraphPathSearch<TestVertex, TestEdge> search = graphSearch();
- Set<Path<TestVertex, TestEdge>> paths =
- search.search(graph, A, H, weight, ALL_PATHS).paths();
- assertEquals("incorrect paths count", 1, paths.size());
-
- Path p = paths.iterator().next();
- assertEquals("incorrect src", A, p.src());
- assertEquals("incorrect dst", H, p.dst());
- assertEquals("incorrect path length", pathLength, p.edges().size());
- assertEquals("incorrect path cost", pathCost, p.cost(), 0.1);
-
- paths = search.search(graph, A, null, weight, ALL_PATHS).paths();
- printPaths(paths);
- assertEquals("incorrect paths count", pathCount, paths.size());
- }
-
- // Executes the search and validates its results.
- protected void executeSearch(GraphPathSearch<TestVertex, TestEdge> search,
- Graph<TestVertex, TestEdge> graph,
- TestVertex src, TestVertex dst,
- EdgeWeight<TestVertex, TestEdge> weight,
- int pathCount, double pathCost) {
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- search.search(graph, src, dst, weight, ALL_PATHS);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- printPaths(paths);
- assertEquals("incorrect paths count", pathCount, paths.size());
- if (pathCount > 0) {
- Path<TestVertex, TestEdge> path = paths.iterator().next();
- assertEquals("incorrect path cost", pathCost, path.cost(), 0.1);
- }
- }
-
- // Executes the single-path search and validates its results.
- protected void executeSinglePathSearch(GraphPathSearch<TestVertex, TestEdge> search,
- Graph<TestVertex, TestEdge> graph,
- TestVertex src, TestVertex dst,
- EdgeWeight<TestVertex, TestEdge> weight,
- int pathCount, double pathCost) {
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- search.search(graph, src, dst, weight, 1);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- printPaths(paths);
- assertEquals("incorrect paths count", Math.min(pathCount, 1), paths.size());
- if (pathCount > 0) {
- Path<TestVertex, TestEdge> path = paths.iterator().next();
- assertEquals("incorrect path cost", pathCost, path.cost(), 0.1);
- }
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultMutablePathTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultMutablePathTest.java
deleted file mode 100644
index 8eb09df6..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultMutablePathTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static com.google.common.collect.ImmutableList.of;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-/**
- * Test of the default mutable path.
- */
-public class DefaultMutablePathTest extends DefaultPathTest {
-
- @Test
- public void equality() {
- DefaultPath<TestVertex, TestEdge> p1 =
- new DefaultPath<>(of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1)), 2.0);
- DefaultPath<TestVertex, TestEdge> p2 =
- new DefaultPath<>(of(new TestEdge(A, B, 1),
- new TestEdge(B, D, 1)), 2.0);
- new EqualsTester().addEqualityGroup(new DefaultMutablePath<>(p1),
- new DefaultMutablePath<>(p1))
- .addEqualityGroup(new DefaultMutablePath<>(p2))
- .testEquals();
- }
-
- @Test
- public void empty() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- assertNull("src should be null", p.src());
- assertNull("dst should be null", p.dst());
- assertEquals("incorrect edge count", 0, p.edges().size());
- assertEquals("incorrect path cost", 0.0, p.cost(), 0.1);
- }
-
- @Test
- public void pathCost() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- p.setCost(4);
- assertEquals("incorrect path cost", 4.0, p.cost(), 0.1);
- }
-
- private void validatePath(Path<TestVertex, TestEdge> p,
- TestVertex src, TestVertex dst, int length) {
- validatePath(p, src, dst, length, 0.0);
- }
-
- @Test
- public void insertEdge() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- p.insertEdge(new TestEdge(B, C, 1));
- p.insertEdge(new TestEdge(A, B, 1));
- validatePath(p, A, C, 2);
- }
-
- @Test
- public void appendEdge() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- p.appendEdge(new TestEdge(A, B, 1));
- p.appendEdge(new TestEdge(B, C, 1));
- validatePath(p, A, C, 2);
- }
-
- @Test
- public void removeEdge() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- p.appendEdge(new TestEdge(A, B, 1));
- p.appendEdge(new TestEdge(B, C, 1));
- p.appendEdge(new TestEdge(C, C, 2));
- p.appendEdge(new TestEdge(C, D, 1));
- validatePath(p, A, D, 4);
-
- p.removeEdge(new TestEdge(A, B, 1));
- validatePath(p, B, D, 3);
-
- p.removeEdge(new TestEdge(C, C, 2));
- validatePath(p, B, D, 2);
-
- p.removeEdge(new TestEdge(C, D, 1));
- validatePath(p, B, C, 1);
- }
-
- @Test
- public void toImmutable() {
- MutablePath<TestVertex, TestEdge> p = new DefaultMutablePath<>();
- p.appendEdge(new TestEdge(A, B, 1));
- p.appendEdge(new TestEdge(B, C, 1));
- validatePath(p, A, C, 2);
-
- assertEquals("immutables should equal", p.toImmutable(), p.toImmutable());
- validatePath(p.toImmutable(), A, C, 2);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultPathTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultPathTest.java
deleted file mode 100644
index 92befbfe..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DefaultPathTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import java.util.List;
-
-import static com.google.common.collect.ImmutableList.of;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test of the default path.
- */
-public class DefaultPathTest extends GraphTest {
-
- @Test
- public void equality() {
- List<TestEdge> edges = of(new TestEdge(A, B, 1), new TestEdge(B, C, 1));
- new EqualsTester().addEqualityGroup(new DefaultPath<>(edges, 2.0),
- new DefaultPath<>(edges, 2.0))
- .addEqualityGroup(new DefaultPath<>(edges, 3.0))
- .testEquals();
- }
-
- @Test
- public void basics() {
- Path<TestVertex, TestEdge> p = new DefaultPath<>(of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1)), 2.0);
- validatePath(p, A, C, 2, 2.0);
- }
-
- // Validates the path against expected attributes
- protected void validatePath(Path<TestVertex, TestEdge> p,
- TestVertex src, TestVertex dst,
- int length, double cost) {
- assertEquals("incorrect path length", length, p.edges().size());
- assertEquals("incorrect source", src, p.src());
- assertEquals("incorrect destination", dst, p.dst());
- assertEquals("incorrect path cost", cost, p.cost(), 0.1);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DepthFirstSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DepthFirstSearchTest.java
deleted file mode 100644
index 3977ebf1..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DepthFirstSearchTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.graph.DepthFirstSearch.EdgeType;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * Test of the DFS algorithm.
- */
-public class DepthFirstSearchTest extends AbstractGraphPathSearchTest {
-
- @Override
- protected DepthFirstSearch<TestVertex, TestEdge> graphSearch() {
- return new DepthFirstSearch<>();
- }
-
- @Test
- public void defaultGraphTest() {
- executeDefaultTest(3, 6, 5.0, 12.0);
- executeBroadSearch();
- }
-
- @Test
- public void defaultHopCountWeight() {
- weight = null;
- executeDefaultTest(3, 6, 3.0, 6.0);
- executeBroadSearch();
- }
-
- protected void executeDefaultTest(int minLength, int maxLength,
- double minCost, double maxCost) {
- graph = new AdjacencyListsGraph<>(vertexes(), edges());
- DepthFirstSearch<TestVertex, TestEdge> search = graphSearch();
-
- DepthFirstSearch<TestVertex, TestEdge>.SpanningTreeResult result =
- search.search(graph, A, H, weight, 1);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- assertEquals("incorrect path count", 1, paths.size());
-
- Path path = paths.iterator().next();
- System.out.println(path);
- assertEquals("incorrect src", A, path.src());
- assertEquals("incorrect dst", H, path.dst());
-
- int l = path.edges().size();
- assertTrue("incorrect path length " + l,
- minLength <= l && l <= maxLength);
- assertTrue("incorrect path cost " + path.cost(),
- minCost <= path.cost() && path.cost() <= maxCost);
-
- System.out.println(result.edges());
- printPaths(paths);
- }
-
- public void executeBroadSearch() {
- graph = new AdjacencyListsGraph<>(vertexes(), edges());
- DepthFirstSearch<TestVertex, TestEdge> search = graphSearch();
-
- // Perform narrow path search to a specific destination.
- DepthFirstSearch<TestVertex, TestEdge>.SpanningTreeResult result =
- search.search(graph, A, null, weight, ALL_PATHS);
- assertEquals("incorrect paths count", 7, result.paths().size());
-
- int[] types = new int[]{0, 0, 0, 0};
- for (EdgeType t : result.edges().values()) {
- types[t.ordinal()] += 1;
- }
- assertEquals("incorrect tree-edge count", 7,
- types[EdgeType.TREE_EDGE.ordinal()]);
- assertEquals("incorrect back-edge count", 1,
- types[EdgeType.BACK_EDGE.ordinal()]);
- assertEquals("incorrect cross-edge & forward-edge count", 4,
- types[EdgeType.FORWARD_EDGE.ordinal()] +
- types[EdgeType.CROSS_EDGE.ordinal()]);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DijkstraGraphSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DijkstraGraphSearchTest.java
deleted file mode 100644
index 17f08225..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DijkstraGraphSearchTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import java.text.DecimalFormat;
-import java.util.HashSet;
-import java.util.Set;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test of the Dijkstra algorithm.
- */
-public class DijkstraGraphSearchTest extends BreadthFirstSearchTest {
-
- @Override
- protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
- return new DijkstraGraphSearch<>();
- }
-
- @Test
- @Override
- public void defaultGraphTest() {
- executeDefaultTest(7, 5, 5.0);
- }
-
- @Test
- @Override
- public void defaultHopCountWeight() {
- weight = null;
- executeDefaultTest(10, 3, 3.0);
- }
-
- @Test
- public void noPath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, C, 1)));
- GraphPathSearch<TestVertex, TestEdge> gs = graphSearch();
- Set<Path<TestVertex, TestEdge>> paths = gs.search(graph, A, B, weight, 1).paths();
- printPaths(paths);
- assertEquals("incorrect paths count", 1, paths.size());
- assertEquals("incorrect path cost", 1.0, paths.iterator().next().cost(), 0.1);
-
- paths = gs.search(graph, A, D, weight, 1).paths();
- printPaths(paths);
- assertEquals("incorrect paths count", 0, paths.size());
-
- paths = gs.search(graph, A, null, weight, 1).paths();
- printPaths(paths);
- assertEquals("incorrect paths count", 1, paths.size());
- assertEquals("incorrect path cost", 1.0, paths.iterator().next().cost(), 0.1);
- }
-
- @Test
- public void simpleMultiplePath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(A, C, 1),
- new TestEdge(B, D, 1),
- new TestEdge(C, D, 1)));
- executeSearch(graphSearch(), graph, A, D, weight, 2, 2.0);
- executeSinglePathSearch(graphSearch(), graph, A, D, weight, 1, 2.0);
- }
-
- @Test
- public void denseMultiplePath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G),
- of(new TestEdge(A, B, 1),
- new TestEdge(A, C, 1),
- new TestEdge(B, D, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, E, 1),
- new TestEdge(D, F, 1),
- new TestEdge(E, G, 1),
- new TestEdge(F, G, 1),
- new TestEdge(A, G, 4)));
- executeSearch(graphSearch(), graph, A, G, weight, 5, 4.0);
- executeSinglePathSearch(graphSearch(), graph, A, G, weight, 1, 4.0);
- }
-
- @Test
- public void dualEdgeMultiplePath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H),
- of(new TestEdge(A, B, 1), new TestEdge(A, C, 3),
- new TestEdge(B, D, 2), new TestEdge(B, C, 1),
- new TestEdge(B, E, 4), new TestEdge(C, E, 1),
- new TestEdge(D, H, 5), new TestEdge(D, E, 1),
- new TestEdge(E, F, 1), new TestEdge(F, D, 1),
- new TestEdge(F, G, 1), new TestEdge(F, H, 1),
- new TestEdge(A, E, 3), new TestEdge(B, D, 1)));
- executeSearch(graphSearch(), graph, A, E, weight, 3, 3.0);
- executeSinglePathSearch(graphSearch(), graph, A, E, weight, 1, 3.0);
- }
-
- @Test
- public void negativeWeights() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G),
- of(new TestEdge(A, B, 1),
- new TestEdge(A, C, -1),
- new TestEdge(B, D, 1),
- new TestEdge(D, A, -2),
- new TestEdge(C, D, 1),
- new TestEdge(D, E, 1),
- new TestEdge(D, F, 1),
- new TestEdge(E, G, 1),
- new TestEdge(F, G, 1),
- new TestEdge(G, A, -5),
- new TestEdge(A, G, 4)));
- executeSearch(graphSearch(), graph, A, G, weight, 3, 4.0);
- executeSinglePathSearch(graphSearch(), graph, A, G, weight, 1, 4.0);
- }
-
- @Test
- public void disconnectedPerf() {
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- disconnected();
- }
-
-
- @Test
- public void disconnected() {
- Set<TestVertex> vertexes = new HashSet<>();
- for (int i = 0; i < 200; i++) {
- vertexes.add(new TestVertex("v" + i));
- }
-
- graph = new AdjacencyListsGraph<>(vertexes, of());
-
- long start = System.nanoTime();
- for (TestVertex src : vertexes) {
- executeSearch(graphSearch(), graph, src, null, null, 0, 0);
- }
- long end = System.nanoTime();
- DecimalFormat fmt = new DecimalFormat("#,###");
- System.out.println("Compute cost is " + fmt.format(end - start) + " nanos");
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DisjointPathPairTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DisjointPathPairTest.java
deleted file mode 100644
index ca6c56c4..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/DisjointPathPairTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.onlab.graph;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.testing.EqualsTester;
-
-/**
- * Test of DisjointPathPair.
- */
-public class DisjointPathPairTest {
-
- private static final TestVertex A = new TestVertex("A");
- private static final TestVertex B = new TestVertex("B");
- private static final TestVertex C = new TestVertex("C");
- private static final TestVertex D = new TestVertex("D");
-
- private static final TestEdge AB = new TestEdge(A, B, 1.0);
- private static final TestEdge BC = new TestEdge(B, C, 1.0);
- private static final TestEdge AD = new TestEdge(A, D, 1.0);
- private static final TestEdge DC = new TestEdge(D, C, 1.0);
-
- private static final Path<TestVertex, TestEdge> ABC
- = new DefaultPath<>(ImmutableList.of(AB, BC), 1.0);
- private static final Path<TestVertex, TestEdge> ADC
- = new DefaultPath<>(ImmutableList.of(AD, DC), 1.0);
-
- @Test
- public void testSwappingPrimarySecondaryDoesntImpactHashCode() {
- assertEquals(new DisjointPathPair<>(ABC, ADC).hashCode(),
- new DisjointPathPair<>(ADC, ABC).hashCode());
- }
-
- @Test
- public void testSwappingPrimarySecondaryDoesntImpactEquality() {
- new EqualsTester()
- .addEqualityGroup(new DisjointPathPair<>(ABC, ADC),
- new DisjointPathPair<>(ADC, ABC));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/GraphTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/GraphTest.java
deleted file mode 100644
index d29282fc..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/GraphTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.Set;
-
-import static com.google.common.collect.ImmutableSet.of;
-
-/**
- * Base class for various graph-related tests.
- */
-public class GraphTest {
-
- static final TestVertex A = new TestVertex("A");
- static final TestVertex B = new TestVertex("B");
- static final TestVertex C = new TestVertex("C");
- static final TestVertex D = new TestVertex("D");
- static final TestVertex E = new TestVertex("E");
- static final TestVertex F = new TestVertex("F");
- static final TestVertex G = new TestVertex("G");
- static final TestVertex H = new TestVertex("H");
- static final TestVertex Z = new TestVertex("Z");
-
- protected Graph<TestVertex, TestEdge> graph;
-
- protected EdgeWeight<TestVertex, TestEdge> weight =
- new EdgeWeight<TestVertex, TestEdge>() {
- @Override
- public double weight(TestEdge edge) {
- return edge.weight();
- }
- };
-
- protected void printPaths(Set<Path<TestVertex, TestEdge>> paths) {
- for (Path p : paths) {
- System.out.println(p);
- }
- }
-
- protected Set<TestVertex> vertexes() {
- return of(A, B, C, D, E, F, G, H);
- }
-
- protected Set<TestEdge> edges() {
- return of(new TestEdge(A, B, 1), new TestEdge(A, C, 3),
- new TestEdge(B, D, 2), new TestEdge(B, C, 1),
- new TestEdge(B, E, 4), new TestEdge(C, E, 1),
- new TestEdge(D, H, 5), new TestEdge(D, E, 1),
- new TestEdge(E, F, 1), new TestEdge(F, D, 1),
- new TestEdge(F, G, 1), new TestEdge(F, H, 1));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/HeapTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/HeapTest.java
deleted file mode 100644
index f34185e2..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/HeapTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import com.google.common.collect.Ordering;
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-
-import static com.google.common.collect.ImmutableList.of;
-import static org.junit.Assert.*;
-
-/**
- * Heap data structure tests.
- */
-public class HeapTest {
-
- private ArrayList<Integer> data =
- new ArrayList<>(of(6, 4, 5, 9, 8, 3, 2, 1, 7, 0));
-
- private static final Comparator<Integer> MIN = Ordering.natural().reverse();
- private static final Comparator<Integer> MAX = Ordering.natural();
-
- @Test
- public void equality() {
- new EqualsTester()
- .addEqualityGroup(new Heap<>(data, MIN),
- new Heap<>(data, MIN))
- .addEqualityGroup(new Heap<>(data, MAX))
- .testEquals();
- }
-
- @Test
- public void empty() {
- Heap<Integer> h = new Heap<>(new ArrayList<Integer>(), MIN);
- assertTrue("should be empty", h.isEmpty());
- assertEquals("incorrect size", 0, h.size());
- assertNull("no item expected", h.extreme());
- assertNull("no item expected", h.extractExtreme());
- }
-
- @Test
- public void insert() {
- Heap<Integer> h = new Heap<>(data, MIN);
- assertEquals("incorrect size", 10, h.size());
- h.insert(3);
- assertEquals("incorrect size", 11, h.size());
- }
-
- @Test
- public void minQueue() {
- Heap<Integer> h = new Heap<>(data, MIN);
- assertFalse("should not be empty", h.isEmpty());
- assertEquals("incorrect size", 10, h.size());
- assertEquals("incorrect extreme", (Integer) 0, h.extreme());
-
- for (int i = 0, n = h.size(); i < n; i++) {
- assertEquals("incorrect element", (Integer) i, h.extractExtreme());
- }
- assertTrue("should be empty", h.isEmpty());
- }
-
- @Test
- public void maxQueue() {
- Heap<Integer> h = new Heap<>(data, MAX);
- assertFalse("should not be empty", h.isEmpty());
- assertEquals("incorrect size", 10, h.size());
- assertEquals("incorrect extreme", (Integer) 9, h.extreme());
-
- for (int i = h.size(); i > 0; i--) {
- assertEquals("incorrect element", (Integer) (i - 1), h.extractExtreme());
- }
- assertTrue("should be empty", h.isEmpty());
- }
-
- @Test
- public void iterator() {
- Heap<Integer> h = new Heap<>(data, MIN);
- assertTrue("should have next element", h.iterator().hasNext());
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
deleted file mode 100644
index 3e8900b8..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayOutputStream;
-//import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class KshortestPathSearchTest extends BreadthFirstSearchTest {
-
- private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
-
- @Test
- public void noPath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, C, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, D, weight, 1);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 0, result.size());
- }
-
- @Test
- public void test2Path() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(B, D, 1),
- new TestEdge(D, B, 1),
- new TestEdge(A, C, 1),
- new TestEdge(C, A, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, C, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, D, weight, 2);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 2, result.size());
- // assertEquals("printing the paths", outContent.toString());
- }
-
- @Test
- public void test3Path() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(A, D, 1),
- new TestEdge(D, A, 1),
- new TestEdge(B, D, 1),
- new TestEdge(D, B, 1),
- new TestEdge(A, C, 1),
- new TestEdge(C, A, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, C, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, D, weight, 3);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 3, result.size());
- // assertEquals("printing the paths", outContent.toString());
- }
-
- @Test
- public void test4Path() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(A, C, 1),
- new TestEdge(C, A, 1),
- new TestEdge(B, D, 1),
- new TestEdge(D, B, 1),
- new TestEdge(C, E, 1),
- new TestEdge(E, C, 1),
- new TestEdge(D, F, 1),
- new TestEdge(F, D, 1),
- new TestEdge(F, E, 1),
- new TestEdge(E, F, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, C, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, F, weight, 4);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 4, result.size());
- // assertEquals("printing the paths", outContent.toString());
- }
-
- @Test
- public void test6Path() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, A, 1),
- new TestEdge(A, C, 1),
- new TestEdge(C, A, 1),
- new TestEdge(B, D, 1),
- new TestEdge(D, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(C, B, 1),
- new TestEdge(D, E, 1),
- new TestEdge(E, D, 1),
- new TestEdge(C, E, 1),
- new TestEdge(E, C, 1),
- new TestEdge(D, F, 1),
- new TestEdge(F, D, 1),
- new TestEdge(E, F, 1),
- new TestEdge(F, E, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, F, weight, 6);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 6, result.size());
- // assertEquals("printing the paths", outContent.toString());
- }
-
- @Test
- public void dualEdgePath() {
- graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H),
- of(new TestEdge(A, B, 1), new TestEdge(A, C, 3),
- new TestEdge(B, D, 2), new TestEdge(B, C, 1),
- new TestEdge(B, E, 4), new TestEdge(C, E, 1),
- new TestEdge(D, H, 5), new TestEdge(D, E, 1),
- new TestEdge(E, F, 1), new TestEdge(F, D, 1),
- new TestEdge(F, G, 1), new TestEdge(F, H, 1),
- new TestEdge(A, E, 3), new TestEdge(B, D, 1)));
- KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
- List<List<TestEdge>> result = gs.search(A, G, weight, 6);
- List<Path> paths = new ArrayList<>();
- Iterator<List<TestEdge>> itr = result.iterator();
- while (itr.hasNext()) {
- System.out.println(itr.next().toString());
- }
- assertEquals("incorrect paths count", 6, result.size());
- // assertEquals("printing the paths", outContent.toString());
- }
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- // System.setOut(new PrintStream(outContent));
- }
-
- @After
- public void tearDown() throws Exception {
- // System.setOut(null);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SrlgGraphSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SrlgGraphSearchTest.java
deleted file mode 100644
index 26d50364..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SrlgGraphSearchTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * Test of the Suurballe backup path algorithm.
- */
-public class SrlgGraphSearchTest extends BreadthFirstSearchTest {
-
- @Override
- protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
- return new SrlgGraphSearch<>(null);
- }
-
- public void setDefaultWeights() {
- weight = null;
- }
-
- @Override
- public void defaultGraphTest() {
- }
-
- @Override
- public void defaultHopCountWeight() {
- }
-
- @Test
- public void onePathPair() {
- setDefaultWeights();
- TestEdge aB = new TestEdge(A, B, 1);
- TestEdge bC = new TestEdge(B, C, 1);
- TestEdge aD = new TestEdge(A, D, 1);
- TestEdge dC = new TestEdge(D, C, 1);
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(aB, bC, aD, dC));
- Map<TestEdge, Integer> riskProfile = new HashMap<>();
- riskProfile.put(aB, 0);
- riskProfile.put(bC, 0);
- riskProfile.put(aD, 1);
- riskProfile.put(dC, 1);
- SrlgGraphSearch<TestVertex, TestEdge> search = new SrlgGraphSearch<>(2, riskProfile);
- Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, ALL_PATHS).paths();
- System.out.println("\n\n\n" + paths + "\n\n\n");
- assertEquals("one disjoint path pair found", 1, paths.size());
- checkIsDisjoint(paths.iterator().next(), riskProfile);
- }
-
- public void checkIsDisjoint(Path<TestVertex, TestEdge> p, Map<TestEdge, Integer> risks) {
- assertTrue("The path is not a DisjointPathPair", (p instanceof DisjointPathPair));
- DisjointPathPair<TestVertex, TestEdge> q = (DisjointPathPair) p;
- Set<Integer> p1Risks = new HashSet<>();
- for (TestEdge e : q.edges()) {
- p1Risks.add(risks.get(e));
- }
- if (!q.hasBackup()) {
- return;
- }
- Path<TestVertex, TestEdge> pq = q.secondary();
- for (TestEdge e: pq.edges()) {
- assertTrue("The paths are not disjoint", !p1Risks.contains(risks.get(e)));
- }
- }
-
- @Test
- public void complexGraphTest() {
- setDefaultWeights();
- TestEdge aB = new TestEdge(A, B, 1);
- TestEdge bC = new TestEdge(B, C, 1);
- TestEdge aD = new TestEdge(A, D, 1);
- TestEdge dC = new TestEdge(D, C, 1);
- TestEdge cE = new TestEdge(C, E, 1);
- TestEdge bE = new TestEdge(B, E, 1);
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(aB, bC, aD, dC, cE, bE));
- Map<TestEdge, Integer> riskProfile = new HashMap<>();
- riskProfile.put(aB, 0);
- riskProfile.put(bC, 0);
- riskProfile.put(aD, 1);
- riskProfile.put(dC, 1);
- riskProfile.put(cE, 2);
- riskProfile.put(bE, 3);
- SrlgGraphSearch<TestVertex, TestEdge> search = new SrlgGraphSearch<>(4, riskProfile);
- search.search(graph, A, E, weight, ALL_PATHS).paths();
- }
-
- @Test
- public void multiplePathGraphTest() {
- setDefaultWeights();
- TestEdge aB = new TestEdge(A, B, 1);
- TestEdge bE = new TestEdge(B, E, 1);
- TestEdge aD = new TestEdge(A, D, 1);
- TestEdge dE = new TestEdge(D, E, 1);
- TestEdge aC = new TestEdge(A, C, 1);
- TestEdge cE = new TestEdge(C, E, 1);
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(aB, bE, aD, dE, aC, cE));
- Map<TestEdge, Integer> riskProfile = new HashMap<>();
- riskProfile.put(aB, 0);
- riskProfile.put(bE, 1);
- riskProfile.put(aD, 2);
- riskProfile.put(dE, 3);
- riskProfile.put(aC, 4);
- riskProfile.put(cE, 5);
- SrlgGraphSearch<TestVertex, TestEdge> search = new SrlgGraphSearch<>(6, riskProfile);
- Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, ALL_PATHS).paths();
- assertTrue("> one disjoint path pair found", paths.size() >= 1);
- checkIsDisjoint(paths.iterator().next(), riskProfile);
- }
-
- @Test
- public void onePath() {
- setDefaultWeights();
- TestEdge aB = new TestEdge(A, B, 1);
- TestEdge bC = new TestEdge(B, C, 1);
- TestEdge aD = new TestEdge(A, D, 1);
- TestEdge dC = new TestEdge(D, C, 1);
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(aB, bC, aD, dC));
- Map<TestEdge, Integer> riskProfile = new HashMap<>();
- riskProfile.put(aB, 0);
- riskProfile.put(bC, 0);
- riskProfile.put(aD, 1);
- riskProfile.put(dC, 0);
- SrlgGraphSearch<TestVertex, TestEdge> search = new SrlgGraphSearch<>(2, riskProfile);
- Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, ALL_PATHS).paths();
- System.out.println(paths);
- assertTrue("no disjoint path pairs found", paths.size() == 0);
- }
-
- @Test
- public void noPath() {
- setDefaultWeights();
- TestEdge aB = new TestEdge(A, B, 1);
- TestEdge bC = new TestEdge(B, C, 1);
- TestEdge aD = new TestEdge(A, D, 1);
- TestEdge dC = new TestEdge(D, C, 1);
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(aB, bC, aD, dC));
- Map<TestEdge, Integer> riskProfile = new HashMap<>();
- riskProfile.put(aB, 0);
- riskProfile.put(bC, 0);
- riskProfile.put(aD, 1);
- riskProfile.put(dC, 0);
- SrlgGraphSearch<TestVertex, TestEdge> search = new SrlgGraphSearch<>(2, riskProfile);
- Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, ALL_PATHS).paths();
- assertTrue("no disjoint path pairs found", paths.size() == 0);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java
deleted file mode 100644
index 0d2d13b0..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-import java.util.Set;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.assertEquals;
-//import static org.junit.Assert.assertTrue;
-
-
-
-/**
- * Test of the Suurballe backup path algorithm.
- */
-public class SuurballeGraphSearchTest extends BreadthFirstSearchTest {
-
- @Override
- protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
- return new SuurballeGraphSearch<>();
- }
-
- public void setWeights() {
- weight = new EdgeWeight<TestVertex, TestEdge>() {
- @Override
- public double weight(TestEdge edge) {
- return edge.weight();
- }
- };
- }
- public void setDefaultWeights() {
- weight = null;
- }
- @Override
- public void defaultGraphTest() {
-
- }
-
- @Override
- public void defaultHopCountWeight() {
-
- }
-
- @Test
- public void basicGraphTest() {
- setDefaultWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(A, D, 1),
- new TestEdge(D, C, 1)));
- executeSearch(graphSearch(), graph, A, C, weight, 1, 4.0);
- }
-
- @Test
- public void multiplePathOnePairGraphTest() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(A, D, 1),
- new TestEdge(D, C, 1),
- new TestEdge(B, E, 2),
- new TestEdge(C, E, 1)));
- executeSearch(graphSearch(), graph, A, E, weight, 1, 6.0);
- }
-
- @Test
- public void multiplePathsMultiplePairs() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, E, 1),
- new TestEdge(A, C, 1),
- new TestEdge(C, E, 1),
- new TestEdge(A, D, 1),
- new TestEdge(D, E, 1),
- new TestEdge(A, E, 2)));
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- graphSearch().search(graph, A, E, weight, GraphPathSearch.ALL_PATHS);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- System.out.println("\n\n" + paths + "\n\n\ndone\n");
- assertEquals("incorrect paths count", 3, paths.size());
- DisjointPathPair<TestVertex, TestEdge> dpp = (DisjointPathPair<TestVertex, TestEdge>) paths.iterator().next();
- assertEquals("incorrect disjoint paths per path", 2, dpp.size());
- }
-
- @Test
- public void differingPrimaryAndBackupPathLengths() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(A, D, 1),
- new TestEdge(D, C, 1),
- new TestEdge(B, E, 1),
- new TestEdge(C, E, 1)));
- executeSearch(graphSearch(), graph, A, E, weight, 1, 5.0);
- }
-
- @Test
- public void onePath() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(A, C, 4),
- new TestEdge(C, D, 1)));
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- assertEquals("incorrect paths count", 1, paths.size());
- DisjointPathPair<TestVertex, TestEdge> dpp = (DisjointPathPair<TestVertex, TestEdge>) paths.iterator().next();
- assertEquals("incorrect disjoint paths count", 1, dpp.size());
- }
-
- @Test
- public void noPath() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(A, C, 4)));
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- assertEquals("incorrect paths count", paths.size(), 0);
- }
-
- @Test
- public void disconnected() {
- setWeights();
- Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
- of());
- GraphPathSearch.Result<TestVertex, TestEdge> result =
- graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
- Set<Path<TestVertex, TestEdge>> paths = result.paths();
- assertEquals("incorrect paths count", 0, paths.size());
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TarjanGraphSearchTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TarjanGraphSearchTest.java
deleted file mode 100644
index 40f90513..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TarjanGraphSearchTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import org.junit.Test;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.assertEquals;
-import static org.onlab.graph.TarjanGraphSearch.SccResult;
-
-/**
- * Tarjan graph search tests.
- */
-public class TarjanGraphSearchTest extends GraphTest {
-
- private void validate(SccResult<TestVertex, TestEdge> result, int cc) {
- System.out.println("Cluster count: " + result.clusterVertexes().size());
- System.out.println("Clusters: " + result.clusterVertexes());
- assertEquals("incorrect cluster count", cc, result.clusterCount());
- }
-
- private void validate(SccResult<TestVertex, TestEdge> result,
- int i, int vc, int ec) {
- assertEquals("incorrect cluster count", vc, result.clusterVertexes().get(i).size());
- assertEquals("incorrect edge count", ec, result.clusterEdges().get(i).size());
- }
-
- @Test
- public void basic() {
- graph = new AdjacencyListsGraph<>(vertexes(), edges());
- TarjanGraphSearch<TestVertex, TestEdge> gs = new TarjanGraphSearch<>();
- SccResult<TestVertex, TestEdge> result = gs.search(graph, null);
- validate(result, 6);
- }
-
- @Test
- public void singleCluster() {
- graph = new AdjacencyListsGraph<>(vertexes(),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, E, 1),
- new TestEdge(E, F, 1),
- new TestEdge(F, G, 1),
- new TestEdge(G, H, 1),
- new TestEdge(H, A, 1)));
-
- TarjanGraphSearch<TestVertex, TestEdge> gs = new TarjanGraphSearch<>();
- SccResult<TestVertex, TestEdge> result = gs.search(graph, null);
- validate(result, 1);
- validate(result, 0, 8, 8);
- }
-
- @Test
- public void twoUnconnectedCluster() {
- graph = new AdjacencyListsGraph<>(vertexes(),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, A, 1),
- new TestEdge(E, F, 1),
- new TestEdge(F, G, 1),
- new TestEdge(G, H, 1),
- new TestEdge(H, E, 1)));
- TarjanGraphSearch<TestVertex, TestEdge> gs = new TarjanGraphSearch<>();
- SccResult<TestVertex, TestEdge> result = gs.search(graph, null);
- validate(result, 2);
- validate(result, 0, 4, 4);
- validate(result, 1, 4, 4);
- }
-
- @Test
- public void twoWeaklyConnectedClusters() {
- graph = new AdjacencyListsGraph<>(vertexes(),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, A, 1),
- new TestEdge(E, F, 1),
- new TestEdge(F, G, 1),
- new TestEdge(G, H, 1),
- new TestEdge(H, E, 1),
- new TestEdge(B, E, 1)));
- TarjanGraphSearch<TestVertex, TestEdge> gs = new TarjanGraphSearch<>();
- SccResult<TestVertex, TestEdge> result = gs.search(graph, null);
- validate(result, 2);
- validate(result, 0, 4, 4);
- validate(result, 1, 4, 4);
- }
-
- @Test
- public void twoClustersConnectedWithIgnoredEdges() {
- graph = new AdjacencyListsGraph<>(vertexes(),
- of(new TestEdge(A, B, 1),
- new TestEdge(B, C, 1),
- new TestEdge(C, D, 1),
- new TestEdge(D, A, 1),
- new TestEdge(E, F, 1),
- new TestEdge(F, G, 1),
- new TestEdge(G, H, 1),
- new TestEdge(H, E, 1),
- new TestEdge(B, E, -1),
- new TestEdge(E, B, -1)));
-
- TarjanGraphSearch<TestVertex, TestEdge> gs = new TarjanGraphSearch<>();
- SccResult<TestVertex, TestEdge> result = gs.search(graph, weight);
- validate(result, 2);
- validate(result, 0, 4, 4);
- validate(result, 1, 4, 4);
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestEdge.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestEdge.java
deleted file mode 100644
index 951f655b..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestEdge.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Test edge.
- */
-public class TestEdge extends AbstractEdge<TestVertex> {
-
- private final double weight;
-
- /**
- * Creates a new edge between the specified source and destination vertexes.
- *
- * @param src source vertex
- * @param dst destination vertex
- * @param weight edge weight
- */
- public TestEdge(TestVertex src, TestVertex dst, double weight) {
- super(src, dst);
- this.weight = weight;
- }
-
- /**
- * Returns the edge weight.
- *
- * @return edge weight
- */
- public double weight() {
- return weight;
- }
-
- @Override
- public int hashCode() {
- return 31 * super.hashCode() + Objects.hash(weight);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof TestEdge) {
- final TestEdge other = (TestEdge) obj;
- return super.equals(obj) && Objects.equals(this.weight, other.weight);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return toStringHelper(this).add("src", src()).add("dst", dst()).
- add("weight", weight).toString();
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestVertex.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestVertex.java
deleted file mode 100644
index b0b92a4a..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/graph/TestVertex.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.graph;
-
-import java.util.Objects;
-
-/**
- * Test vertex.
- */
-public class TestVertex implements Vertex {
-
- private final String name;
-
- public TestVertex(String name) {
- this.name = name;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof TestVertex) {
- final TestVertex other = (TestVertex) obj;
- return Objects.equals(this.name, other.name);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return name;
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ArpTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ArpTest.java
deleted file mode 100644
index 62246245..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ArpTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for the ARP class.
- */
-public class ArpTest {
-
- private Deserializer<ARP> deserializer = ARP.deserializer();
-
- private final byte hwAddressLength = 6;
- private final byte protoAddressLength = 4;
-
- private MacAddress srcMac = MacAddress.valueOf(1);
- private MacAddress targetMac = MacAddress.valueOf(2);
- private Ip4Address srcIp = Ip4Address.valueOf(1);
- private Ip4Address targetIp = Ip4Address.valueOf(2);
-
- private byte[] byteHeader;
-
- @Before
- public void setUp() {
- ByteBuffer bb = ByteBuffer.allocate(ARP.INITIAL_HEADER_LENGTH +
- 2 * hwAddressLength + 2 * protoAddressLength);
- bb.putShort(ARP.HW_TYPE_ETHERNET);
- bb.putShort(ARP.PROTO_TYPE_IP);
- bb.put(hwAddressLength);
- bb.put(protoAddressLength);
- bb.putShort(ARP.OP_REPLY);
-
- bb.put(srcMac.toBytes());
- bb.put(srcIp.toOctets());
- bb.put(targetMac.toBytes());
- bb.put(targetIp.toOctets());
-
- byteHeader = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, byteHeader);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- ARP arp = deserializer.deserialize(byteHeader, 0, byteHeader.length);
-
- assertEquals(ARP.HW_TYPE_ETHERNET, arp.getHardwareType());
- assertEquals(ARP.PROTO_TYPE_IP, arp.getProtocolType());
- assertEquals(hwAddressLength, arp.getHardwareAddressLength());
- assertEquals(protoAddressLength, arp.getProtocolAddressLength());
- assertEquals(ARP.OP_REPLY, arp.getOpCode());
-
- assertTrue(Arrays.equals(srcMac.toBytes(), arp.getSenderHardwareAddress()));
- assertTrue(Arrays.equals(srcIp.toOctets(), arp.getSenderProtocolAddress()));
- assertTrue(Arrays.equals(targetMac.toBytes(), arp.getTargetHardwareAddress()));
- assertTrue(Arrays.equals(targetIp.toOctets(), arp.getTargetProtocolAddress()));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java
deleted file mode 100644
index aac81412..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import com.google.common.base.Charsets;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for DHCP class.
- */
-public class DhcpTest {
-
- private Deserializer<DHCP> deserializer = DHCP.deserializer();
-
- private byte opCode = 1;
- private byte hardwareType = 1;
- private byte hardwareAddressLength = Ethernet.DATALAYER_ADDRESS_LENGTH;
- private byte hops = 0;
- private int transactionId = 0x2ed4eb50;
- private short seconds = 0;
- private short flags = 0;
- private int clientIpAddress = 1;
- private int yourIpAddress = 2;
- private int serverIpAddress = 3;
- private int gatewayIpAddress = 4;
- private byte[] clientHardwareAddress = MacAddress.valueOf(500).toBytes();
- private String serverName = "test-server";
- private String bootFileName = "test-file";
-
- private String hostName = "test-host";
- private DHCPOption hostNameOption = new DHCPOption();
-
- private byte[] byteHeader;
-
- @Before
- public void setUp() {
- hostNameOption.setCode((byte) 55);
- hostNameOption.setLength((byte) hostName.length());
- hostNameOption.setData(hostName.getBytes(Charsets.US_ASCII));
-
- // Packet length is the fixed DHCP header plus option length plus an
- // extra byte to indicate 'end of options'.
- ByteBuffer bb = ByteBuffer.allocate(DHCP.MIN_HEADER_LENGTH +
- 2 + hostNameOption.getLength() + 1);
-
- bb.put(opCode);
- bb.put(hardwareType);
- bb.put(hardwareAddressLength);
- bb.put(hops);
- bb.putInt(transactionId);
- bb.putShort(seconds);
- bb.putShort(flags);
- bb.putInt(clientIpAddress);
- bb.putInt(yourIpAddress);
- bb.putInt(serverIpAddress);
- bb.putInt(gatewayIpAddress);
- bb.put(clientHardwareAddress);
-
- // need 16 bytes of zeros to pad out the client hardware address field
- bb.put(new byte[16 - hardwareAddressLength]);
-
- // Put server name and pad out to 64 bytes
- bb.put(serverName.getBytes(Charsets.US_ASCII));
- bb.put(new byte[64 - serverName.length()]);
-
- // Put boot file name and pad out to 128 bytes
- bb.put(bootFileName.getBytes(Charsets.US_ASCII));
- bb.put(new byte[128 - bootFileName.length()]);
-
- // Magic cookie
- bb.put("DHCP".getBytes(Charsets.US_ASCII));
-
- bb.put(hostNameOption.getCode());
- bb.put(hostNameOption.getLength());
- bb.put(hostNameOption.getData());
-
- // End of options marker
- bb.put((byte) (0xff & 255));
-
- byteHeader = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, byteHeader);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- DHCP dhcp = deserializer.deserialize(byteHeader, 0, byteHeader.length);
-
- assertEquals(opCode, dhcp.opCode);
- assertEquals(hardwareType, dhcp.hardwareType);
- assertEquals(hardwareAddressLength, dhcp.hardwareAddressLength);
- assertEquals(hops, dhcp.hops);
- assertEquals(transactionId, dhcp.transactionId);
- assertEquals(seconds, dhcp.seconds);
- assertEquals(flags, dhcp.flags);
- assertEquals(clientIpAddress, dhcp.clientIPAddress);
- assertEquals(yourIpAddress, dhcp.yourIPAddress);
- assertEquals(serverIpAddress, dhcp.serverIPAddress);
- assertEquals(gatewayIpAddress, dhcp.gatewayIPAddress);
- assertTrue(Arrays.equals(clientHardwareAddress, dhcp.clientHardwareAddress));
-
- assertEquals(serverName, dhcp.serverName);
- assertEquals(bootFileName, dhcp.bootFileName);
- assertEquals(2, dhcp.options.size());
- assertEquals(hostNameOption, dhcp.options.get(0));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/EthernetTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/EthernetTest.java
deleted file mode 100644
index 15a01fc3..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/EthernetTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit tests for the Ethernet class.
- */
-public class EthernetTest {
-
- private MacAddress dstMac;
- private MacAddress srcMac;
- private short ethertype = 6;
- private short vlan = 5;
-
- private Deserializer<Ethernet> deserializer;
-
- private byte[] byteHeader;
- private byte[] vlanByteHeader;
-
- @Before
- public void setUp() {
- deserializer = Ethernet.deserializer();
-
- byte[] dstMacBytes = {
- (byte) 0x88, (byte) 0x88, (byte) 0x88, (byte) 0x88, (byte) 0x88,
- (byte) 0x88 };
- dstMac = MacAddress.valueOf(dstMacBytes);
- byte[] srcMacBytes = {
- (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
- (byte) 0xaa };
- srcMac = MacAddress.valueOf(srcMacBytes);
-
- // Create Ethernet byte array with no VLAN header
- ByteBuffer bb = ByteBuffer.allocate(Ethernet.ETHERNET_HEADER_LENGTH);
- bb.put(dstMacBytes);
- bb.put(srcMacBytes);
- bb.putShort(ethertype);
-
- byteHeader = bb.array();
-
- // Create Ethernet byte array with a VLAN header
- bb = ByteBuffer.allocate(Ethernet.ETHERNET_HEADER_LENGTH + Ethernet.VLAN_HEADER_LENGTH);
- bb.put(dstMacBytes);
- bb.put(srcMacBytes);
- bb.putShort(Ethernet.TYPE_VLAN);
- bb.putShort(vlan);
- bb.putShort(ethertype);
-
- vlanByteHeader = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws DeserializationException {
- PacketTestUtils.testDeserializeTruncated(deserializer, vlanByteHeader);
- }
-
- @Test
- public void testDeserializeNoVlan() throws Exception {
- Ethernet eth = deserializer.deserialize(byteHeader, 0, byteHeader.length);
-
- assertEquals(dstMac, eth.getDestinationMAC());
- assertEquals(srcMac, eth.getSourceMAC());
- assertEquals(Ethernet.VLAN_UNTAGGED, eth.getVlanID());
- assertEquals(ethertype, eth.getEtherType());
- }
-
- @Test
- public void testDeserializeWithVlan() throws Exception {
- Ethernet eth = deserializer.deserialize(vlanByteHeader, 0, vlanByteHeader.length);
-
- assertEquals(dstMac, eth.getDestinationMAC());
- assertEquals(srcMac, eth.getSourceMAC());
- assertEquals(vlan, eth.getVlanID());
- assertEquals(ethertype, eth.getEtherType());
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMP6Test.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMP6Test.java
deleted file mode 100644
index 39ddc24c..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMP6Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link ICMP6}.
- */
-public class ICMP6Test {
- private static final byte[] IPV6_SOURCE_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01
- };
- private static final byte[] IPV6_DESTINATION_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02
- };
-
- private static IPv6 ipv6 = new IPv6();
- private static byte[] bytePacket = {
- ICMP6.ECHO_REQUEST, // type
- (byte) 0x00, // code
- (byte) 0x82, (byte) 0xbc, // checksum
- };
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- ipv6.setSourceAddress(IPV6_SOURCE_ADDRESS);
- ipv6.setDestinationAddress(IPV6_DESTINATION_ADDRESS);
- ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- ICMP6 icmp6 = new ICMP6();
- icmp6.setIcmpType(ICMP6.ECHO_REQUEST);
- icmp6.setIcmpCode((byte) 0);
- icmp6.setParent(ipv6);
-
- assertArrayEquals(bytePacket, icmp6.serialize());
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(ICMP6.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(ICMP6.deserializer(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- ICMP6 icmp6 = ICMP6.deserializer().deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(icmp6.getIcmpType(), is(ICMP6.ECHO_REQUEST));
- assertThat(icmp6.getIcmpCode(), is((byte) 0x00));
- assertThat(icmp6.getChecksum(), is((short) 0x82bc));
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- ICMP6 icmp61 = new ICMP6();
- icmp61.setIcmpType(ICMP6.ECHO_REQUEST);
- icmp61.setIcmpCode((byte) 0);
- icmp61.setChecksum((short) 0);
-
- ICMP6 icmp62 = new ICMP6();
- icmp62.setIcmpType(ICMP6.ECHO_REPLY);
- icmp62.setIcmpCode((byte) 0);
- icmp62.setChecksum((short) 0);
-
- assertTrue(icmp61.equals(icmp61));
- assertFalse(icmp61.equals(icmp62));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMPTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMPTest.java
deleted file mode 100644
index 8514aa59..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ICMPTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit tests for the ICMP class.
- */
-public class ICMPTest {
-
- private Deserializer<ICMP> deserializer;
-
- private byte icmpType = ICMP.TYPE_ECHO_REQUEST;
- private byte icmpCode = 4;
- private short checksum = 870;
-
- private byte[] headerBytes;
-
- @Before
- public void setUp() throws Exception {
- deserializer = ICMP.deserializer();
-
- ByteBuffer bb = ByteBuffer.allocate(ICMP.ICMP_HEADER_LENGTH);
-
- bb.put(icmpType);
- bb.put(icmpCode);
- bb.putShort(checksum);
-
- headerBytes = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, headerBytes);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- ICMP icmp = deserializer.deserialize(headerBytes, 0, headerBytes.length);
-
- assertEquals(icmpType, icmp.getIcmpType());
- assertEquals(icmpCode, icmp.getIcmpCode());
- assertEquals(checksum, icmp.getChecksum());
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IGMPTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IGMPTest.java
deleted file mode 100644
index a25f7217..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IGMPTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static junit.framework.Assert.assertTrue;
-
-/**
- * Unit tests for IGMP class.
- */
-public class IGMPTest {
- private Deserializer<IGMP> deserializer;
-
- private IGMP igmpQuery;
- private IGMP igmpMembership;
-
- private Ip4Address gaddr1;
- private Ip4Address gaddr2;
- private Ip4Address saddr1;
- private Ip4Address saddr2;
-
- @Before
- public void setUp() throws Exception {
- gaddr1 = Ip4Address.valueOf(0xe1010101);
- gaddr2 = Ip4Address.valueOf(0xe2020202);
- saddr1 = Ip4Address.valueOf(0x0a010101);
- saddr2 = Ip4Address.valueOf(0x0b020202);
-
- deserializer = IGMP.deserializer();
-
- // Create an IGMP Query object
- igmpQuery = new IGMP();
- igmpQuery.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY);
- igmpQuery.setMaxRespCode((byte) 0x7f);
- IGMPQuery q = new IGMPQuery(gaddr1, (byte) 0x7f);
- q.addSource(saddr1);
- q.addSource(saddr2);
- q.setSbit(false);
- igmpQuery.groups.add(q);
-
- // Create an IGMP Membership Object
- igmpMembership = new IGMP();
- igmpMembership.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT);
- IGMPMembership g1 = new IGMPMembership(gaddr1);
- g1.addSource(saddr1);
- g1.addSource(saddr2);
- igmpMembership.groups.add(g1);
- IGMPMembership g2 = new IGMPMembership(gaddr2);
- g2.addSource(saddr1);
- g2.addSource(saddr2);
- igmpMembership.groups.add(g2);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- byte [] bits = igmpQuery.serialize();
- PacketTestUtils.testDeserializeTruncated(deserializer, bits);
-
- bits = igmpMembership.serialize();
- PacketTestUtils.testDeserializeTruncated(deserializer, bits);
- }
-
- @Test
- public void testDeserializeQuery() throws Exception {
- byte [] data = igmpQuery.serialize();
- IGMP igmp = deserializer.deserialize(data, 0, data.length);
- assertTrue(igmp.equals(igmpQuery));
- }
-
- @Test
- public void testDeserializeMembership() throws Exception {
- byte [] data = igmpMembership.serialize();
- IGMP igmp = deserializer.deserialize(data, 0, data.length);
- assertTrue(igmp.equals(igmpMembership));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv4Test.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv4Test.java
deleted file mode 100644
index 1bacf2a2..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv4Test.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for IPv4 class.
- */
-public class IPv4Test {
-
- private Deserializer<IPv4> deserializer;
-
- private byte version = 4;
- private byte headerLength = 6;
- private byte diffServ = 2;
- private short totalLength = 20;
- private short identification = 1;
- private byte flags = 1;
- private short fragmentOffset = 1;
- private byte ttl = 60;
- private byte protocol = 4;
- private short checksum = 4;
- private int sourceAddress = 1;
- private int destinationAddress = 2;
- private byte[] options = new byte[] {0x1, 0x2, 0x3, 0x4};
-
- private byte[] headerBytes;
-
- @Before
- public void setUp() throws Exception {
- deserializer = IPv4.deserializer();
-
- ByteBuffer bb = ByteBuffer.allocate(headerLength * 4);
-
- bb.put((byte) ((version & 0xf) << 4 | headerLength & 0xf));
- bb.put(diffServ);
- bb.putShort(totalLength);
- bb.putShort(identification);
- bb.putShort((short) ((flags & 0x7) << 13 | fragmentOffset & 0x1fff));
- bb.put(ttl);
- bb.put(protocol);
- bb.putShort(checksum);
- bb.putInt(sourceAddress);
- bb.putInt(destinationAddress);
- bb.put(options);
-
- headerBytes = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, headerBytes);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- IPv4 ipv4 = deserializer.deserialize(headerBytes, 0, headerBytes.length);
-
- assertEquals(version, ipv4.getVersion());
- assertEquals(headerLength, ipv4.getHeaderLength());
- assertEquals(diffServ, ipv4.getDiffServ());
- assertEquals(totalLength, ipv4.getTotalLength());
- assertEquals(identification, ipv4.getIdentification());
- assertEquals(flags, ipv4.getFlags());
- assertEquals(fragmentOffset, ipv4.getFragmentOffset());
- assertEquals(ttl, ipv4.getTtl());
- assertEquals(protocol, ipv4.getProtocol());
- assertEquals(checksum, ipv4.getChecksum());
- assertEquals(sourceAddress, ipv4.getSourceAddress());
- assertEquals(destinationAddress, ipv4.getDestinationAddress());
- assertTrue(ipv4.isTruncated());
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv6Test.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv6Test.java
deleted file mode 100644
index 720a4d20..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IPv6Test.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link IPv6}.
- */
-public class IPv6Test {
- private static final byte[] SOURCE_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- private static final byte[] DESTINATION_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
- };
- private static Data data;
- private static UDP udp;
- private static byte[] bytePacket;
-
- private Deserializer<IPv6> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- data = new Data();
- data.setData("testSerialize".getBytes());
- udp = new UDP();
- udp.setPayload(data);
-
- byte[] bytePayload = udp.serialize();
- byte[] byteHeader = {
- (byte) 0x69, (byte) 0x31, (byte) 0x35, (byte) 0x79,
- (byte) (bytePayload.length >> 8 & 0xff), (byte) (bytePayload.length & 0xff),
- (byte) 0x11, (byte) 0x20,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8,
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = IPv6.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- IPv6 ipv6 = new IPv6();
- ipv6.setPayload(udp);
- ipv6.setVersion((byte) 6);
- ipv6.setTrafficClass((byte) 0x93);
- ipv6.setFlowLabel(0x13579);
- ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
- ipv6.setHopLimit((byte) 32);
- ipv6.setSourceAddress(SOURCE_ADDRESS);
- ipv6.setDestinationAddress(DESTINATION_ADDRESS);
-
- assertArrayEquals(ipv6.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the IPv6 header
- byte[] ipv6Header = new byte[IPv6.FIXED_HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(ipv6Header);
-
- PacketTestUtils.testDeserializeTruncated(deserializer, ipv6Header);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- IPv6 ipv6 = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(ipv6.getVersion(), is((byte) 6));
- assertThat(ipv6.getTrafficClass(), is((byte) 0x93));
- assertThat(ipv6.getFlowLabel(), is(0x13579));
- assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP));
- assertThat(ipv6.getHopLimit(), is((byte) 32));
- assertArrayEquals(ipv6.getSourceAddress(), SOURCE_ADDRESS);
- assertArrayEquals(ipv6.getDestinationAddress(), DESTINATION_ADDRESS);
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- IPv6 packet1 = new IPv6();
- packet1.setPayload(udp);
- packet1.setVersion((byte) 6);
- packet1.setTrafficClass((byte) 0x93);
- packet1.setFlowLabel(0x13579);
- packet1.setNextHeader(IPv6.PROTOCOL_UDP);
- packet1.setHopLimit((byte) 32);
- packet1.setSourceAddress(SOURCE_ADDRESS);
- packet1.setDestinationAddress(DESTINATION_ADDRESS);
-
- IPv6 packet2 = new IPv6();
- packet2.setPayload(udp);
- packet2.setVersion((byte) 6);
- packet2.setTrafficClass((byte) 0x93);
- packet2.setFlowLabel(0x13579);
- packet2.setNextHeader(IPv6.PROTOCOL_UDP);
- packet2.setHopLimit((byte) 32);
- packet2.setSourceAddress(DESTINATION_ADDRESS);
- packet2.setDestinationAddress(SOURCE_ADDRESS);
-
- assertTrue(packet1.equals(packet1));
- assertFalse(packet1.equals(packet2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4AddressTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4AddressTest.java
deleted file mode 100644
index 3bbf0009..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4AddressTest.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import com.google.common.net.InetAddresses;
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import java.net.InetAddress;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * Tests for class {@link Ip4Address}.
- */
-public class Ip4AddressTest {
- /**
- * Tests the immutability of {@link Ip4Address}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutable(Ip4Address.class);
- }
-
- /**
- * Tests the IPv4 address version constant.
- */
- @Test
- public void testAddressVersion() {
- assertThat(Ip4Address.VERSION, is(IpAddress.Version.INET));
- }
-
- /**
- * Tests the length of the address in bytes (octets).
- */
- @Test
- public void testAddrByteLength() {
- assertThat(Ip4Address.BYTE_LENGTH, is(4));
- }
-
- /**
- * Tests the length of the address in bits.
- */
- @Test
- public void testAddrBitLength() {
- assertThat(Ip4Address.BIT_LENGTH, is(32));
- }
-
- /**
- * Tests returning the IP address version.
- */
- @Test
- public void testVersion() {
- Ip4Address ipAddress;
-
- // IPv4
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- assertThat(ipAddress.version(), is(IpAddress.Version.INET));
- }
-
- /**
- * Tests returning an IPv4 address as a byte array.
- */
- @Test
- public void testAddressToOctetsIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {0, 0, 0, 0};
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = Ip4Address.valueOf("255.255.255.255");
- assertThat(ipAddress.toOctets(), is(value));
- }
-
- /**
- * Tests returning an IPv4 address as an integer.
- */
- @Test
- public void testToInt() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- assertThat(ipAddress.toInt(), is(0x01020304));
-
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- assertThat(ipAddress.toInt(), is(0));
-
- ipAddress = Ip4Address.valueOf("255.255.255.255");
- assertThat(ipAddress.toInt(), is(-1));
- }
-
- /**
- * Tests valueOf() converter for IPv4 integer value.
- */
- @Test
- public void testValueOfForIntegerIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.valueOf(0x01020304);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = Ip4Address.valueOf(0);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = Ip4Address.valueOf(0xffffffff);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipAddress = Ip4Address.valueOf(value);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- value = new byte[] {0, 0, 0, 0};
- ipAddress = Ip4Address.valueOf(value);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = Ip4Address.valueOf(value);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv4.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = null;
- ipAddress = Ip4Address.valueOf(value);
- }
-
- /**
- * Tests invalid valueOf() converger for an array that is too short for
- * IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3};
- ipAddress = Ip4Address.valueOf(value);
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array and an offset.
- */
- @Test
- public void testValueOfByteArrayOffsetIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 1, 2, 3, 4,
- 44, 55}; // Extra bytes
- ipAddress = Ip4Address.valueOf(value, 3);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- value = new byte[] {11, 22, // Preamble
- 0, 0, 0, 0,
- 33}; // Extra bytes
- ipAddress = Ip4Address.valueOf(value, 2);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- value = new byte[] {11, 22, // Preamble
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- 33}; // Extra bytes
- ipAddress = Ip4Address.valueOf(value, 2);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests invalid valueOf() converger for an array and an invalid offset
- * for IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfArrayInvalidOffsetIPv4() {
- Ip4Address ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 1, 2, 3, 4,
- 44, 55}; // Extra bytes
- ipAddress = Ip4Address.valueOf(value, 6);
- }
-
- /**
- * Tests valueOf() converter for IPv4 InetAddress.
- */
- @Test
- public void testValueOfInetAddressIPv4() {
- Ip4Address ipAddress;
- InetAddress inetAddress;
-
- inetAddress = InetAddresses.forString("1.2.3.4");
- ipAddress = Ip4Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- inetAddress = InetAddresses.forString("0.0.0.0");
- ipAddress = Ip4Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- inetAddress = InetAddresses.forString("255.255.255.255");
- ipAddress = Ip4Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv4 string.
- */
- @Test
- public void testValueOfStringIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = Ip4Address.valueOf("255.255.255.255");
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- Ip4Address ipAddress;
-
- String fromString = null;
- ipAddress = Ip4Address.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- Ip4Address ipAddress;
-
- String fromString = "";
- ipAddress = Ip4Address.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- Ip4Address ipAddress;
-
- String fromString = "NoSuchIpAddress";
- ipAddress = Ip4Address.valueOf(fromString);
- }
-
- /**
- * Tests making a mask prefix for a given prefix length for IPv4.
- */
- @Test
- public void testMakeMaskPrefixIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.makeMaskPrefix(25);
- assertThat(ipAddress.toString(), is("255.255.255.128"));
-
- ipAddress = Ip4Address.makeMaskPrefix(0);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = Ip4Address.makeMaskPrefix(32);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv4:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskPrefixIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.makeMaskPrefix(-1);
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv4:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskPrefixIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.makeMaskPrefix(33);
- }
-
- /**
- * Tests making of a masked address for IPv4.
- */
- @Test
- public void testMakeMaskedAddressIPv4() {
- Ip4Address ipAddress = Ip4Address.valueOf("1.2.3.5");
- Ip4Address ipAddressMasked;
-
- ipAddressMasked = Ip4Address.makeMaskedAddress(ipAddress, 24);
- assertThat(ipAddressMasked.toString(), is("1.2.3.0"));
-
- ipAddressMasked = Ip4Address.makeMaskedAddress(ipAddress, 0);
- assertThat(ipAddressMasked.toString(), is("0.0.0.0"));
-
- ipAddressMasked = Ip4Address.makeMaskedAddress(ipAddress, 32);
- assertThat(ipAddressMasked.toString(), is("1.2.3.5"));
- }
-
- /**
- * Tests making of a masked address for invalid prefix length for IPv4:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskedAddressIPv4() {
- Ip4Address ipAddress = Ip4Address.valueOf("1.2.3.5");
- Ip4Address ipAddressMasked;
-
- ipAddressMasked = Ip4Address.makeMaskedAddress(ipAddress, -1);
- }
-
- /**
- * Tests making of a masked address for an invalid prefix length for IPv4:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskedAddressIPv4() {
- Ip4Address ipAddress = Ip4Address.valueOf("1.2.3.5");
- Ip4Address ipAddressMasked;
-
- ipAddressMasked = Ip4Address.makeMaskedAddress(ipAddress, 33);
- }
-
- /**
- * Tests comparison of {@link Ip4Address} for IPv4.
- */
- @Test
- public void testComparisonIPv4() {
- Ip4Address addr1, addr2, addr3, addr4;
-
- addr1 = Ip4Address.valueOf("1.2.3.4");
- addr2 = Ip4Address.valueOf("1.2.3.4");
- addr3 = Ip4Address.valueOf("1.2.3.3");
- addr4 = Ip4Address.valueOf("1.2.3.5");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = Ip4Address.valueOf("255.2.3.4");
- addr2 = Ip4Address.valueOf("255.2.3.4");
- addr3 = Ip4Address.valueOf("255.2.3.3");
- addr4 = Ip4Address.valueOf("255.2.3.5");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
- }
-
- /**
- * Tests equality of {@link Ip4Address} for IPv4.
- */
- @Test
- public void testEqualityIPv4() {
- new EqualsTester()
- .addEqualityGroup(Ip4Address.valueOf("1.2.3.4"),
- Ip4Address.valueOf("1.2.3.4"))
- .addEqualityGroup(Ip4Address.valueOf("1.2.3.5"),
- Ip4Address.valueOf("1.2.3.5"))
- .addEqualityGroup(Ip4Address.valueOf("0.0.0.0"),
- Ip4Address.valueOf("0.0.0.0"))
- .addEqualityGroup(Ip4Address.valueOf("255.255.255.255"),
- Ip4Address.valueOf("255.255.255.255"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv4.
- */
- @Test
- public void testToStringIPv4() {
- Ip4Address ipAddress;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = Ip4Address.valueOf("255.255.255.255");
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4PrefixTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4PrefixTest.java
deleted file mode 100644
index c731ed66..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip4PrefixTest.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * Tests for class {@link Ip4Prefix}.
- */
-public class Ip4PrefixTest {
- /**
- * Tests the immutability of {@link Ip4Prefix}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutable(Ip4Prefix.class);
- }
-
- /**
- * Tests the IPv4 prefix address version constant.
- */
- @Test
- public void testAddressVersion() {
- assertThat(Ip4Prefix.VERSION, is(IpAddress.Version.INET));
- }
-
- /**
- * Tests the maximum mask length.
- */
- @Test
- public void testMaxMaskLength() {
- assertThat(Ip4Prefix.MAX_MASK_LENGTH, is(32));
- }
-
- /**
- * Tests returning the IP version of the prefix.
- */
- @Test
- public void testVersion() {
- Ip4Prefix ipPrefix;
-
- // IPv4
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.version(), is(IpAddress.Version.INET));
- }
-
- /**
- * Tests returning the IP address value and IP address prefix length of
- * an IPv4 prefix.
- */
- @Test
- public void testAddressAndPrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.0/24");
- assertThat(ipPrefix.address(), equalTo(Ip4Address.valueOf("1.2.3.0")));
- assertThat(ipPrefix.prefixLength(), is(24));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.address(), equalTo(Ip4Address.valueOf("1.2.3.0")));
- assertThat(ipPrefix.prefixLength(), is(24));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/32");
- assertThat(ipPrefix.address(), equalTo(Ip4Address.valueOf("1.2.3.4")));
- assertThat(ipPrefix.prefixLength(), is(32));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.5/32");
- assertThat(ipPrefix.address(), equalTo(Ip4Address.valueOf("1.2.3.5")));
- assertThat(ipPrefix.prefixLength(), is(32));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.address(), equalTo(Ip4Address.valueOf("0.0.0.0")));
- assertThat(ipPrefix.prefixLength(), is(0));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.address(),
- equalTo(Ip4Address.valueOf("255.255.255.255")));
- assertThat(ipPrefix.prefixLength(), is(32));
- }
-
- /**
- * Tests valueOf() converter for IPv4 integer value.
- */
- @Test
- public void testValueOfForIntegerIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf(0x01020304, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf(0x01020304, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipPrefix = Ip4Prefix.valueOf(0x01020305, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipPrefix = Ip4Prefix.valueOf(0, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(0, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipPrefix = Ip4Prefix.valueOf(0xffffffff, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(0xffffffff, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = Ip4Prefix.valueOf(0xffffffff, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 integer value and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIntegerNegativePrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf(0x01020304, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 integer value and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIntegerTooLongPrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf(0x01020304, 33);
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv4() {
- Ip4Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = Ip4Prefix.valueOf(value, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf(value, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- value = new byte[] {1, 2, 3, 5};
- ipPrefix = Ip4Prefix.valueOf(value, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- value = new byte[] {0, 0, 0, 0};
- ipPrefix = Ip4Prefix.valueOf(value, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(value, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipPrefix = Ip4Prefix.valueOf(value, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(value, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = Ip4Prefix.valueOf(value, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv4.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv4() {
- Ip4Prefix ipPrefix;
- byte[] value;
-
- value = null;
- ipPrefix = Ip4Prefix.valueOf(value, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for a short array for IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv4() {
- Ip4Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3};
- ipPrefix = Ip4Prefix.valueOf(value, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 byte array and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayNegativePrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = Ip4Prefix.valueOf(value, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 byte array and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayTooLongPrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = Ip4Prefix.valueOf(value, 33);
- }
-
- /**
- * Tests valueOf() converter for IPv4 address.
- */
- @Test
- public void testValueOfAddressIPv4() {
- Ip4Address ipAddress;
- Ip4Prefix ipPrefix;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipAddress = Ip4Address.valueOf("1.2.3.5");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipAddress = Ip4Address.valueOf("0.0.0.0");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipAddress = Ip4Address.valueOf("255.255.255.255");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null IP address.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullAddress() {
- Ip4Address ipAddress;
- Ip4Prefix ipPrefix;
-
- ipAddress = null;
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 address and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressNegativePrefixLengthIPv4() {
- Ip4Address ipAddress;
- Ip4Prefix ipPrefix;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 address and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressTooLongPrefixLengthIPv4() {
- Ip4Address ipAddress;
- Ip4Prefix ipPrefix;
-
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- ipPrefix = Ip4Prefix.valueOf(ipAddress, 33);
- }
-
- /**
- * Tests valueOf() converter for IPv4 string.
- */
- @Test
- public void testValueOfStringIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/32");
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.5/32");
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/32");
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/16");
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- Ip4Prefix ipPrefix;
- String fromString;
-
- fromString = null;
- ipPrefix = Ip4Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- Ip4Prefix ipPrefix;
- String fromString;
-
- fromString = "";
- ipPrefix = Ip4Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- Ip4Prefix ipPrefix;
- String fromString;
-
- fromString = "NoSuchIpPrefix";
- ipPrefix = Ip4Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 string and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringNegativePrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/-1");
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 string and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringTooLongPrefixLengthIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/33");
- }
-
- /**
- * Tests IP prefix contains another IP prefix for IPv4.
- */
- @Test
- public void testContainsIpPrefixIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.0.0/24");
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/32")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/0")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.0.0/32");
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/32")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/0")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/32")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.4/32")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/16")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("1.3.0.0/24")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/16")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/0")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/24")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/32")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(Ip4Prefix.valueOf("0.0.0.0/0")));
- assertTrue(ipPrefix.contains(Ip4Prefix.valueOf("255.255.255.255/32")));
- }
-
- /**
- * Tests IP prefix contains IP address for IPv4.
- */
- @Test
- public void testContainsIpAddressIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.0.0/24");
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.2.0.0")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("0.0.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("255.255.255.255")));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.0.0/32");
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.2.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("0.0.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("255.255.255.255")));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.2.0.0")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.2.0.4")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("1.3.0.0")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("0.0.0.0")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("255.255.255.255")));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.2.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(Ip4Address.valueOf("0.0.0.0")));
- assertTrue(ipPrefix.contains(Ip4Address.valueOf("255.255.255.255")));
- }
-
- /**
- * Tests equality of {@link Ip4Prefix} for IPv4.
- */
- @Test
- public void testEqualityIPv4() {
- new EqualsTester()
- .addEqualityGroup(Ip4Prefix.valueOf("1.2.0.0/24"),
- Ip4Prefix.valueOf("1.2.0.0/24"),
- Ip4Prefix.valueOf("1.2.0.4/24"))
- .addEqualityGroup(Ip4Prefix.valueOf("1.2.0.0/16"),
- Ip4Prefix.valueOf("1.2.0.0/16"))
- .addEqualityGroup(Ip4Prefix.valueOf("1.2.0.0/32"),
- Ip4Prefix.valueOf("1.2.0.0/32"))
- .addEqualityGroup(Ip4Prefix.valueOf("1.3.0.0/24"),
- Ip4Prefix.valueOf("1.3.0.0/24"))
- .addEqualityGroup(Ip4Prefix.valueOf("0.0.0.0/0"),
- Ip4Prefix.valueOf("0.0.0.0/0"))
- .addEqualityGroup(Ip4Prefix.valueOf("255.255.255.255/32"),
- Ip4Prefix.valueOf("255.255.255.255/32"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv4.
- */
- @Test
- public void testToStringIPv4() {
- Ip4Prefix ipPrefix;
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.0/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = Ip4Prefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = Ip4Prefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6AddressTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6AddressTest.java
deleted file mode 100644
index e7d017d1..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6AddressTest.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import com.google.common.net.InetAddresses;
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import java.net.InetAddress;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * Tests for class {@link Ip6Address}.
- */
-public class Ip6AddressTest {
- /**
- * Tests the immutability of {@link Ip6Address}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutable(Ip6Address.class);
- }
-
- /**
- * Tests the IPv4 address version constant.
- */
- @Test
- public void testAddressVersion() {
- assertThat(Ip6Address.VERSION, is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests the length of the address in bytes (octets).
- */
- @Test
- public void testAddrByteLength() {
- assertThat(Ip6Address.BYTE_LENGTH, is(16));
- }
-
- /**
- * Tests the length of the address in bits.
- */
- @Test
- public void testAddrBitLength() {
- assertThat(Ip6Address.BIT_LENGTH, is(128));
- }
-
- /**
- * Tests returning the IP address version.
- */
- @Test
- public void testVersion() {
- IpAddress ipAddress;
-
- // IPv6
- ipAddress = IpAddress.valueOf("::");
- assertThat(ipAddress.version(), is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests returning an IPv6 address as a byte array.
- */
- @Test
- public void testAddressToOctetsIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88};
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipAddress = Ip6Address.valueOf("::");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress =
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toOctets(), is(value));
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88};
- ipAddress = Ip6Address.valueOf(value);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipAddress = Ip6Address.valueOf(value);
- assertThat(ipAddress.toString(), is("::"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = Ip6Address.valueOf(value);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv6.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = null;
- ipAddress = Ip6Address.valueOf(value);
- }
-
- /**
- * Tests invalid valueOf() converger for an array that is too short for
- * IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- ipAddress = Ip6Address.valueOf(value);
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array and an offset.
- */
- @Test
- public void testValueOfByteArrayOffsetIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88,
- 44, 55}; // Extra bytes
- ipAddress = Ip6Address.valueOf(value, 3);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- value = new byte[] {11, 22, // Preamble
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 33}; // Extra bytes
- ipAddress = Ip6Address.valueOf(value, 2);
- assertThat(ipAddress.toString(), is("::"));
-
- value = new byte[] {11, 22, // Preamble
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- 33}; // Extra bytes
- ipAddress = Ip6Address.valueOf(value, 2);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converger for an array and an invalid offset
- * for IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfArrayInvalidOffsetIPv6() {
- Ip6Address ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88,
- 44, 55}; // Extra bytes
- ipAddress = Ip6Address.valueOf(value, 6);
- }
-
- /**
- * Tests valueOf() converter for IPv6 InetAddress.
- */
- @Test
- public void testValueOfInetAddressIPv6() {
- Ip6Address ipAddress;
- InetAddress inetAddress;
-
- inetAddress =
- InetAddresses.forString("1111:2222:3333:4444:5555:6666:7777:8888");
- ipAddress = Ip6Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- inetAddress = InetAddresses.forString("::");
- ipAddress = Ip6Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("::"));
-
- inetAddress =
- InetAddresses.forString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- ipAddress = Ip6Address.valueOf(inetAddress);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 string.
- */
- @Test
- public void testValueOfStringIPv6() {
- Ip6Address ipAddress;
-
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- ipAddress = Ip6Address.valueOf("::");
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress =
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- Ip6Address ipAddress;
-
- String fromString = null;
- ipAddress = Ip6Address.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- Ip6Address ipAddress;
-
- String fromString = "";
- ipAddress = Ip6Address.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- Ip6Address ipAddress;
-
- String fromString = "NoSuchIpAddress";
- ipAddress = Ip6Address.valueOf(fromString);
- }
-
- /**
- * Tests making a mask prefix for a given prefix length for IPv6.
- */
- @Test
- public void testMakeMaskPrefixIPv6() {
- Ip6Address ipAddress;
-
- ipAddress = Ip6Address.makeMaskPrefix(8);
- assertThat(ipAddress.toString(), is("ff00::"));
-
- ipAddress = Ip6Address.makeMaskPrefix(120);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
-
- ipAddress = Ip6Address.makeMaskPrefix(0);
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress = Ip6Address.makeMaskPrefix(128);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
-
- ipAddress = Ip6Address.makeMaskPrefix(64);
- assertThat(ipAddress.toString(), is("ffff:ffff:ffff:ffff::"));
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv6:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskPrefixIPv6() {
- Ip6Address ipAddress;
-
- ipAddress = Ip6Address.makeMaskPrefix(-1);
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv6:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskPrefixIPv6() {
- Ip6Address ipAddress;
-
- ipAddress = Ip6Address.makeMaskPrefix(129);
- }
-
- /**
- * Tests making of a masked address for IPv6.
- */
- @Test
- public void testMakeMaskedAddressIPv6() {
- Ip6Address ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- Ip6Address ipAddressMasked;
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 8);
- assertThat(ipAddressMasked.toString(), is("1100::"));
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 120);
- assertThat(ipAddressMasked.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800"));
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 0);
- assertThat(ipAddressMasked.toString(), is("::"));
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 128);
- assertThat(ipAddressMasked.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8885"));
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 64);
- assertThat(ipAddressMasked.toString(), is("1111:2222:3333:4444::"));
- }
-
- /**
- * Tests making of a masked address for invalid prefix length for IPv6:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskedAddressIPv6() {
- Ip6Address ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- Ip6Address ipAddressMasked;
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, -1);
- }
-
- /**
- * Tests making of a masked address for an invalid prefix length for IPv6:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskedAddressIPv6() {
- Ip6Address ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- Ip6Address ipAddressMasked;
-
- ipAddressMasked = Ip6Address.makeMaskedAddress(ipAddress, 129);
- }
-
- /**
- * Tests comparison of {@link Ip6Address} for IPv6.
- */
- @Test
- public void testComparisonIPv6() {
- Ip6Address addr1, addr2, addr3, addr4;
-
- addr1 = Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- addr2 = Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- addr3 = Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8887");
- addr4 = Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8889");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr2 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr3 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8887");
- addr4 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8889");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr2 = Ip6Address.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr3 = Ip6Address.valueOf("ffff:2222:3333:4443:5555:6666:7777:8888");
- addr4 = Ip6Address.valueOf("ffff:2222:3333:4445:5555:6666:7777:8888");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
- }
-
- /**
- * Tests equality of {@link Ip6Address} for IPv6.
- */
- @Test
- public void testEqualityIPv6() {
- new EqualsTester()
- .addEqualityGroup(
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"),
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"))
- .addEqualityGroup(
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"),
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"))
- .addEqualityGroup(
- Ip6Address.valueOf("::"),
- Ip6Address.valueOf("::"))
- .addEqualityGroup(
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv6.
- */
- @Test
- public void testToStringIPv6() {
- Ip6Address ipAddress;
-
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- ipAddress = Ip6Address.valueOf("1111::8888");
- assertThat(ipAddress.toString(), is("1111::8888"));
-
- ipAddress = Ip6Address.valueOf("1111::");
- assertThat(ipAddress.toString(), is("1111::"));
-
- ipAddress = Ip6Address.valueOf("::8888");
- assertThat(ipAddress.toString(), is("::8888"));
-
- ipAddress = Ip6Address.valueOf("::");
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress =
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6PrefixTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6PrefixTest.java
deleted file mode 100644
index dceeb840..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/Ip6PrefixTest.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * Tests for class {@link Ip6Prefix}.
- */
-public class Ip6PrefixTest {
- /**
- * Tests the immutability of {@link Ip6Prefix}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutable(Ip6Prefix.class);
- }
-
- /**
- * Tests the IPv4 prefix address version constant.
- */
- @Test
- public void testAddressVersion() {
- assertThat(Ip6Prefix.VERSION, is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests the maximum mask length.
- */
- @Test
- public void testMaxMaskLength() {
- assertThat(Ip6Prefix.MAX_MASK_LENGTH, is(128));
- }
-
- /**
- * Tests returning the IP version of the prefix.
- */
- @Test
- public void testVersion() {
- Ip6Prefix ipPrefix;
-
- // IPv6
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertThat(ipPrefix.version(), is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests returning the IP address value and IP address prefix length of
- * an IPv6 prefix.
- */
- @Test
- public void testAddressAndPrefixLengthIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix = Ip6Prefix.valueOf("1100::/8");
- assertThat(ipPrefix.address(), equalTo(Ip6Address.valueOf("1100::")));
- assertThat(ipPrefix.prefixLength(), is(8));
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/8");
- assertThat(ipPrefix.address(), equalTo(Ip6Address.valueOf("1100::")));
- assertThat(ipPrefix.prefixLength(), is(8));
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8800/120");
- assertThat(ipPrefix.address(),
- equalTo(Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8800")));
- assertThat(ipPrefix.prefixLength(), is(120));
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/128");
- assertThat(ipPrefix.address(),
- equalTo(Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8885")));
- assertThat(ipPrefix.prefixLength(), is(128));
-
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertThat(ipPrefix.address(), equalTo(Ip6Address.valueOf("::")));
- assertThat(ipPrefix.prefixLength(), is(0));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.address(),
- equalTo(Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
- assertThat(ipPrefix.prefixLength(), is(128));
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/64");
- assertThat(ipPrefix.address(),
- equalTo(Ip6Address.valueOf("1111:2222:3333:4444::")));
- assertThat(ipPrefix.prefixLength(), is(64));
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv6() {
- Ip6Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = Ip6Prefix.valueOf(value, 120);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix = Ip6Prefix.valueOf(value, 128);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipPrefix = Ip6Prefix.valueOf(value, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf(value, 128);
- assertThat(ipPrefix.toString(), is("::/128"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipPrefix = Ip6Prefix.valueOf(value, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf(value, 64);
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix = Ip6Prefix.valueOf(value, 128);
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv6.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv6() {
- Ip6Prefix ipPrefix;
- byte[] value;
-
- value = null;
- ipPrefix = Ip6Prefix.valueOf(value, 120);
- }
-
- /**
- * Tests invalid valueOf() converter for a short array for IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv6() {
- Ip6Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- ipPrefix = Ip6Prefix.valueOf(value, 120);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 byte array and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayNegativePrefixLengthIPv6() {
- Ip6Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = Ip6Prefix.valueOf(value, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 byte array and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayTooLongPrefixLengthIPv6() {
- Ip6Prefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = Ip6Prefix.valueOf(value, 129);
- }
-
- /**
- * Tests valueOf() converter for IPv6 address.
- */
- @Test
- public void testValueOfAddressIPv6() {
- Ip6Address ipAddress;
- Ip6Prefix ipPrefix;
-
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 120);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- ipAddress = Ip6Address.valueOf("::");
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(), is("::/128"));
-
- ipAddress =
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 64);
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null IP address.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullAddress() {
- Ip6Address ipAddress;
- Ip6Prefix ipPrefix;
-
- ipAddress = null;
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 address and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressNegativePrefixLengthIPv6() {
- Ip6Address ipAddress;
- Ip6Prefix ipPrefix;
-
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = Ip6Prefix.valueOf(ipAddress, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 address and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressTooLongPrefixLengthIPv6() {
- Ip6Address ipAddress;
- Ip6Prefix ipPrefix;
-
- ipAddress =
- Ip6Address.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = Ip6Prefix.valueOf(ipAddress, 129);
- }
-
- /**
- * Tests valueOf() converter for IPv6 string.
- */
- @Test
- public void testValueOfStringIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/120");
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/128");
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf("::/128");
- assertThat(ipPrefix.toString(), is("::/128"));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64");
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- Ip6Prefix ipPrefix;
- String fromString;
-
- fromString = null;
- ipPrefix = Ip6Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- Ip6Prefix ipPrefix;
- String fromString;
-
- fromString = "";
- ipPrefix = Ip6Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- Ip6Prefix ipPrefix;
- String fromString;
-
- fromString = "NoSuchIpPrefix";
- ipPrefix = Ip6Prefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 string and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringNegativePrefixLengthIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/-1");
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 string and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringTooLongPrefixLengthIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix =
- Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/129");
- }
-
- /**
- * Tests IP prefix contains another IP prefix for IPv6.
- */
- @Test
- public void testContainsIpPrefixIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix = Ip6Prefix.valueOf("1111:2222:3333:4444::/120");
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/0")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix = Ip6Prefix.valueOf("1111:2222:3333:4444::/128");
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/0")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::1/128")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4445::/120")));
- assertTrue(ipPrefix.contains(Ip6Prefix.valueOf("::/64")));
- assertTrue(ipPrefix.contains(Ip6Prefix.valueOf("::/0")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- Ip6Prefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(Ip6Prefix.valueOf("::/0")));
- assertTrue(ipPrefix.contains(
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
- }
-
- /**
- * Tests IP prefix contains IP address for IPv6.
- */
- @Test
- public void testContainsIpAddressIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix = Ip6Prefix.valueOf("1111:2222:3333:4444::/120");
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::")));
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(Ip6Address.valueOf("::")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix = Ip6Prefix.valueOf("1111:2222:3333:4444::/128");
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(Ip6Address.valueOf("::")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::")));
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::1")));
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4445::")));
- assertTrue(ipPrefix.contains(Ip6Address.valueOf("::")));
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix =
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- Ip6Address.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(Ip6Address.valueOf("::")));
- assertTrue(ipPrefix.contains(
- Ip6Address.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
- }
-
- /**
- * Tests equality of {@link Ip6Prefix} for IPv6.
- */
- @Test
- public void testEqualityIPv6() {
- new EqualsTester()
- .addEqualityGroup(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120"),
- Ip6Prefix.valueOf("1111:2222:3333:4444::1/120"),
- Ip6Prefix.valueOf("1111:2222:3333:4444::/120"))
- .addEqualityGroup(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64"),
- Ip6Prefix.valueOf("1111:2222:3333:4444::/64"))
- .addEqualityGroup(
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128"),
- Ip6Prefix.valueOf("1111:2222:3333:4444::/128"))
- .addEqualityGroup(
- Ip6Prefix.valueOf("1111:2222:3333:4445::/64"),
- Ip6Prefix.valueOf("1111:2222:3333:4445::/64"))
- .addEqualityGroup(
- Ip6Prefix.valueOf("::/0"),
- Ip6Prefix.valueOf("::/0"))
- .addEqualityGroup(
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"),
- Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv6.
- */
- @Test
- public void testToStringIPv6() {
- Ip6Prefix ipPrefix;
-
- ipPrefix = Ip6Prefix.valueOf("1100::/8");
- assertThat(ipPrefix.toString(), is("1100::/8"));
-
- ipPrefix = Ip6Prefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/8");
- assertThat(ipPrefix.toString(), is("1100::/8"));
-
- ipPrefix = Ip6Prefix.valueOf("::/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = Ip6Prefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpAddressTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpAddressTest.java
deleted file mode 100644
index 8618c466..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpAddressTest.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.net.InetAddress;
-
-import org.junit.Test;
-
-import com.google.common.net.InetAddresses;
-import com.google.common.testing.EqualsTester;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
-
-/**
- * Tests for class {@link IpAddress}.
- */
-public class IpAddressTest {
- /**
- * Tests the immutability of {@link IpAddress}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutableBaseClass(IpAddress.class);
- }
-
- /**
- * Tests the length of the address in bytes (octets).
- */
- @Test
- public void testAddrByteLength() {
- assertThat(IpAddress.INET_BYTE_LENGTH, is(4));
- assertThat(IpAddress.INET6_BYTE_LENGTH, is(16));
- assertThat(IpAddress.byteLength(IpAddress.Version.INET), is(4));
- assertThat(IpAddress.byteLength(IpAddress.Version.INET6), is(16));
- }
-
- /**
- * Tests the length of the address in bits.
- */
- @Test
- public void testAddrBitLength() {
- assertThat(IpAddress.INET_BIT_LENGTH, is(32));
- assertThat(IpAddress.INET6_BIT_LENGTH, is(128));
- }
-
- /**
- * Tests returning the IP address version.
- */
- @Test
- public void testVersion() {
- IpAddress ipAddress;
-
- // IPv4
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertThat(ipAddress.version(), is(IpAddress.Version.INET));
-
- // IPv6
- ipAddress = IpAddress.valueOf("::");
- assertThat(ipAddress.version(), is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests whether the IP version of an address is IPv4.
- */
- @Test
- public void testIsIp4() {
- IpAddress ipAddress;
-
- // IPv4
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertTrue(ipAddress.isIp4());
-
- // IPv6
- ipAddress = IpAddress.valueOf("::");
- assertFalse(ipAddress.isIp4());
- }
-
- /**
- * Tests whether the IP version of an address is IPv6.
- */
- @Test
- public void testIsIp6() {
- IpAddress ipAddress;
-
- // IPv4
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertFalse(ipAddress.isIp6());
-
- // IPv6
- ipAddress = IpAddress.valueOf("::");
- assertTrue(ipAddress.isIp6());
- }
-
- /**
- * Tests getting the Ip4Address and Ip6Address view of the IP address.
- */
- @Test
- public void testGetIp4AndIp6AddressView() {
- IpAddress ipAddress;
- Ip4Address ip4Address;
- Ip6Address ip6Address;
-
- // Pure IPv4 IpAddress
- ipAddress = IpAddress.valueOf("1.2.3.4");
- ip4Address = ipAddress.getIp4Address();
- ip6Address = ipAddress.getIp6Address();
- assertThat(ip4Address.toString(), is("1.2.3.4"));
- assertNull(ip6Address);
-
- // IPv4 IpAddress that is Ip4Address
- ipAddress = Ip4Address.valueOf("1.2.3.4");
- ip4Address = ipAddress.getIp4Address();
- ip6Address = ipAddress.getIp6Address();
- assertThat(ip4Address.toString(), is("1.2.3.4"));
- assertNull(ip6Address);
-
- // Pure IPv6 IpAddress
- ipAddress = IpAddress.valueOf("1111:2222::");
- ip4Address = ipAddress.getIp4Address();
- ip6Address = ipAddress.getIp6Address();
- assertNull(ip4Address);
- assertThat(ip6Address.toString(), is("1111:2222::"));
-
- // IPv6 IpAddress that is Ip6Address
- ipAddress = Ip6Address.valueOf("1111:2222::");
- ip4Address = ipAddress.getIp4Address();
- ip6Address = ipAddress.getIp6Address();
- assertNull(ip4Address);
- assertThat(ip6Address.toString(), is("1111:2222::"));
- }
-
- /**
- * Tests returning an IPv4 address as a byte array.
- */
- @Test
- public void testAddressToOctetsIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipAddress = IpAddress.valueOf("1.2.3.4");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {0, 0, 0, 0};
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = IpAddress.valueOf("255.255.255.255");
- assertThat(ipAddress.toOctets(), is(value));
- }
-
- /**
- * Tests returning an IPv6 address as a byte array.
- */
- @Test
- public void testAddressToOctetsIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88};
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipAddress = IpAddress.valueOf("::");
- assertThat(ipAddress.toOctets(), is(value));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress =
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toOctets(), is(value));
- }
-
- /**
- * Tests valueOf() converter for IPv4 integer value.
- */
- @Test
- public void testValueOfForIntegerIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.valueOf(0x01020304);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = IpAddress.valueOf(0);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = IpAddress.valueOf(0xffffffff);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- value = new byte[] {0, 0, 0, 0};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
- assertThat(ipAddress.toString(), is("::"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv4.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = null;
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv6.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = null;
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
- }
-
- /**
- * Tests invalid valueOf() converger for an array that is too short for
- * IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value);
- }
-
- /**
- * Tests invalid valueOf() converger for an array that is too short for
- * IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value);
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array and an offset.
- */
- @Test
- public void testValueOfByteArrayOffsetIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 1, 2, 3, 4,
- 44, 55}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value, 3);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- value = new byte[] {11, 22, // Preamble
- 0, 0, 0, 0,
- 33}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value, 2);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- value = new byte[] {11, 22, // Preamble
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- 33}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value, 2);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array and an offset.
- */
- @Test
- public void testValueOfByteArrayOffsetIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88,
- 44, 55}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value, 3);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- value = new byte[] {11, 22, // Preamble
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 33}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value, 2);
- assertThat(ipAddress.toString(), is("::"));
-
- value = new byte[] {11, 22, // Preamble
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- 33}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value, 2);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converger for an array and an invalid offset
- * for IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfArrayInvalidOffsetIPv4() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 1, 2, 3, 4,
- 44, 55}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value, 6);
- }
-
- /**
- * Tests invalid valueOf() converger for an array and an invalid offset
- * for IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfArrayInvalidOffsetIPv6() {
- IpAddress ipAddress;
- byte[] value;
-
- value = new byte[] {11, 22, 33, // Preamble
- 0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77,
- (byte) 0x88, (byte) 0x88,
- 44, 55}; // Extra bytes
- ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value, 6);
- }
-
- /**
- * Tests valueOf() converter for IPv4 InetAddress.
- */
- @Test
- public void testValueOfInetAddressIPv4() {
- IpAddress ipAddress;
- InetAddress inetAddress;
-
- inetAddress = InetAddresses.forString("1.2.3.4");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- inetAddress = InetAddresses.forString("0.0.0.0");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- inetAddress = InetAddresses.forString("255.255.255.255");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 InetAddress.
- */
- @Test
- public void testValueOfInetAddressIPv6() {
- IpAddress ipAddress;
- InetAddress inetAddress;
-
- inetAddress =
- InetAddresses.forString("1111:2222:3333:4444:5555:6666:7777:8888");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- inetAddress = InetAddresses.forString("::");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(), is("::"));
-
- inetAddress =
- InetAddresses.forString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- ipAddress = IpAddress.valueOf(inetAddress);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests valueOf() converter for IPv4 string.
- */
- @Test
- public void testValueOfStringIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.valueOf("1.2.3.4");
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = IpAddress.valueOf("255.255.255.255");
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 string.
- */
- @Test
- public void testValueOfStringIPv6() {
- IpAddress ipAddress;
-
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- ipAddress = IpAddress.valueOf("::");
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress =
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- IpAddress ipAddress;
-
- String fromString = null;
- ipAddress = IpAddress.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- IpAddress ipAddress;
-
- String fromString = "";
- ipAddress = IpAddress.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- IpAddress ipAddress;
-
- String fromString = "NoSuchIpAddress";
- ipAddress = IpAddress.valueOf(fromString);
- }
-
- /**
- * Tests making a mask prefix for a given prefix length for IPv4.
- */
- @Test
- public void testMakeMaskPrefixIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 25);
- assertThat(ipAddress.toString(), is("255.255.255.128"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 0);
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 32);
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests making a mask prefix for a given prefix length for IPv6.
- */
- @Test
- public void testMakeMaskPrefixIPv6() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 8);
- assertThat(ipAddress.toString(), is("ff00::"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 120);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 0);
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 128);
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 64);
- assertThat(ipAddress.toString(), is("ffff:ffff:ffff:ffff::"));
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv4:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskPrefixIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, -1);
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv6:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskPrefixIPv6() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, -1);
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv4:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskPrefixIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 33);
- }
-
- /**
- * Tests making a mask prefix for an invalid prefix length for IPv6:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskPrefixIPv6() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 129);
- }
-
- /**
- * Tests making of a masked address for IPv4.
- */
- @Test
- public void testMakeMaskedAddressIPv4() {
- IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 24);
- assertThat(ipAddressMasked.toString(), is("1.2.3.0"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
- assertThat(ipAddressMasked.toString(), is("0.0.0.0"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 32);
- assertThat(ipAddressMasked.toString(), is("1.2.3.5"));
- }
-
- /**
- * Tests making of a masked address for IPv6.
- */
- @Test
- public void testMakeMaskedAddressIPv6() {
- IpAddress ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 8);
- assertThat(ipAddressMasked.toString(), is("1100::"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 120);
- assertThat(ipAddressMasked.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
- assertThat(ipAddressMasked.toString(), is("::"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 128);
- assertThat(ipAddressMasked.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8885"));
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 64);
- assertThat(ipAddressMasked.toString(), is("1111:2222:3333:4444::"));
- }
-
- /**
- * Tests making of a masked address for invalid prefix length for IPv4:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskedAddressIPv4() {
- IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
- }
-
- /**
- * Tests making of a masked address for invalid prefix length for IPv6:
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeNegativeMaskedAddressIPv6() {
- IpAddress ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
- }
-
- /**
- * Tests making of a masked address for an invalid prefix length for IPv4:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskedAddressIPv4() {
- IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 33);
- }
-
- /**
- * Tests making of a masked address for an invalid prefix length for IPv6:
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidMakeTooLongMaskedAddressIPv6() {
- IpAddress ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
- IpAddress ipAddressMasked;
-
- ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 129);
- }
-
- /**
- * Tests if address is zero for IPv4.
- */
- @Test
- public void testIsZeroIPv4() {
- IpAddress normalIP = IpAddress.valueOf("10.0.0.1");
- IpAddress zeroIP = IpAddress.valueOf("0.0.0.0");
- assertFalse(normalIP.isZero());
- assertTrue(zeroIP.isZero());
- }
-
- /**
- * Tests if address is zero for IPv6.
- */
- @Test
- public void testIsZeroIPv6() {
- IpAddress normalIP = IpAddress.valueOf("fe80::1");
- IpAddress zeroIP = IpAddress.valueOf("::");
- assertFalse(normalIP.isZero());
- assertTrue(zeroIP.isZero());
- }
-
- /**
- * Tests if address is self-assigned for IPv4.
- */
- @Test
- public void testIsSelfAssignedIpv4() {
- IpAddress normalIP = IpAddress.valueOf("10.0.0.1");
- IpAddress selfAssignedIP = IpAddress.valueOf("169.1.2.3");
- assertFalse(normalIP.isSelfAssigned());
- assertTrue(selfAssignedIP.isSelfAssigned());
- }
-
- /**
- * Tests comparison of {@link IpAddress} for IPv4.
- */
- @Test
- public void testComparisonIPv4() {
- IpAddress addr1, addr2, addr3, addr4;
-
- addr1 = IpAddress.valueOf("1.2.3.4");
- addr2 = IpAddress.valueOf("1.2.3.4");
- addr3 = IpAddress.valueOf("1.2.3.3");
- addr4 = IpAddress.valueOf("1.2.3.5");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = IpAddress.valueOf("255.2.3.4");
- addr2 = IpAddress.valueOf("255.2.3.4");
- addr3 = IpAddress.valueOf("255.2.3.3");
- addr4 = IpAddress.valueOf("255.2.3.5");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
- }
-
- /**
- * Tests comparison of {@link IpAddress} for IPv6.
- */
- @Test
- public void testComparisonIPv6() {
- IpAddress addr1, addr2, addr3, addr4;
-
- addr1 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- addr2 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- addr3 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8887");
- addr4 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8889");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr3 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8887");
- addr4 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8889");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
-
- addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
- addr3 = IpAddress.valueOf("ffff:2222:3333:4443:5555:6666:7777:8888");
- addr4 = IpAddress.valueOf("ffff:2222:3333:4445:5555:6666:7777:8888");
- assertTrue(addr1.compareTo(addr2) == 0);
- assertTrue(addr1.compareTo(addr3) > 0);
- assertTrue(addr1.compareTo(addr4) < 0);
- }
-
- /**
- * Tests equality of {@link IpAddress} for IPv4.
- */
- @Test
- public void testEqualityIPv4() {
- new EqualsTester()
- .addEqualityGroup(IpAddress.valueOf("1.2.3.4"),
- IpAddress.valueOf("1.2.3.4"))
- .addEqualityGroup(IpAddress.valueOf("1.2.3.5"),
- IpAddress.valueOf("1.2.3.5"))
- .addEqualityGroup(IpAddress.valueOf("0.0.0.0"),
- IpAddress.valueOf("0.0.0.0"))
- .addEqualityGroup(IpAddress.valueOf("255.255.255.255"),
- IpAddress.valueOf("255.255.255.255"))
- .testEquals();
- }
-
- /**
- * Tests equality of {@link IpAddress} for IPv6.
- */
- @Test
- public void testEqualityIPv6() {
- new EqualsTester()
- .addEqualityGroup(
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"),
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"))
- .addEqualityGroup(
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"),
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"))
- .addEqualityGroup(
- IpAddress.valueOf("::"),
- IpAddress.valueOf("::"))
- .addEqualityGroup(
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv4.
- */
- @Test
- public void testToStringIPv4() {
- IpAddress ipAddress;
-
- ipAddress = IpAddress.valueOf("1.2.3.4");
- assertThat(ipAddress.toString(), is("1.2.3.4"));
-
- ipAddress = IpAddress.valueOf("0.0.0.0");
- assertThat(ipAddress.toString(), is("0.0.0.0"));
-
- ipAddress = IpAddress.valueOf("255.255.255.255");
- assertThat(ipAddress.toString(), is("255.255.255.255"));
- }
-
- /**
- * Tests object string representation for IPv6.
- */
- @Test
- public void testToStringIPv6() {
- IpAddress ipAddress;
-
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- assertThat(ipAddress.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888"));
-
- ipAddress = IpAddress.valueOf("1111::8888");
- assertThat(ipAddress.toString(), is("1111::8888"));
-
- ipAddress = IpAddress.valueOf("1111::");
- assertThat(ipAddress.toString(), is("1111::"));
-
- ipAddress = IpAddress.valueOf("::8888");
- assertThat(ipAddress.toString(), is("::8888"));
-
- ipAddress = IpAddress.valueOf("::");
- assertThat(ipAddress.toString(), is("::"));
-
- ipAddress =
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- assertThat(ipAddress.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
-
- ipAddress =
- IpAddress.valueOf("::1111:2222");
- assertThat(ipAddress.toString(),
- is("::1111:2222"));
-
- ipAddress =
- IpAddress.valueOf("1:0:0:1:0:0:2:3");
- assertThat(ipAddress.toString(),
- is("1::1:0:0:2:3"));
-
- ipAddress =
- IpAddress.valueOf("::0123:0004");
- assertThat(ipAddress.toString(),
- is("::123:4"));
-
- ipAddress =
- IpAddress.valueOf("0:0:1:1:0:0:1:1");
- assertThat(ipAddress.toString(),
- is("::1:1:0:0:1:1"));
-
- ipAddress =
- IpAddress.valueOf("1:1a2b::");
- assertThat(ipAddress.toString(),
- is("1:1a2b::"));
-
- ipAddress =
- IpAddress.valueOf("0:0:00:00:0000:00:00:000");
- assertThat(ipAddress.toString(),
- is("::"));
-
- ipAddress =
- IpAddress.valueOf("0:0:0:1:0:0:0:0");
- assertThat(ipAddress.toString(),
- is("0:0:0:1::"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java
deleted file mode 100644
index 052a4cbb..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import org.junit.Test;
-
-import com.google.common.testing.EqualsTester;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
-
-/**
- * Tests for class {@link IpPrefix}.
- */
-public class IpPrefixTest {
- /**
- * Tests the immutability of {@link IpPrefix}.
- */
- @Test
- public void testImmutable() {
- assertThatClassIsImmutableBaseClass(IpPrefix.class);
- }
-
- /**
- * Tests the maximum mask length.
- */
- @Test
- public void testMaxMaskLength() {
- assertThat(IpPrefix.MAX_INET_MASK_LENGTH, is(32));
- assertThat(IpPrefix.MAX_INET6_MASK_LENGTH, is(128));
- }
-
- /**
- * Tests returning the IP version of the prefix.
- */
- @Test
- public void testVersion() {
- IpPrefix ipPrefix;
-
- // IPv4
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.version(), is(IpAddress.Version.INET));
-
- // IPv6
- ipPrefix = IpPrefix.valueOf("::/0");
- assertThat(ipPrefix.version(), is(IpAddress.Version.INET6));
- }
-
- /**
- * Tests whether the IP version of a prefix is IPv4.
- */
- @Test
- public void testIsIp4() {
- IpPrefix ipPrefix;
-
- // IPv4
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertTrue(ipPrefix.isIp4());
-
- // IPv6
- ipPrefix = IpPrefix.valueOf("::/0");
- assertFalse(ipPrefix.isIp4());
- }
-
- /**
- * Tests whether the IP version of a prefix is IPv6.
- */
- @Test
- public void testIsIp6() {
- IpPrefix ipPrefix;
-
- // IPv4
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertFalse(ipPrefix.isIp6());
-
- // IPv6
- ipPrefix = IpPrefix.valueOf("::/0");
- assertTrue(ipPrefix.isIp6());
- }
-
- /**
- * Tests returning the IP address value and IP address prefix length of
- * an IPv4 prefix.
- */
- @Test
- public void testAddressAndPrefixLengthIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.3.0/24");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1.2.3.0")));
- assertThat(ipPrefix.prefixLength(), is(24));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1.2.3.0")));
- assertThat(ipPrefix.prefixLength(), is(24));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/32");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1.2.3.4")));
- assertThat(ipPrefix.prefixLength(), is(32));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.5/32");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1.2.3.5")));
- assertThat(ipPrefix.prefixLength(), is(32));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("0.0.0.0")));
- assertThat(ipPrefix.prefixLength(), is(0));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.address(),
- equalTo(IpAddress.valueOf("255.255.255.255")));
- assertThat(ipPrefix.prefixLength(), is(32));
- }
-
- /**
- * Tests returning the IP address value and IP address prefix length of
- * an IPv6 prefix.
- */
- @Test
- public void testAddressAndPrefixLengthIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1100::/8");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1100::")));
- assertThat(ipPrefix.prefixLength(), is(8));
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/8");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("1100::")));
- assertThat(ipPrefix.prefixLength(), is(8));
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8800/120");
- assertThat(ipPrefix.address(),
- equalTo(IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8800")));
- assertThat(ipPrefix.prefixLength(), is(120));
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/128");
- assertThat(ipPrefix.address(),
- equalTo(IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885")));
- assertThat(ipPrefix.prefixLength(), is(128));
-
- ipPrefix = IpPrefix.valueOf("::/0");
- assertThat(ipPrefix.address(), equalTo(IpAddress.valueOf("::")));
- assertThat(ipPrefix.prefixLength(), is(0));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.address(),
- equalTo(IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
- assertThat(ipPrefix.prefixLength(), is(128));
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/64");
- assertThat(ipPrefix.address(),
- equalTo(IpAddress.valueOf("1111:2222:3333:4444::")));
- assertThat(ipPrefix.prefixLength(), is(64));
- }
-
- /**
- * Tests getting the Ip4Prefix and Ip6Prefix view of the IP prefix.
- */
- @Test
- public void testGetIp4AndIp6PrefixView() {
- IpPrefix ipPrefix;
- Ip4Prefix ip4Prefix;
- Ip6Prefix ip6Prefix;
-
- // Pure IPv4 IpPrefix
- ipPrefix = IpPrefix.valueOf("1.2.3.0/24");
- ip4Prefix = ipPrefix.getIp4Prefix();
- ip6Prefix = ipPrefix.getIp6Prefix();
- assertThat(ip4Prefix.toString(), is("1.2.3.0/24"));
- assertNull(ip6Prefix);
-
- // IPv4 IpPrefix that is Ip4Prefix
- ipPrefix = Ip4Prefix.valueOf("1.2.3.0/24");
- ip4Prefix = ipPrefix.getIp4Prefix();
- ip6Prefix = ipPrefix.getIp6Prefix();
- assertThat(ip4Prefix.toString(), is("1.2.3.0/24"));
- assertNull(ip6Prefix);
-
- // Pure IPv6 IpPrefix
- ipPrefix = IpPrefix.valueOf("1111:2222::/64");
- ip4Prefix = ipPrefix.getIp4Prefix();
- ip6Prefix = ipPrefix.getIp6Prefix();
- assertNull(ip4Prefix);
- assertThat(ip6Prefix.toString(), is("1111:2222::/64"));
-
- // IPv6 IpPrefix that is Ip6Prefix
- ipPrefix = Ip6Prefix.valueOf("1111:2222::/64");
- ip4Prefix = ipPrefix.getIp4Prefix();
- ip6Prefix = ipPrefix.getIp6Prefix();
- assertNull(ip4Prefix);
- assertThat(ip6Prefix.toString(), is("1111:2222::/64"));
- }
-
- /**
- * Tests valueOf() converter for IPv4 integer value.
- */
- @Test
- public void testValueOfForIntegerIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf(0x01020304, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf(0x01020304, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipPrefix = IpPrefix.valueOf(0x01020305, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipPrefix = IpPrefix.valueOf(0, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(0, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipPrefix = IpPrefix.valueOf(0xffffffff, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(0xffffffff, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = IpPrefix.valueOf(0xffffffff, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 integer value and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIntegerNegativePrefixLengthIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf(0x01020304, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 integer value and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIntegerTooLongPrefixLengthIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf(0x01020304, 33);
- }
-
- /**
- * Tests valueOf() converter for IPv4 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv4() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- value = new byte[] {1, 2, 3, 5};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- value = new byte[] {0, 0, 0, 0};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 byte array.
- */
- @Test
- public void testValueOfByteArrayIPv6() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 120);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 128);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- value = new byte[] {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 128);
- assertThat(ipPrefix.toString(), is("::/128"));
-
- value = new byte[] {(byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 64);
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 128);
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv4.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv4() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = null;
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for a null array for IPv6.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullArrayIPv6() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = null;
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 120);
- }
-
- /**
- * Tests invalid valueOf() converter for a short array for IPv4.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv4() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for a short array for IPv6.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfShortArrayIPv6() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 120);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 byte array and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayNegativePrefixLengthIPv4() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 byte array and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayNegativePrefixLengthIPv6() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 byte array and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayTooLongPrefixLengthIPv4() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {1, 2, 3, 4};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, 33);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 byte array and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfByteArrayTooLongPrefixLengthIPv6() {
- IpPrefix ipPrefix;
- byte[] value;
-
- value = new byte[] {0x11, 0x11, 0x22, 0x22,
- 0x33, 0x33, 0x44, 0x44,
- 0x55, 0x55, 0x66, 0x66,
- 0x77, 0x77, (byte) 0x88, (byte) 0x88};
- ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, 129);
- }
-
- /**
- * Tests valueOf() converter for IPv4 address.
- */
- @Test
- public void testValueOfAddressIPv4() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress = IpAddress.valueOf("1.2.3.4");
- ipPrefix = IpPrefix.valueOf(ipAddress, 24);
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipAddress = IpAddress.valueOf("1.2.3.5");
- ipPrefix = IpPrefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipAddress = IpAddress.valueOf("0.0.0.0");
- ipPrefix = IpPrefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipAddress = IpAddress.valueOf("255.255.255.255");
- ipPrefix = IpPrefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 16);
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 32);
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 address.
- */
- @Test
- public void testValueOfAddressIPv6() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = IpPrefix.valueOf(ipAddress, 120);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- ipAddress = IpAddress.valueOf("::");
- ipPrefix = IpPrefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(), is("::/128"));
-
- ipAddress =
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
- ipPrefix = IpPrefix.valueOf(ipAddress, 0);
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 64);
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix = IpPrefix.valueOf(ipAddress, 128);
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null IP address.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullAddress() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress = null;
- ipPrefix = IpPrefix.valueOf(ipAddress, 24);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 address and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressNegativePrefixLengthIPv4() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress = IpAddress.valueOf("1.2.3.4");
- ipPrefix = IpPrefix.valueOf(ipAddress, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 address and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressNegativePrefixLengthIPv6() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = IpPrefix.valueOf(ipAddress, -1);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 address and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressTooLongPrefixLengthIPv4() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress = IpAddress.valueOf("1.2.3.4");
- ipPrefix = IpPrefix.valueOf(ipAddress, 33);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 address and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfAddressTooLongPrefixLengthIPv6() {
- IpAddress ipAddress;
- IpPrefix ipPrefix;
-
- ipAddress =
- IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
- ipPrefix = IpPrefix.valueOf(ipAddress, 129);
- }
-
- /**
- * Tests valueOf() converter for IPv4 string.
- */
- @Test
- public void testValueOfStringIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/32");
- assertThat(ipPrefix.toString(), is("1.2.3.4/32"));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.5/32");
- assertThat(ipPrefix.toString(), is("1.2.3.5/32"));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/32");
- assertThat(ipPrefix.toString(), is("0.0.0.0/32"));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/16");
- assertThat(ipPrefix.toString(), is("255.255.0.0/16"));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests valueOf() converter for IPv6 string.
- */
- @Test
- public void testValueOfStringIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/120");
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/128");
- assertThat(ipPrefix.toString(),
- is("1111:2222:3333:4444:5555:6666:7777:8888/128"));
-
- ipPrefix = IpPrefix.valueOf("::/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf("::/128");
- assertThat(ipPrefix.toString(), is("::/128"));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64");
- assertThat(ipPrefix.toString(), is("ffff:ffff:ffff:ffff::/64"));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-
- /**
- * Tests invalid valueOf() converter for a null string.
- */
- @Test(expected = NullPointerException.class)
- public void testInvalidValueOfNullString() {
- IpPrefix ipPrefix;
- String fromString;
-
- fromString = null;
- ipPrefix = IpPrefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an empty string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfEmptyString() {
- IpPrefix ipPrefix;
- String fromString;
-
- fromString = "";
- ipPrefix = IpPrefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for an incorrect string.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfIncorrectString() {
- IpPrefix ipPrefix;
- String fromString;
-
- fromString = "NoSuchIpPrefix";
- ipPrefix = IpPrefix.valueOf(fromString);
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 string and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringNegativePrefixLengthIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/-1");
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 string and
- * negative prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringNegativePrefixLengthIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/-1");
- }
-
- /**
- * Tests invalid valueOf() converter for IPv4 string and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringTooLongPrefixLengthIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/33");
- }
-
- /**
- * Tests invalid valueOf() converter for IPv6 string and
- * too long prefix length.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidValueOfStringTooLongPrefixLengthIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix =
- IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8888/129");
- }
-
- /**
- * Tests IP prefix contains another IP prefix for IPv4.
- */
- @Test
- public void testContainsIpPrefixIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.0.0/24");
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/32")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/0")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = IpPrefix.valueOf("1.2.0.0/32");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/32")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/0")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/24")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/32")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.4/32")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/16")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("1.3.0.0/24")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/16")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/0")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("255.255.255.255/32")));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/24")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/32")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.4/32")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.3.0.0/24")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/16")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("0.0.0.0/0")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("255.255.255.255/32")));
-
- // Test when there is a mistmatch in the compared IP address families
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1111:2222:3333:4444::/120")));
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
- }
-
- /**
- * Tests IP prefix contains another IP prefix for IPv6.
- */
- @Test
- public void testContainsIpPrefixIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1111:2222:3333:4444::/120");
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/128")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/0")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix = IpPrefix.valueOf("1111:2222:3333:4444::/128");
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/128")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/0")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix = IpPrefix.valueOf("::/0");
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/120")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/128")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::1/128")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/64")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4445::/120")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("::/64")));
- assertTrue(ipPrefix.contains(IpPrefix.valueOf("::/0")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/120")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/128")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::1/128")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4444::/64")));
- assertFalse(ipPrefix.contains(
- IpPrefix.valueOf("1111:2222:3333:4445::/120")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/64")));
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("::/0")));
- assertTrue(ipPrefix.contains(
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")));
-
- // Test when there is a mistmatch in the compared IP address families
- ipPrefix = IpPrefix.valueOf("::/0");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("1.2.0.0/24")));
- ipPrefix = IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(IpPrefix.valueOf("255.255.255.255/32")));
- }
-
- /**
- * Tests IP prefix contains IP address for IPv4.
- */
- @Test
- public void testContainsIpAddressIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.0.0/24");
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.2.0.0")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("0.0.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("255.255.255.255")));
-
- ipPrefix = IpPrefix.valueOf("1.2.0.0/32");
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.2.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("0.0.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("255.255.255.255")));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.2.0.0")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.2.0.4")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("1.3.0.0")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("0.0.0.0")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("255.255.255.255")));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.2.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.2.0.4")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.3.0.0")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("0.0.0.0")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("255.255.255.255")));
-
- // Test when there is a mistmatch in the compared IP address families
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1111:2222:3333:4444::")));
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertFalse(ipPrefix.contains(IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
- }
-
- /**
- * Tests IP prefix contains IP address for IPv6.
- */
- @Test
- public void testContainsIpAddressIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1111:2222:3333:4444::/120");
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::")));
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("::")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix = IpPrefix.valueOf("1111:2222:3333:4444::/128");
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("::")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix = IpPrefix.valueOf("::/0");
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::")));
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::1")));
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4445::")));
- assertTrue(ipPrefix.contains(IpAddress.valueOf("::")));
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- ipPrefix =
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4444::1")));
- assertFalse(ipPrefix.contains(
- IpAddress.valueOf("1111:2222:3333:4445::")));
- assertFalse(ipPrefix.contains(IpAddress.valueOf("::")));
- assertTrue(ipPrefix.contains(
- IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
- // Test when there is a mistmatch in the compared IP address families
- ipPrefix = IpPrefix.valueOf("::/0");
- assertFalse(ipPrefix.contains(IpAddress.valueOf("1.2.0.0")));
- ipPrefix = IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertFalse(ipPrefix.contains(IpAddress.valueOf("255.255.255.255")));
- }
-
- /**
- * Tests equality of {@link IpPrefix} for IPv4.
- */
- @Test
- public void testEqualityIPv4() {
- new EqualsTester()
- .addEqualityGroup(IpPrefix.valueOf("1.2.0.0/24"),
- IpPrefix.valueOf("1.2.0.0/24"),
- IpPrefix.valueOf("1.2.0.4/24"))
- .addEqualityGroup(IpPrefix.valueOf("1.2.0.0/16"),
- IpPrefix.valueOf("1.2.0.0/16"))
- .addEqualityGroup(IpPrefix.valueOf("1.2.0.0/32"),
- IpPrefix.valueOf("1.2.0.0/32"))
- .addEqualityGroup(IpPrefix.valueOf("1.3.0.0/24"),
- IpPrefix.valueOf("1.3.0.0/24"))
- .addEqualityGroup(IpPrefix.valueOf("0.0.0.0/0"),
- IpPrefix.valueOf("0.0.0.0/0"))
- .addEqualityGroup(IpPrefix.valueOf("255.255.255.255/32"),
- IpPrefix.valueOf("255.255.255.255/32"))
- .testEquals();
- }
-
- /**
- * Tests equality of {@link IpPrefix} for IPv6.
- */
- @Test
- public void testEqualityIPv6() {
- new EqualsTester()
- .addEqualityGroup(
- IpPrefix.valueOf("1111:2222:3333:4444::/120"),
- IpPrefix.valueOf("1111:2222:3333:4444::1/120"),
- IpPrefix.valueOf("1111:2222:3333:4444::/120"))
- .addEqualityGroup(
- IpPrefix.valueOf("1111:2222:3333:4444::/64"),
- IpPrefix.valueOf("1111:2222:3333:4444::/64"))
- .addEqualityGroup(
- IpPrefix.valueOf("1111:2222:3333:4444::/128"),
- IpPrefix.valueOf("1111:2222:3333:4444::/128"))
- .addEqualityGroup(
- IpPrefix.valueOf("1111:2222:3333:4445::/64"),
- IpPrefix.valueOf("1111:2222:3333:4445::/64"))
- .addEqualityGroup(
- IpPrefix.valueOf("::/0"),
- IpPrefix.valueOf("::/0"))
- .addEqualityGroup(
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"),
- IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"))
- .testEquals();
- }
-
- /**
- * Tests object string representation for IPv4.
- */
- @Test
- public void testToStringIPv4() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1.2.3.0/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf("1.2.3.4/24");
- assertThat(ipPrefix.toString(), is("1.2.3.0/24"));
-
- ipPrefix = IpPrefix.valueOf("0.0.0.0/0");
- assertThat(ipPrefix.toString(), is("0.0.0.0/0"));
-
- ipPrefix = IpPrefix.valueOf("255.255.255.255/32");
- assertThat(ipPrefix.toString(), is("255.255.255.255/32"));
- }
-
- /**
- * Tests object string representation for IPv6.
- */
- @Test
- public void testToStringIPv6() {
- IpPrefix ipPrefix;
-
- ipPrefix = IpPrefix.valueOf("1100::/8");
- assertThat(ipPrefix.toString(), is("1100::/8"));
-
- ipPrefix = IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/8");
- assertThat(ipPrefix.toString(), is("1100::/8"));
-
- ipPrefix = IpPrefix.valueOf("::/0");
- assertThat(ipPrefix.toString(), is("::/0"));
-
- ipPrefix = IpPrefix.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
- assertThat(ipPrefix.toString(),
- is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLCTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLCTest.java
deleted file mode 100644
index 39bb72f4..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLCTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit tests for LLC class.
- */
-public class LLCTest {
-
- private Deserializer<LLC> deserializer;
-
- private byte dsap = 10;
- private byte ssap = 20;
- private byte ctrl = 30;
-
- private byte[] bytes;
-
- @Before
- public void setUp() throws Exception {
- deserializer = LLC.deserializer();
-
- ByteBuffer bb = ByteBuffer.allocate(LLC.LLC_HEADER_LENGTH);
-
- bb.put(dsap);
- bb.put(ssap);
- bb.put(ctrl);
-
- bytes = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, bytes);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- LLC llc = deserializer.deserialize(bytes, 0, bytes.length);
-
- assertEquals(dsap, llc.getDsap());
- assertEquals(ssap, llc.getSsap());
- assertEquals(ctrl, llc.getCtrl());
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLDPTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLDPTest.java
deleted file mode 100644
index 95b0b04a..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/LLDPTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for the LLDP class.
- */
-public class LLDPTest {
-
- private Deserializer<LLDP> deserializer;
-
- private byte[] chassisValue = new byte[] {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
- private byte[] portValue = new byte[] {0x1, 0x2, 0x3, 0x4, 0x5};
- private byte[] ttlValue = new byte[] {0x0, 0x20};
-
- private short optionalTlvSize = 6;
- private byte[] optionalTlvValue = new byte[] {0x6, 0x5, 0x4, 0x3, 0x2, 0x1};
-
- private byte[] bytes;
-
- @Before
- public void setUp() throws Exception {
- deserializer = LLDP.deserializer();
-
- // Each TLV is 2 bytes for the type+length, plus the size of the value
- // There are 2 zero-bytes at the end
- ByteBuffer bb = ByteBuffer.allocate(2 + LLDP.CHASSIS_TLV_SIZE +
- 2 + LLDP.PORT_TLV_SIZE +
- 2 + LLDP.TTL_TLV_SIZE +
- 2 + optionalTlvSize +
- 2);
-
- // Chassis TLV
- bb.putShort(getTypeLength(LLDP.CHASSIS_TLV_TYPE, LLDP.CHASSIS_TLV_SIZE));
- bb.put(chassisValue);
-
- // Port TLV
- bb.putShort(getTypeLength(LLDP.PORT_TLV_TYPE, LLDP.PORT_TLV_SIZE));
- bb.put(portValue);
-
- // TTL TLV
- bb.putShort(getTypeLength(LLDP.TTL_TLV_TYPE, LLDP.TTL_TLV_SIZE));
- bb.put(ttlValue);
-
- // Optional TLV
- bb.putShort(getTypeLength(LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE, optionalTlvSize));
- bb.put(optionalTlvValue);
-
- bb.putShort((short) 0);
-
- bytes = bb.array();
-
- }
-
- private short getTypeLength(byte type, short length) {
- return (short) ((0x7f & type) << 9 | 0x1ff & length);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, bytes);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- LLDP lldp = deserializer.deserialize(bytes, 0, bytes.length);
-
- assertEquals(LLDP.CHASSIS_TLV_TYPE, lldp.getChassisId().getType());
- assertEquals(LLDP.CHASSIS_TLV_SIZE, lldp.getChassisId().getLength());
- assertTrue(Arrays.equals(chassisValue, lldp.getChassisId().getValue()));
-
- assertEquals(LLDP.PORT_TLV_TYPE, lldp.getPortId().getType());
- assertEquals(LLDP.PORT_TLV_SIZE, lldp.getPortId().getLength());
- assertTrue(Arrays.equals(portValue, lldp.getPortId().getValue()));
-
- assertEquals(LLDP.TTL_TLV_TYPE, lldp.getTtl().getType());
- assertEquals(LLDP.TTL_TLV_SIZE, lldp.getTtl().getLength());
- assertTrue(Arrays.equals(ttlValue, lldp.getTtl().getValue()));
-
- assertEquals(1, lldp.getOptionalTLVList().size());
- LLDPTLV optionalTlv = lldp.getOptionalTLVList().get(0);
-
- assertEquals(LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE, optionalTlv.getType());
- assertEquals(optionalTlvSize, optionalTlv.getLength());
- assertTrue(Arrays.equals(optionalTlvValue, optionalTlv.getValue()));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/MplsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/MplsTest.java
deleted file mode 100644
index 2ab8ff98..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/MplsTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit tests for MPLS class.
- */
-public class MplsTest {
-
- private Deserializer<MPLS> deserializer;
-
- private int label = 1048575;
- private byte bos = 1;
- private byte ttl = 20;
- private byte protocol = MPLS.PROTOCOL_IPV4;
-
- private byte[] bytes;
-
- @Before
- public void setUp() throws Exception {
- // Replace normal deserializer map with an empty map. This will cause
- // the DataDeserializer to be used which will silently handle 0-byte input.
- MPLS.protocolDeserializerMap = new HashMap<>();
-
- deserializer = MPLS.deserializer();
-
- ByteBuffer bb = ByteBuffer.allocate(MPLS.HEADER_LENGTH);
- bb.putInt(((label & 0x000fffff) << 12) | ((bos & 0x1) << 8 | (ttl & 0xff)));
-
- bytes = bb.array();
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, bytes);
- }
-
- @Test
- public void testDeserialize() throws Exception {
- MPLS mpls = deserializer.deserialize(bytes, 0, bytes.length);
-
- assertEquals(label, mpls.label);
- assertEquals(bos, mpls.bos);
- assertEquals(ttl, mpls.ttl);
- assertEquals(protocol, mpls.protocol);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java
deleted file mode 100644
index 7fba3cd7..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PIMTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.pim.PIMAddrUnicast;
-import org.onlab.packet.pim.PIMHello;
-import org.onlab.packet.pim.PIMJoinPrune;
-
-import static junit.framework.Assert.assertTrue;
-
-public final class PIMTest {
-
- public static final String SADDR = "10.2.1.2";
- public static final String PIMADDR = "224.0.0.13";
- public static final String PIMUADDR = "10.23.3.5";
-
- public static final String SADDR1 = "10.1.1.1/32";
- public static final String SADDR2 = "10.1.2.1/32";
- public static final String GADDR1 = "232.1.1.1/32";
- public static final String GADDR2 = "232.1.2.1/32";
-
- public static final String CPSTR1 = "of:deadbeefball/8";
- public static final String CPSTR2 = "of:deadbeefcafe/3";
- public static final String CPSTR3 = "of:2badcafef00d/3";
-
- private Deserializer<PIM> deserializer;
-
- private PIM pimHello;
- private PIMHello hello;
-
- private PIM pimJoinPrune;
- private PIMJoinPrune joinPrune;
-
- /**
- * Create PIM Hello and Join/Prune packets to be used in testing.
- *
- * @throws Exception if packet creation fails
- */
- @Before
- public void setUp() throws Exception {
-
- // Create a PIM Hello
- pimHello = new PIM();
- pimHello.setVersion((byte) 2);
- pimHello.setPIMType((byte) PIM.TYPE_HELLO);
- pimHello.setChecksum((short) 0);
-
- hello = new PIMHello();
- hello.createDefaultOptions();
- pimHello.setPayload(hello);
- hello.setParent(pimHello);
-
- // Create PIM Join Prune
- pimJoinPrune = new PIM();
- pimJoinPrune.setVersion((byte) 2);
- pimJoinPrune.setPIMType((byte) PIM.TYPE_JOIN_PRUNE_REQUEST);
- pimJoinPrune.setChecksum((short) 0);
-
- joinPrune = new PIMJoinPrune();
- joinPrune.setUpstreamAddr(new PIMAddrUnicast(SADDR));
- joinPrune.addJoin(GADDR1, SADDR1);
- joinPrune.addJoin(GADDR2, SADDR2);
- joinPrune.addPrune(GADDR1, SADDR2);
- joinPrune.addPrune(GADDR2, SADDR1);
-
- pimJoinPrune.setPayload(joinPrune);
- joinPrune.setParent(pimJoinPrune);
-
- deserializer = PIM.deserializer();
- }
-
- /**
- * Make sure our deserializer throws an exception if we recieve bad input.
- *
- * @throws Exception if we are given bad input.
- */
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- /**
- * Verify we throw an exception if we receive a truncated Join/Prune message.
- *
- * @throws Exception if we receive a truncated Join/Prune message.
- */
- @Test
- public void testDeserializeTruncated() throws Exception {
- byte [] bits = pimJoinPrune.serialize();
- PacketTestUtils.testDeserializeTruncated(deserializer, bits);
- }
-
- /**
- * Verify that we correctly deserialize hello messages.
- *
- * @throws Exception if our input is bad or truncated.
- */
- @Test
- public void testDeserializeHello() throws Exception {
- byte [] data = pimHello.serialize();
- PIM pim = deserializer.deserialize(data, 0, data.length);
- assertTrue(pim.equals(pimHello));
- }
-
- /**
- * Verify that we correctly deserialize Join/Prune messages.
- *
- * @throws Exception if our input is bad or truncated.
- */
- @Test
- public void testDeserializeJoinPrune() throws Exception {
- byte [] data = pimJoinPrune.serialize();
- PIM pim = deserializer.deserialize(data, 0, data.length);
- assertTrue(pim.equals(pimJoinPrune));
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PacketTestUtils.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PacketTestUtils.java
deleted file mode 100644
index 209b1d27..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/PacketTestUtils.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet;
-
-import java.nio.ByteBuffer;
-
-import static junit.framework.TestCase.fail;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Utilities for testing packet methods.
- */
-public final class PacketTestUtils {
-
- private PacketTestUtils() {
- }
-
- /**
- * Tests that the Deserializer function is resilient to bad input parameters
- * such as null input, negative offset and length, etc.
- *
- * @param deserializer deserializer function to test
- */
- public static void testDeserializeBadInput(Deserializer deserializer) {
- byte[] bytes = ByteBuffer.allocate(4).array();
-
- try {
- deserializer.deserialize(null, 0, 4);
- fail("NullPointerException was not thrown");
- } catch (NullPointerException e) {
- assertTrue(true);
- } catch (DeserializationException e) {
- fail("NullPointerException was not thrown");
- }
-
- // input byte array length, offset and length don't make sense
- expectDeserializationException(deserializer, bytes, -1, 0);
- expectDeserializationException(deserializer, bytes, 0, -1);
- expectDeserializationException(deserializer, bytes, 0, 5);
- expectDeserializationException(deserializer, bytes, 2, 3);
- expectDeserializationException(deserializer, bytes, 5, 0);
- }
-
- /**
- * Tests that the Deserializer function is resilient to truncated input, or
- * cases where the input byte array does not contain enough bytes to
- * deserialize the packet.
- *
- * @param deserializer deserializer function to test
- * @param header byte array of a full-size packet
- */
- public static void testDeserializeTruncated(Deserializer deserializer,
- byte[] header) {
- byte[] truncated;
-
- for (int i = 0; i < header.length; i++) {
- truncated = new byte[i];
-
- ByteBuffer.wrap(header).get(truncated);
-
- expectDeserializationException(deserializer, truncated, 0, truncated.length);
- }
- }
-
- /**
- * Run the given deserializer function against the given inputs and verify
- * that a DeserializationException is thrown. The the test will fail if a
- * DeserializationException is not thrown by the deserializer function.
- *
- * @param deserializer deserializer function to test
- * @param bytes input byte array
- * @param offset input offset
- * @param length input length
- */
- public static void expectDeserializationException(Deserializer deserializer,
- byte[] bytes, int offset, int length) {
- try {
- deserializer.deserialize(bytes, offset, length);
- fail("DeserializationException was not thrown");
- } catch (DeserializationException e) {
- assertTrue(true);
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/TCPTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/TCPTest.java
deleted file mode 100644
index faab5c2c..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/TCPTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link TCP}.
- */
-public class TCPTest {
- private static final byte[] IPV4_SOURCE_ADDRESS = {
- (byte) 192, (byte) 168, (byte) 1, (byte) 1
- };
- private static final byte[] IPV4_DESTINATION_ADDRESS = {
- (byte) 192, (byte) 168, (byte) 1, (byte) 2
- };
- private static final byte[] IPV6_SOURCE_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01
- };
- private static final byte[] IPV6_DESTINATION_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02
- };
-
- private static IPv4 ipv4 = new IPv4();
- private static IPv6 ipv6 = new IPv6();
- private static byte[] bytePacketTCP4 = {
- (byte) 0x00, (byte) 0x50, (byte) 0x00, (byte) 0x60, // src,dst port
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, // seq
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, // ack
- (byte) 0x50, (byte) 0x02, // offset,flag
- (byte) 0x10, (byte) 0x00, // window
- (byte) 0x1b, (byte) 0xae, // checksum
- (byte) 0x00, (byte) 0x01 // urgent
- };
- private static byte[] bytePacketTCP6 = {
- (byte) 0x00, (byte) 0x50, (byte) 0x00, (byte) 0x60, // src,dst port
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, // seq
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, // ack
- (byte) 0x50, (byte) 0x02, // offset,flag
- (byte) 0x10, (byte) 0x00, // window
- (byte) 0xa1, (byte) 0xfd, // checksum
- (byte) 0x00, (byte) 0x01 // urgent
- };
-
- private static Deserializer<TCP> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- deserializer = TCP.deserializer();
-
- ipv4.setSourceAddress(IPv4.toIPv4Address(IPV4_SOURCE_ADDRESS));
- ipv4.setDestinationAddress(IPv4.toIPv4Address(IPV4_DESTINATION_ADDRESS));
- ipv4.setProtocol(IPv4.PROTOCOL_TCP);
-
- ipv6.setSourceAddress(IPV6_SOURCE_ADDRESS);
- ipv6.setDestinationAddress(IPV6_DESTINATION_ADDRESS);
- ipv6.setNextHeader(IPv6.PROTOCOL_TCP);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- TCP tcp = new TCP();
- tcp.setSourcePort(0x50);
- tcp.setDestinationPort(0x60);
- tcp.setSequence(0x10);
- tcp.setAcknowledge(0x20);
- tcp.setDataOffset((byte) 0x5);
- tcp.setFlags((short) 0x2);
- tcp.setWindowSize((short) 0x1000);
- tcp.setUrgentPointer((short) 0x1);
-
- tcp.setParent(ipv4);
- assertArrayEquals(bytePacketTCP4, tcp.serialize());
- tcp.resetChecksum();
- tcp.setParent(ipv6);
- assertArrayEquals(bytePacketTCP6, tcp.serialize());
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, bytePacketTCP4);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- TCP tcp = deserializer.deserialize(bytePacketTCP4, 0, bytePacketTCP4.length);
-
- assertThat(tcp.getSourcePort(), is(0x50));
- assertThat(tcp.getDestinationPort(), is(0x60));
- assertThat(tcp.getSequence(), is(0x10));
- assertThat(tcp.getAcknowledge(), is(0x20));
- assertThat(tcp.getDataOffset(), is((byte) 0x5));
- assertThat(tcp.getFlags(), is((short) 0x2));
- assertThat(tcp.getWindowSize(), is((short) 0x1000));
- assertThat(tcp.getUrgentPointer(), is((short) 0x1));
- assertThat(tcp.getChecksum(), is((short) 0x1bae));
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- TCP tcp1 = new TCP();
- tcp1.setSourcePort(0x50);
- tcp1.setDestinationPort(0x60);
- tcp1.setSequence(0x10);
- tcp1.setAcknowledge(0x20);
- tcp1.setDataOffset((byte) 0x5);
- tcp1.setFlags((short) 0x2);
- tcp1.setWindowSize((short) 0x1000);
- tcp1.setUrgentPointer((short) 0x1);
-
- TCP tcp2 = new TCP();
- tcp2.setSourcePort(0x70);
- tcp2.setDestinationPort(0x60);
- tcp2.setSequence(0x10);
- tcp2.setAcknowledge(0x20);
- tcp2.setDataOffset((byte) 0x5);
- tcp2.setFlags((short) 0x2);
- tcp2.setWindowSize((short) 0x1000);
- tcp2.setUrgentPointer((short) 0x1);
-
- assertTrue(tcp1.equals(tcp1));
- assertFalse(tcp1.equals(tcp2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/UDPTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/UDPTest.java
deleted file mode 100644
index ba453f61..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/UDPTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-package org.onlab.packet;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link UDP}.
- */
-public class UDPTest {
- private static final byte[] IPV4_SOURCE_ADDRESS = {
- (byte) 192, (byte) 168, (byte) 1, (byte) 1
- };
- private static final byte[] IPV4_DESTINATION_ADDRESS = {
- (byte) 192, (byte) 168, (byte) 1, (byte) 2
- };
- private static final byte[] IPV6_SOURCE_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01
- };
- private static final byte[] IPV6_DESTINATION_ADDRESS = {
- (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02
- };
-
- private static IPv4 ipv4 = new IPv4();
- private static IPv6 ipv6 = new IPv6();
- private static byte[] bytePacketUDP4 = {
- (byte) 0x00, (byte) 0x50, // src port
- (byte) 0x00, (byte) 0x60, // dst port
- (byte) 0x00, (byte) 0x08, // length
- (byte) 0x7b, (byte) 0xda, // checksum
- };
- private static byte[] bytePacketUDP6 = {
- (byte) 0x00, (byte) 0x50, // src port
- (byte) 0x00, (byte) 0x60, // dst port
- (byte) 0x00, (byte) 0x08, // length
- (byte) 0x02, (byte) 0x2a, // checksum
- };
-
- private static Deserializer<UDP> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- deserializer = UDP.deserializer();
-
- ipv4.setSourceAddress(IPv4.toIPv4Address(IPV4_SOURCE_ADDRESS));
- ipv4.setDestinationAddress(IPv4.toIPv4Address(IPV4_DESTINATION_ADDRESS));
- ipv4.setProtocol(IPv4.PROTOCOL_UDP);
-
- ipv6.setSourceAddress(IPV6_SOURCE_ADDRESS);
- ipv6.setDestinationAddress(IPV6_DESTINATION_ADDRESS);
- ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- UDP udp = new UDP();
- udp.setSourcePort(0x50);
- udp.setDestinationPort(0x60);
-
- udp.setParent(ipv4);
- assertArrayEquals(bytePacketUDP4, udp.serialize());
- udp.resetChecksum();
- udp.setParent(ipv6);
- assertArrayEquals(bytePacketUDP6, udp.serialize());
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(deserializer);
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- PacketTestUtils.testDeserializeTruncated(deserializer, bytePacketUDP4);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- UDP udp = deserializer.deserialize(bytePacketUDP4, 0, bytePacketUDP4.length);
-
- assertThat(udp.getSourcePort(), is(0x50));
- assertThat(udp.getDestinationPort(), is(0x60));
- assertThat(udp.getLength(), is((short) 8));
- assertThat(udp.getChecksum(), is((short) 0x7bda));
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- UDP udp1 = new UDP();
- udp1.setSourcePort(0x50);
- udp1.setDestinationPort(0x60);
-
- UDP udp2 = new UDP();
- udp2.setSourcePort(0x70);
- udp2.setDestinationPort(0x60);
-
- assertTrue(udp1.equals(udp1));
- assertFalse(udp1.equals(udp2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/VlanIdTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/VlanIdTest.java
deleted file mode 100644
index 9ec8ddda..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/VlanIdTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import com.google.common.testing.EqualsTester;
-
-public class VlanIdTest {
-
- @Test
- public void testEquality() {
-
- VlanId vlan1 = VlanId.vlanId((short) -1);
- VlanId vlan2 = VlanId.vlanId((short) 100);
- VlanId vlan3 = VlanId.vlanId((short) 100);
-
- new EqualsTester().addEqualityGroup(VlanId.vlanId(), vlan1)
- .addEqualityGroup(vlan2, vlan3)
- .addEqualityGroup(VlanId.vlanId((short) 10));
-
- }
-
- @Test
- public void basics() {
- // purposefully create UNTAGGED VLAN
- VlanId vlan1 = VlanId.vlanId((short) 10);
- VlanId vlan2 = VlanId.vlanId((short) -1);
-
- assertEquals("incorrect VLAN value", 10, vlan1.toShort());
- assertEquals("invalid untagged value", VlanId.UNTAGGED, vlan2.toShort());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testIllicitVLAN() {
- VlanId.vlanId((short) 5000);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/AuthenticationTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/AuthenticationTest.java
deleted file mode 100644
index 39ab9104..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/AuthenticationTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Data;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.UDP;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link Authentication}.
- */
-public class AuthenticationTest {
- private static Data data;
- private static UDP udp;
- private static byte[] icv = {
- (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44
- };
- private static byte[] bytePacket;
-
- private Deserializer<Authentication> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- data = new Data();
- data.setData("testSerialize".getBytes());
- udp = new UDP();
- udp.setPayload(data);
-
- byte[] bytePayload = udp.serialize();
- byte[] byteHeader = {
- (byte) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x00,
- (byte) 0x13, (byte) 0x57, (byte) 0x24, (byte) 0x68,
- (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00,
- (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = Authentication.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- Authentication auth = new Authentication();
- auth.setNextHeader((byte) 0x11);
- auth.setPayloadLength((byte) 0x02);
- auth.setSecurityParamIndex(0x13572468);
- auth.setSequence(0xffff00);
- auth.setIngegrityCheck(icv);
- auth.setPayload(udp);
-
- assertArrayEquals(auth.serialize(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- Authentication auth = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(auth.getNextHeader(), is((byte) 0x11));
- assertThat(auth.getPayloadLength(), is((byte) 0x02));
- assertThat(auth.getSecurityParamIndex(), is(0x13572468));
- assertThat(auth.getSequence(), is(0xffff00));
- assertArrayEquals(auth.getIntegrityCheck(), icv);
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- Authentication auth1 = new Authentication();
- auth1.setNextHeader((byte) 0x11);
- auth1.setPayloadLength((byte) 0x02);
- auth1.setSecurityParamIndex(0x13572468);
- auth1.setSequence(0xffff00);
- auth1.setIngegrityCheck(icv);
-
- Authentication auth2 = new Authentication();
- auth2.setNextHeader((byte) 0x11);
- auth2.setPayloadLength((byte) 0x02);
- auth2.setSecurityParamIndex(0x13572467);
- auth2.setSequence(0xffff00);
- auth2.setIngegrityCheck(icv);
-
- assertTrue(auth1.equals(auth1));
- assertFalse(auth1.equals(auth2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/BaseOptionsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/BaseOptionsTest.java
deleted file mode 100644
index bb91e9e7..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/BaseOptionsTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Data;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPv6;
-import org.onlab.packet.UDP;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link BaseOptions}.
- */
-public class BaseOptionsTest {
- private static Data data;
- private static UDP udp;
- private static byte[] options = {
- (byte) 0x00, (byte) 0x03,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00
- };
- private static byte[] bytePacket;
-
- private Deserializer<BaseOptions> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- data = new Data();
- data.setData("testSerialize".getBytes());
- udp = new UDP();
- udp.setPayload(data);
-
- byte[] bytePayload = udp.serialize();
- byte[] byteHeader = {
- (byte) 0x11, (byte) 0x00, (byte) 0x00, (byte) 0x03,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = BaseOptions.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- BaseOptions baseopt = new BaseOptions();
- baseopt.setNextHeader((byte) 0x11);
- baseopt.setHeaderExtLength((byte) 0x00);
- baseopt.setOptions(options);
- baseopt.setPayload(udp);
-
- assertArrayEquals(baseopt.serialize(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- BaseOptions baseopt = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(baseopt.getNextHeader(), is((byte) 0x11));
- assertThat(baseopt.getHeaderExtLength(), is((byte) 0x00));
- assertArrayEquals(baseopt.getOptions(), options);
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- BaseOptions baseopt1 = new BaseOptions();
- baseopt1.setNextHeader((byte) 0x11);
- baseopt1.setHeaderExtLength((byte) 0x00);
- baseopt1.setOptions(options);
- baseopt1.setType(IPv6.PROTOCOL_HOPOPT);
-
- BaseOptions baseopt2 = new BaseOptions();
- baseopt2.setNextHeader((byte) 0x11);
- baseopt2.setHeaderExtLength((byte) 0x00);
- baseopt2.setOptions(options);
- baseopt1.setType(IPv6.PROTOCOL_DSTOPT);
-
- assertTrue(baseopt1.equals(baseopt1));
- assertFalse(baseopt1.equals(baseopt2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/DestinationOptionsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/DestinationOptionsTest.java
deleted file mode 100644
index 29dd1266..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/DestinationOptionsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Test;
-import org.onlab.packet.IPv6;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-/**
- * Tests for class {@link DestinationOptions}.
- */
-public class DestinationOptionsTest {
- /**
- * Tests constructor.
- */
- @Test
- public void testConstructor() {
- DestinationOptions dstopt = new DestinationOptions();
- assertThat(dstopt.getType(), is(IPv6.PROTOCOL_DSTOPT));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/EncapSecurityPayloadTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/EncapSecurityPayloadTest.java
deleted file mode 100644
index e0e99191..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/EncapSecurityPayloadTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-
-import java.util.Arrays;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link EncapSecurityPayload}.
- */
-public class EncapSecurityPayloadTest {
- private static Data data;
- private static byte[] dataByte = new byte[32];
- private static byte[] bytePacket;
-
- private Deserializer<EncapSecurityPayload> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- Arrays.fill(dataByte, (byte) 0xff);
- data = new Data().setData(dataByte);
-
- byte[] bytePayload = data.serialize();
- byte[] byteHeader = {
- (byte) 0x13, (byte) 0x57, (byte) 0x24, (byte) 0x68,
- (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = EncapSecurityPayload.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- EncapSecurityPayload esp = new EncapSecurityPayload();
- esp.setSecurityParamIndex(0x13572468);
- esp.setSequence(0xffff00);
- esp.setPayload(data);
-
- assertArrayEquals(esp.serialize(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- EncapSecurityPayload esp = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(esp.getSecurityParamIndex(), is(0x13572468));
- assertThat(esp.getSequence(), is(0xffff00));
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- EncapSecurityPayload esp1 = new EncapSecurityPayload();
- esp1.setSecurityParamIndex(0x13572468);
- esp1.setSequence(0xffff00);
-
- EncapSecurityPayload esp2 = new EncapSecurityPayload();
- esp2.setSecurityParamIndex(0x13572468);
- esp2.setSequence(0xfffff0);
-
- assertTrue(esp1.equals(esp1));
- assertFalse(esp1.equals(esp2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/FragmentTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/FragmentTest.java
deleted file mode 100644
index f2d5e48e..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/FragmentTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.UDP;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link Fragment}.
- */
-public class FragmentTest {
- private static Data data;
- private static UDP udp;
- private static byte[] bytePacket;
-
- private Deserializer<Fragment> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- data = new Data();
- data.setData("testSerialize".getBytes());
- udp = new UDP();
- udp.setPayload(data);
-
- byte[] bytePayload = udp.serialize();
- byte[] byteHeader = {
- (byte) 0x11, (byte) 0x00, (byte) 0x00, (byte) 0xf9,
- (byte) 0x00, (byte) 0x00, (byte) 0x13, (byte) 0x57
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = Fragment.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- Fragment frag = new Fragment();
- frag.setNextHeader((byte) 0x11);
- frag.setFragmentOffset((short) 0x1f);
- frag.setMoreFragment((byte) 1);
- frag.setIdentification(0x1357);
- frag.setPayload(udp);
-
- assertArrayEquals(frag.serialize(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- Fragment frag = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(frag.getNextHeader(), is((byte) 0x11));
- assertThat(frag.getFragmentOffset(), is((short) 0x1f));
- assertThat(frag.getMoreFragment(), is((byte) 1));
- assertThat(frag.getIdentification(), is(0x1357));
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- Fragment frag1 = new Fragment();
- frag1.setNextHeader((byte) 0x11);
- frag1.setFragmentOffset((short) 0x1f);
- frag1.setMoreFragment((byte) 1);
- frag1.setIdentification(0x1357);
-
- Fragment frag2 = new Fragment();
- frag2.setNextHeader((byte) 0x11);
- frag2.setFragmentOffset((short) 0x1f);
- frag2.setMoreFragment((byte) 1);
- frag2.setIdentification(0x1358);
-
- assertTrue(frag1.equals(frag1));
- assertFalse(frag1.equals(frag2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/HopByHopOptionsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/HopByHopOptionsTest.java
deleted file mode 100644
index 1e9be2f6..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/HopByHopOptionsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Test;
-import org.onlab.packet.IPv6;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-/**
- * Tests for class {@link HopByHopOptions}.
- */
-public class HopByHopOptionsTest {
- /**
- * Tests constructor.
- */
- @Test
- public void testConstructor() {
- HopByHopOptions hopopt = new HopByHopOptions();
- assertThat(hopopt.getType(), is(IPv6.PROTOCOL_HOPOPT));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/RoutingTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/RoutingTest.java
deleted file mode 100644
index a03bacc9..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ipv6/RoutingTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.packet.ipv6;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.UDP;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link Routing}.
- */
-public class RoutingTest {
- private static Data data;
- private static UDP udp;
- private static byte[] routingData = {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- private static byte[] bytePacket;
-
- private Deserializer<Routing> deserializer;
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- data = new Data();
- data.setData("testSerialize".getBytes());
- udp = new UDP();
- udp.setPayload(data);
-
- byte[] bytePayload = udp.serialize();
- byte[] byteHeader = {
- (byte) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x03,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- bytePacket = new byte[byteHeader.length + bytePayload.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
- }
-
- @Before
- public void setUp() {
- deserializer = Routing.deserializer();
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- Routing routing = new Routing();
- routing.setNextHeader((byte) 0x11);
- routing.setHeaderExtLength((byte) 0x02);
- routing.setRoutingType((byte) 0x00);
- routing.setSegmntsLeft((byte) 0x03);
- routing.setRoutingData(routingData);
- routing.setPayload(udp);
-
- assertArrayEquals(routing.serialize(), bytePacket);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- Routing routing = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(routing.getNextHeader(), is((byte) 0x11));
- assertThat(routing.getHeaderExtLength(), is((byte) 0x02));
- assertThat(routing.getRoutingType(), is((byte) 0x00));
- assertThat(routing.getSegmentsLeft(), is((byte) 0x03));
- assertArrayEquals(routing.getRoutingData(), routingData);
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- Routing routing1 = new Routing();
- routing1.setNextHeader((byte) 0x11);
- routing1.setHeaderExtLength((byte) 0x02);
- routing1.setRoutingType((byte) 0x00);
- routing1.setSegmntsLeft((byte) 0x03);
- routing1.setRoutingData(routingData);
-
- Routing routing2 = new Routing();
- routing2.setNextHeader((byte) 0x11);
- routing2.setHeaderExtLength((byte) 0x02);
- routing2.setRoutingType((byte) 0x00);
- routing2.setSegmntsLeft((byte) 0x02);
- routing2.setRoutingData(routingData);
-
- assertTrue(routing1.equals(routing1));
- assertFalse(routing1.equals(routing2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborAdvertisementTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborAdvertisementTest.java
deleted file mode 100644
index d537251c..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborAdvertisementTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.PacketTestUtils;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link NeighborAdvertisement}.
- */
-public class NeighborAdvertisementTest {
- private static final byte[] TARGET_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- private static final MacAddress MAC_ADDRESS =
- MacAddress.valueOf("11:22:33:44:55:66");
-
- private static byte[] bytePacket;
-
- private Deserializer<NeighborAdvertisement> deserializer
- = NeighborAdvertisement.deserializer();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- byte[] byteHeader = {
- (byte) 0xe0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
- (byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
- (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
- };
- bytePacket = new byte[byteHeader.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- NeighborAdvertisement na = new NeighborAdvertisement();
- na.setRouterFlag((byte) 1);
- na.setSolicitedFlag((byte) 1);
- na.setOverrideFlag((byte) 1);
- na.setTargetAddress(TARGET_ADDRESS);
- na.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertArrayEquals(na.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(NeighborAdvertisement.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the NeighborAdvertisement header
- byte[] naHeader = new byte[NeighborAdvertisement.HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(naHeader);
-
- PacketTestUtils.testDeserializeTruncated(NeighborAdvertisement.deserializer(), naHeader);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- NeighborAdvertisement na = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(na.getRouterFlag(), is((byte) 1));
- assertThat(na.getSolicitedFlag(), is((byte) 1));
- assertThat(na.getOverrideFlag(), is((byte) 1));
- assertArrayEquals(na.getTargetAddress(), TARGET_ADDRESS);
-
- // Check the option(s)
- assertThat(na.getOptions().size(), is(1));
- NeighborDiscoveryOptions.Option option = na.getOptions().get(0);
- assertThat(option.type(),
- is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
- assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- NeighborAdvertisement na1 = new NeighborAdvertisement();
- na1.setRouterFlag((byte) 1);
- na1.setSolicitedFlag((byte) 1);
- na1.setOverrideFlag((byte) 1);
- na1.setTargetAddress(TARGET_ADDRESS);
- na1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- NeighborAdvertisement na2 = new NeighborAdvertisement();
- na2.setRouterFlag((byte) 1);
- na2.setSolicitedFlag((byte) 1);
- na2.setOverrideFlag((byte) 0);
- na2.setTargetAddress(TARGET_ADDRESS);
- na2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertTrue(na1.equals(na1));
- assertFalse(na1.equals(na2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java
deleted file mode 100644
index 03e57f5e..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/NeighborSolicitationTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.PacketTestUtils;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link NeighborSolicitation}.
- */
-public class NeighborSolicitationTest {
- private static final byte[] TARGET_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- private static final byte[] TARGET_ADDRESS2 = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff,
- (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
- };
- private static final MacAddress MAC_ADDRESS =
- MacAddress.valueOf("11:22:33:44:55:66");
-
- private static byte[] bytePacket;
-
- private Deserializer<NeighborSolicitation> deserializer
- = NeighborSolicitation.deserializer();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- byte[] byteHeader = {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
- (byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
- (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
- };
- bytePacket = new byte[byteHeader.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- NeighborSolicitation ns = new NeighborSolicitation();
- ns.setTargetAddress(TARGET_ADDRESS);
- ns.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertArrayEquals(ns.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(NeighborSolicitation.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the NeighborSolicitation header
- byte[] nsHeader = new byte[NeighborSolicitation.HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(nsHeader);
-
- PacketTestUtils.testDeserializeTruncated(NeighborSolicitation.deserializer(), nsHeader);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- NeighborSolicitation ns = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertArrayEquals(ns.getTargetAddress(), TARGET_ADDRESS);
-
- // Check the option(s)
- assertThat(ns.getOptions().size(), is(1));
- NeighborDiscoveryOptions.Option option = ns.getOptions().get(0);
- assertThat(option.type(),
- is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
- assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- NeighborSolicitation ns1 = new NeighborSolicitation();
- ns1.setTargetAddress(TARGET_ADDRESS);
- ns1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- NeighborSolicitation ns2 = new NeighborSolicitation();
- ns2.setTargetAddress(TARGET_ADDRESS2);
- ns2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertTrue(ns1.equals(ns1));
- assertFalse(ns1.equals(ns2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RedirectTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RedirectTest.java
deleted file mode 100644
index 31157145..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RedirectTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.PacketTestUtils;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link Redirect}.
- */
-public class RedirectTest {
- private static final byte[] TARGET_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
- };
- private static final byte[] DESTINATION_ADDRESS = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
- };
- private static final byte[] DESTINATION_ADDRESS2 = {
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff,
- (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
- };
- private static final MacAddress MAC_ADDRESS =
- MacAddress.valueOf("11:22:33:44:55:66");
-
- private static byte[] bytePacket;
-
- private Deserializer<Redirect> deserializer = Redirect.deserializer();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- byte[] byteHeader = {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
- (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
- (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
- (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
- (byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
- (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
- };
- bytePacket = new byte[byteHeader.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- Redirect rd = new Redirect();
- rd.setTargetAddress(TARGET_ADDRESS);
- rd.setDestinationAddress(DESTINATION_ADDRESS);
- rd.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertArrayEquals(rd.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(Redirect.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the Redirect header
- byte[] rdHeader = new byte[Redirect.HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(rdHeader);
-
- PacketTestUtils.testDeserializeTruncated(Redirect.deserializer(), rdHeader);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- Redirect rd = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertArrayEquals(rd.getTargetAddress(), TARGET_ADDRESS);
- assertArrayEquals(rd.getDestinationAddress(), DESTINATION_ADDRESS);
-
- // Check the option(s)
- assertThat(rd.getOptions().size(), is(1));
- NeighborDiscoveryOptions.Option option = rd.getOptions().get(0);
- assertThat(option.type(),
- is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
- assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- Redirect rd1 = new Redirect();
- rd1.setTargetAddress(TARGET_ADDRESS);
- rd1.setDestinationAddress(DESTINATION_ADDRESS);
- rd1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- Redirect rd2 = new Redirect();
- rd2.setTargetAddress(TARGET_ADDRESS);
- rd2.setDestinationAddress(DESTINATION_ADDRESS2);
- rd2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertTrue(rd1.equals(rd1));
- assertFalse(rd1.equals(rd2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterAdvertisementTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterAdvertisementTest.java
deleted file mode 100644
index ede15747..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterAdvertisementTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.PacketTestUtils;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link RouterAdvertisement}.
- */
-public class RouterAdvertisementTest {
- private static final MacAddress MAC_ADDRESS =
- MacAddress.valueOf("11:22:33:44:55:66");
-
- private static byte[] bytePacket;
-
- private Deserializer<RouterAdvertisement> deserializer
- = RouterAdvertisement.deserializer();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- byte[] byteHeader = {
- (byte) 0x03, (byte) 0xc0, (byte) 0x02, (byte) 0x58,
- (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0xe8,
- (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0xf4,
- (byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
- (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
- };
- bytePacket = new byte[byteHeader.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- RouterAdvertisement ra = new RouterAdvertisement();
- ra.setCurrentHopLimit((byte) 3);
- ra.setMFlag((byte) 1);
- ra.setOFlag((byte) 1);
- ra.setRouterLifetime((short) 0x258);
- ra.setReachableTime(0x3e8);
- ra.setRetransmitTimer(0x1f4);
- ra.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertArrayEquals(ra.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(RouterAdvertisement.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the RouterAdvertisement header
- byte[] raHeader = new byte[RouterAdvertisement.HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(raHeader);
-
- PacketTestUtils.testDeserializeTruncated(RouterAdvertisement.deserializer(), raHeader);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws DeserializationException {
- RouterAdvertisement ra = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- assertThat(ra.getCurrentHopLimit(), is((byte) 3));
- assertThat(ra.getMFlag(), is((byte) 1));
- assertThat(ra.getOFlag(), is((byte) 1));
- assertThat(ra.getRouterLifetime(), is((short) 0x258));
- assertThat(ra.getReachableTime(), is(0x3e8));
- assertThat(ra.getRetransmitTimer(), is(0x1f4));
-
- // Check the option(s)
- assertThat(ra.getOptions().size(), is(1));
- NeighborDiscoveryOptions.Option option = ra.getOptions().get(0);
- assertThat(option.type(),
- is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
- assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- RouterAdvertisement ra1 = new RouterAdvertisement();
- ra1.setCurrentHopLimit((byte) 3);
- ra1.setMFlag((byte) 1);
- ra1.setOFlag((byte) 1);
- ra1.setRouterLifetime((short) 0x258);
- ra1.setReachableTime(0x3e8);
- ra1.setRetransmitTimer(0x1f4);
- ra1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- RouterAdvertisement ra2 = new RouterAdvertisement();
- ra2.setCurrentHopLimit((byte) 3);
- ra2.setMFlag((byte) 0);
- ra2.setOFlag((byte) 0);
- ra2.setRouterLifetime((short) 0x1f4);
- ra2.setReachableTime(0x3e8);
- ra2.setRetransmitTimer(0x1f4);
- ra2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS.toBytes());
-
- assertTrue(ra1.equals(ra1));
- assertFalse(ra1.equals(ra2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterSolicitationTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterSolicitationTest.java
deleted file mode 100644
index e3b5686c..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/packet/ndp/RouterSolicitationTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet.ndp;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.Deserializer;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.PacketTestUtils;
-
-import java.nio.ByteBuffer;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for class {@link RouterSolicitation}.
- */
-public class RouterSolicitationTest {
- private static final MacAddress MAC_ADDRESS1 =
- MacAddress.valueOf("11:22:33:44:55:66");
- private static final MacAddress MAC_ADDRESS2 =
- MacAddress.valueOf("11:22:33:44:55:00");
-
- private static byte[] bytePacket;
-
- private Deserializer<RouterSolicitation> deserializer
- = RouterSolicitation.deserializer();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- byte[] byteHeader = {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
- (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
- };
- bytePacket = new byte[byteHeader.length];
- System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
- }
-
- /**
- * Tests serialize and setters.
- */
- @Test
- public void testSerialize() {
- RouterSolicitation rs = new RouterSolicitation();
- rs.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS1.toBytes());
-
- assertArrayEquals(rs.serialize(), bytePacket);
- }
-
- @Test
- public void testDeserializeBadInput() throws Exception {
- PacketTestUtils.testDeserializeBadInput(RouterSolicitation.deserializer());
- }
-
- @Test
- public void testDeserializeTruncated() throws Exception {
- // Run the truncation test only on the RouterSolicitation header
- byte[] rsHeader = new byte[RouterSolicitation.HEADER_LENGTH];
- ByteBuffer.wrap(bytePacket).get(rsHeader);
-
- PacketTestUtils.testDeserializeTruncated(RouterSolicitation.deserializer(), rsHeader);
- }
-
- /**
- * Tests deserialize and getters.
- */
- @Test
- public void testDeserialize() throws Exception {
- RouterSolicitation rs = deserializer.deserialize(bytePacket, 0, bytePacket.length);
-
- // Check the option(s)
- assertThat(rs.getOptions().size(), is(1));
- NeighborDiscoveryOptions.Option option = rs.getOptions().get(0);
- assertThat(option.type(),
- is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
- assertArrayEquals(option.data(), MAC_ADDRESS1.toBytes());
- }
-
- /**
- * Tests comparator.
- */
- @Test
- public void testEqual() {
- RouterSolicitation rs1 = new RouterSolicitation();
- rs1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS1.toBytes());
-
- RouterSolicitation rs2 = new RouterSolicitation();
- rs2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
- MAC_ADDRESS2.toBytes());
-
- assertTrue(rs1.equals(rs1));
- assertFalse(rs1.equals(rs2));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java
deleted file mode 100644
index 8a409c3d..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/AbstractAccumulatorTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-
-import java.util.List;
-import java.util.stream.IntStream;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.TestTools.assertAfter;
-
-/**
- * Tests the operation of the accumulator.
- */
-public class AbstractAccumulatorTest {
-
-
- private final ManuallyAdvancingTimer timer = new ManuallyAdvancingTimer(true);
-
- private static final int LONG_REAL_TIME_DELAY = 30;
- private static final int SHORT_REAL_TIME_DELAY = 5;
-
-
- @Test
- public void basics() throws Exception {
- TestAccumulator accumulator = new TestAccumulator();
- assertEquals("incorrect timer", timer, accumulator.timer());
- assertEquals("incorrect max events", 5, accumulator.maxItems());
- assertEquals("incorrect max ms", 100, accumulator.maxBatchMillis());
- assertEquals("incorrect idle ms", 70, accumulator.maxIdleMillis());
- }
-
- @Test
- public void eventTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.add(new TestItem("a"));
- accumulator.add(new TestItem("b"));
- accumulator.add(new TestItem("c"));
- accumulator.add(new TestItem("d"));
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("e"));
- timer.advanceTimeMillis(20, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "abcde", accumulator.batch);
- }
-
- @Test
- public void timeTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.add(new TestItem("a"));
- timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("b"));
- timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("c"));
- timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("d"));
- timer.advanceTimeMillis(10, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "abcd", accumulator.batch);
- }
-
- @Test
- public void idleTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.add(new TestItem("a"));
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("b"));
- timer.advanceTimeMillis(70, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "ab", accumulator.batch);
- }
-
- @Test
- public void readyIdleTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.ready = false;
- accumulator.add(new TestItem("a"));
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("b"));
- timer.advanceTimeMillis(80, SHORT_REAL_TIME_DELAY);
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.ready = true;
- timer.advanceTimeMillis(80, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "ab", accumulator.batch);
- }
-
- @Test
- public void readyLongTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.ready = false;
- timer.advanceTimeMillis(120, SHORT_REAL_TIME_DELAY);
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.add(new TestItem("a"));
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.ready = true;
- timer.advanceTimeMillis(120, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "a", accumulator.batch);
- }
-
- @Test
- public void readyMaxTrigger() {
- TestAccumulator accumulator = new TestAccumulator();
- accumulator.ready = false;
- accumulator.add(new TestItem("a"));
- accumulator.add(new TestItem("b"));
- accumulator.add(new TestItem("c"));
- accumulator.add(new TestItem("d"));
- accumulator.add(new TestItem("e"));
- accumulator.add(new TestItem("f"));
- assertTrue("should not have fired yet", accumulator.batch.isEmpty());
- accumulator.ready = true;
- accumulator.add(new TestItem("g"));
- timer.advanceTimeMillis(10, LONG_REAL_TIME_DELAY);
- assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "abcdefg", accumulator.batch);
- }
-
- @Test
- public void stormTest() {
- TestAccumulator accumulator = new TestAccumulator();
- IntStream.range(0, 1000).forEach(i -> accumulator.add(new TestItem("#" + i)));
- timer.advanceTimeMillis(1);
- assertAfter(100, () -> assertEquals("wrong item count", 1000, accumulator.itemCount));
- assertEquals("wrong batch count", 200, accumulator.batchCount);
- }
-
- private class TestItem {
- private final String s;
-
- public TestItem(String s) {
- this.s = s;
- }
- }
-
- private class TestAccumulator extends AbstractAccumulator<TestItem> {
-
- String batch = "";
- boolean ready = true;
- int batchCount = 0;
- int itemCount = 0;
-
- protected TestAccumulator() {
- super(timer, 5, 100, 70);
- }
-
- @Override
- public void processItems(List<TestItem> items) {
- batchCount++;
- itemCount += items.size();
- for (TestItem item : items) {
- batch += item.s;
- }
- }
-
- @Override
- public boolean isReady() {
- return ready;
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java
deleted file mode 100644
index a3baf06c..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BandwidthTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.lessThan;
-import static org.junit.Assert.assertThat;
-
-/**
- * Unit tests for Bandwidth.
- */
-public class BandwidthTest {
-
- private final Bandwidth small = Bandwidth.kbps(100.0);
- private final Bandwidth large = Bandwidth.mbps(1.0);
-
- /**
- * Tests equality of Bandwidth instances.
- */
- @Test
- public void testEquality() {
- new EqualsTester()
- .addEqualityGroup(Bandwidth.kbps(1000.0), Bandwidth.kbps(1000.0), Bandwidth.mbps(1.0))
- .addEqualityGroup(Bandwidth.gbps(1.0))
- .testEquals();
- }
-
- /**
- * Tests add operation of two Bandwidths.
- */
- @Test
- public void testAdd() {
- Bandwidth expected = Bandwidth.kbps(1100.0);
-
- assertThat(small.add(large), is(expected));
- }
-
- /**
- * Tests subtract operation of two Bandwidths.
- */
- @Test
- public void testSubtract() {
- Bandwidth expected = Bandwidth.kbps(900.0);
-
- assertThat(large.subtract(small), is(expected));
- }
-
- /**
- * Tests if the first object is less than the second object.
- */
- @Test
- public void testLessThan() {
- assertThat(small, is(lessThan(large)));
- assertThat(small.isLessThan(large), is(true));
- }
-
- /**
- * Tests if the first object is greater than the second object.
- */
- @Test
- public void testGreaterThan() {
- assertThat(large, is(greaterThan(small)));
- assertThat(large.isGreaterThan(small), is(true));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java
deleted file mode 100644
index 2d8b688e..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BlockingBooleanTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.apache.commons.lang.mutable.MutableBoolean;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests of the BlockingBoolean utility.
- */
-public class BlockingBooleanTest {
-
- private static final int TIMEOUT = 100; //ms
-
- @Test
- public void basics() {
- BlockingBoolean b = new BlockingBoolean(false);
- assertEquals(false, b.get());
- b.set(true);
- assertEquals(true, b.get());
- b.set(true);
- assertEquals(true, b.get());
- b.set(false);
- assertEquals(false, b.get());
- }
-
- private void waitChange(boolean value, int numThreads) {
- BlockingBoolean b = new BlockingBoolean(!value);
-
- CountDownLatch latch = new CountDownLatch(numThreads);
- ExecutorService exec = Executors.newFixedThreadPool(numThreads);
- for (int i = 0; i < numThreads; i++) {
- exec.submit(() -> {
- try {
- b.await(value);
- latch.countDown();
- } catch (InterruptedException e) {
- fail();
- }
- });
- }
- b.set(value);
- try {
- assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- exec.shutdown();
- }
-
- @Test
- public void waitTrueChange() {
- waitChange(true, 4);
- }
-
- @Test
- public void waitFalseChange() {
- waitChange(false, 4);
- }
-
- @Test
- public void waitSame() {
- BlockingBoolean b = new BlockingBoolean(true);
-
- CountDownLatch latch = new CountDownLatch(1);
- ExecutorService exec = Executors.newSingleThreadExecutor();
- exec.submit(() -> {
- try {
- b.await(true);
- latch.countDown();
- } catch (InterruptedException e) {
- fail();
- }
- });
- try {
- assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- exec.shutdown();
- }
-
- @Test
- public void someWait() {
- BlockingBoolean b = new BlockingBoolean(false);
-
- int numThreads = 4;
- CountDownLatch sameLatch = new CountDownLatch(numThreads / 2);
- CountDownLatch waitLatch = new CountDownLatch(numThreads / 2);
-
- ExecutorService exec = Executors.newFixedThreadPool(numThreads);
- for (int i = 0; i < numThreads; i++) {
- final boolean value = (i % 2 == 1);
- exec.submit(() -> {
- try {
- b.await(value);
- if (value) {
- waitLatch.countDown();
- } else {
- sameLatch.countDown();
- }
- } catch (InterruptedException e) {
- fail();
- }
- });
- }
- try {
- assertTrue(sameLatch.await(TIMEOUT, TimeUnit.MILLISECONDS));
- assertEquals(waitLatch.getCount(), numThreads / 2);
- } catch (InterruptedException e) {
- fail();
- }
- b.set(true);
- try {
- assertTrue(waitLatch.await(TIMEOUT, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- exec.shutdown();
- }
-
- @Test
- public void waitTimeout() {
- BlockingBoolean b = new BlockingBoolean(true);
-
- CountDownLatch latch = new CountDownLatch(1);
- ExecutorService exec = Executors.newSingleThreadExecutor();
- exec.submit(() -> {
- try {
- if (!b.await(false, 1, TimeUnit.NANOSECONDS)) {
- latch.countDown();
- } else {
- fail();
- }
- } catch (InterruptedException e) {
- fail();
- }
- });
- try {
- assertTrue(latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- exec.shutdown();
-
- }
-
- @Test
- @Ignore
- public void samePerf() {
- int iters = 10_000;
-
- BlockingBoolean b1 = new BlockingBoolean(false);
- long t1 = System.nanoTime();
- for (int i = 0; i < iters; i++) {
- b1.set(false);
- }
- long t2 = System.nanoTime();
- MutableBoolean b2 = new MutableBoolean(false);
- for (int i = 0; i < iters; i++) {
- b2.setValue(false);
- }
- long t3 = System.nanoTime();
- System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
- }
-
- @Test
- @Ignore
- public void changePerf() {
- int iters = 10_000;
-
- BlockingBoolean b1 = new BlockingBoolean(false);
- boolean v = true;
- long t1 = System.nanoTime();
- for (int i = 0; i < iters; i++) {
- b1.set(v);
- v = !v;
- }
- long t2 = System.nanoTime();
- MutableBoolean b2 = new MutableBoolean(false);
- for (int i = 0; i < iters; i++) {
- b2.setValue(v);
- v = !v;
- }
- long t3 = System.nanoTime();
- System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java
deleted file mode 100644
index c6132de1..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/BoundedThreadPoolTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.collect.Lists;
-import org.junit.Test;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static org.junit.Assert.*;
-import static org.onlab.util.BoundedThreadPool.*;
-import static org.onlab.util.Tools.namedThreads;
-
-/**
- * Test of BoundedThreadPool.
- */
-public final class BoundedThreadPoolTest {
-
- @Test
- public void simpleJob() {
- final Thread myThread = Thread.currentThread();
- final AtomicBoolean sameThread = new AtomicBoolean(true);
- final CountDownLatch latch = new CountDownLatch(1);
-
- BoundedThreadPool exec = newSingleThreadExecutor(namedThreads("test"));
- exec.submit(() -> {
- sameThread.set(myThread.equals(Thread.currentThread()));
- latch.countDown();
- });
-
- try {
- assertTrue("Job not run", latch.await(100, TimeUnit.MILLISECONDS));
- assertFalse("Runnable used caller thread", sameThread.get());
- } catch (InterruptedException e) {
- fail();
- } finally {
- exec.shutdown();
- }
-
- // TODO perhaps move to tearDown
- try {
- assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- }
-
- private List<CountDownLatch> fillExecutor(BoundedThreadPool exec) {
- int numThreads = exec.getMaximumPoolSize();
- List<CountDownLatch> latches = Lists.newArrayList();
- final CountDownLatch started = new CountDownLatch(numThreads);
- List<CountDownLatch> finished = Lists.newArrayList();
-
- // seed the executor's threads
- for (int i = 0; i < numThreads; i++) {
- final CountDownLatch latch = new CountDownLatch(1);
- final CountDownLatch fin = new CountDownLatch(1);
- latches.add(latch);
- finished.add(fin);
- exec.submit(() -> {
- try {
- started.countDown();
- latch.await();
- fin.countDown();
- } catch (InterruptedException e) {
- fail();
- }
- });
- }
- try {
- assertTrue(started.await(100, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- // fill the queue
- CountDownLatch startedBlocked = new CountDownLatch(1);
- while (exec.getQueue().remainingCapacity() > 0) {
- final CountDownLatch latch = new CountDownLatch(1);
- latches.add(latch);
- exec.submit(() -> {
- try {
- startedBlocked.countDown();
- latch.await();
- } catch (InterruptedException e) {
- fail();
- }
- });
- }
-
- latches.remove(0).countDown(); // release one of the executors
- // ... we need to do this because load is recomputed when jobs are taken
- // Note: For this to work, 1 / numThreads must be less than the load threshold (0.2)
-
- // verify that the old job has terminated
- try {
- assertTrue("Job didn't finish",
- finished.remove(0).await(100, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
-
- // verify that a previously blocked thread has started
- try {
- assertTrue(startedBlocked.await(10, TimeUnit.MILLISECONDS));
- } catch (InterruptedException e) {
- fail();
- }
-
-
- // add another job to fill the queue
- final CountDownLatch latch = new CountDownLatch(1);
- latches.add(latch);
- exec.submit(() -> {
- try {
- latch.await();
- } catch (InterruptedException e) {
- fail();
- }
- });
- assertEquals(exec.getQueue().size(), maxQueueSize);
-
- return latches;
- }
-
- @Test
- public void releaseOneThread() {
- maxQueueSize = 10;
- BoundedThreadPool exec = newFixedThreadPool(4, namedThreads("test"));
- List<CountDownLatch> latches = fillExecutor(exec);
-
- CountDownLatch myLatch = new CountDownLatch(1);
- ExecutorService myExec = Executors.newSingleThreadExecutor();
- Future<Thread> expected = myExec.submit(Thread::currentThread);
-
- assertEquals(exec.getQueue().size(), maxQueueSize);
- long start = System.nanoTime();
- Future<Thread> actual = myExec.submit(() -> {
- return exec.submit(() -> {
- myLatch.countDown();
- return Thread.currentThread();
- }).get();
- });
-
- try {
- assertFalse("Thread should still be blocked",
- myLatch.await(10, TimeUnit.MILLISECONDS));
-
- latches.remove(0).countDown(); // release the first thread
- assertFalse("Thread should still be blocked",
- myLatch.await(10, TimeUnit.MILLISECONDS));
- latches.remove(0).countDown(); // release the second thread
-
- assertTrue("Thread should be unblocked",
- myLatch.await(10, TimeUnit.MILLISECONDS));
- long delta = System.nanoTime() - start;
- double load = exec.getQueue().size() / (double) maxQueueSize;
- assertTrue("Load is greater than threshold", load <= 0.8);
- assertTrue("Load is less than threshold", load >= 0.6);
- assertEquals("Work done on wrong thread", expected.get(), actual.get());
- assertTrue("Took more than one second", delta < Math.pow(10, 9));
- } catch (InterruptedException | ExecutionException e) {
- fail();
- } finally {
- latches.forEach(CountDownLatch::countDown);
- exec.shutdown();
- }
-
- // TODO perhaps move to tearDown
- try {
- assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- fail();
- }
-
- }
-
- @Test
- public void highLoadTimeout() {
- maxQueueSize = 10;
- BoundedThreadPool exec = newFixedThreadPool(2, namedThreads("test"));
- List<CountDownLatch> latches = fillExecutor(exec);
-
- // true if the job is executed and it is done on the test thread
- final AtomicBoolean sameThread = new AtomicBoolean(false);
- final Thread myThread = Thread.currentThread();
- long start = System.nanoTime();
- exec.submit(() -> {
- sameThread.set(myThread.equals(Thread.currentThread()));
- });
-
- long delta = System.nanoTime() - start;
- assertEquals(maxQueueSize, exec.getQueue().size());
- assertTrue("Work done on wrong thread (or didn't happen)", sameThread.get());
- assertTrue("Took less than one second. Actual: " + delta / 1_000_000.0 + "ms",
- delta > Math.pow(10, 9));
- assertTrue("Took more than two seconds", delta < 2 * Math.pow(10, 9));
- latches.forEach(CountDownLatch::countDown);
- exec.shutdown();
-
- // TODO perhaps move to tearDown
- try {
- assertTrue(exec.awaitTermination(1, TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- fail();
- }
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java
deleted file mode 100644
index e3a5e945..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ByteArraySizeHashPrinterTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import static org.junit.Assert.*;
-
-import java.util.Arrays;
-
-import org.junit.Test;
-
-/**
- * Test cases for byte[] pretty printer.
- */
-public class ByteArraySizeHashPrinterTest {
-
- /**
- * Test method for {@link org.onlab.util.ByteArraySizeHashPrinter#toString()}.
- */
- @Test
- public void testToStringNull() {
- final byte[] none = null;
-
- assertEquals("byte[]{null}", String.valueOf(ByteArraySizeHashPrinter.of(none)));
- assertNull(ByteArraySizeHashPrinter.orNull(none));
- }
-
- /**
- * Test method for {@link org.onlab.util.ByteArraySizeHashPrinter#toString()}.
- */
- @Test
- public void testToString() {
- final byte[] some = new byte[] {2, 5, 0, 1 };
- final String expected = "byte[]{length=" + some.length + ", hash=" + Arrays.hashCode(some) + "}";
-
- assertEquals(expected, String.valueOf(ByteArraySizeHashPrinter.of(some)));
- assertNotNull(ByteArraySizeHashPrinter.orNull(some));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java
deleted file mode 100644
index d30e1b59..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/CounterTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.TestTools.delay;
-
-/**
- * Tests of the Counter utility.
- */
-public class CounterTest {
-
- @Test
- public void basics() {
- Counter tt = new Counter();
- assertEquals("incorrect number of bytes", 0L, tt.total());
- assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
- tt.add(1234567890L);
- assertEquals("incorrect number of bytes", 1234567890L, tt.total());
- assertTrue("incorrect throughput", 1234567890.0 < tt.throughput());
- delay(1500);
- tt.add(1L);
- assertEquals("incorrect number of bytes", 1234567891L, tt.total());
- assertTrue("incorrect throughput", 1234567891.0 > tt.throughput());
- tt.reset();
- assertEquals("incorrect number of bytes", 0L, tt.total());
- assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
- }
-
- @Test
- public void freeze() {
- Counter tt = new Counter();
- tt.add(123L);
- assertEquals("incorrect number of bytes", 123L, tt.total());
- delay(1000);
- tt.freeze();
- tt.add(123L);
- assertEquals("incorrect number of bytes", 123L, tt.total());
-
- double d = tt.duration();
- double t = tt.throughput();
- assertEquals("incorrect duration", d, tt.duration(), 0.0001);
- assertEquals("incorrect throughput", t, tt.throughput(), 0.0001);
- assertEquals("incorrect number of bytes", 123L, tt.total());
- }
-
- @Test
- public void reset() {
- Counter tt = new Counter();
- tt.add(123L);
- assertEquals("incorrect number of bytes", 123L, tt.total());
-
- double d = tt.duration();
- double t = tt.throughput();
- assertEquals("incorrect duration", d, tt.duration(), 0.0001);
- assertEquals("incorrect throughput", t, tt.throughput(), 0.0001);
- assertEquals("incorrect number of bytes", 123L, tt.total());
-
- tt.reset();
- assertEquals("incorrect throughput", 0.0, tt.throughput(), 0.0001);
- assertEquals("incorrect number of bytes", 0, tt.total());
- }
-
- @Test
- public void syntheticTracker() {
- Counter tt = new Counter(5000, 1000, 6000);
- assertEquals("incorrect duration", 1, tt.duration(), 0.1);
- assertEquals("incorrect throughput", 1000, tt.throughput(), 1.0);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/DefaultHashMapTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/DefaultHashMapTest.java
deleted file mode 100644
index db6b5fb7..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/DefaultHashMapTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit tests for {@link DefaultHashMap}.
- */
-public class DefaultHashMapTest {
-
- private static final String ONE = "one";
- private static final String TWO = "two";
- private static final String THREE = "three";
- private static final String FOUR = "four";
-
- private static final String ALPHA = "Alpha";
- private static final String BETA = "Beta";
- private static final String OMEGA = "Omega";
-
- private DefaultHashMap<String, Integer> map;
- private DefaultHashMap<String, String> chartis;
-
- private void loadMap() {
- map.put(ONE, 1);
- map.put(TWO, 2);
- }
-
- private void fortioCharti() {
- chartis.put(ONE, ALPHA);
- chartis.put(TWO, BETA);
- }
-
- @Test
- public void nullDefaultIsAllowed() {
- // but makes this class behave no different than HashMap
- map = new DefaultHashMap<>(null);
- loadMap();
- assertEquals("missing 1", 1, (int) map.get(ONE));
- assertEquals("missing 2", 2, (int) map.get(TWO));
- assertEquals("three?", null, map.get(THREE));
- assertEquals("four?", null, map.get(FOUR));
- }
-
- @Test
- public void defaultToFive() {
- map = new DefaultHashMap<>(5);
- loadMap();
- assertEquals("missing 1", 1, (int) map.get(ONE));
- assertEquals("missing 2", 2, (int) map.get(TWO));
- assertEquals("three?", 5, (int) map.get(THREE));
- assertEquals("four?", 5, (int) map.get(FOUR));
- }
-
- @Test
- public void defaultToOmega() {
- chartis = new DefaultHashMap<>(OMEGA);
- fortioCharti();
- assertEquals("missing 1", ALPHA, chartis.get(ONE));
- assertEquals("missing 2", BETA, chartis.get(TWO));
- assertEquals("three?", OMEGA, chartis.get(THREE));
- assertEquals("four?", OMEGA, chartis.get(FOUR));
- }
-
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java
deleted file mode 100644
index 727c0f73..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/FrequencyTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-import org.onlab.junit.ImmutableClassChecker;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.lessThan;
-
-public class FrequencyTest {
-
- private final Frequency frequency1 = Frequency.ofMHz(1000);
- private final Frequency sameFrequency1 = Frequency.ofMHz(1000);
- private final Frequency frequency2 = Frequency.ofGHz(1000);
- private final Frequency sameFrequency2 = Frequency.ofGHz(1000);
- private final Frequency moreSameFrequency2 = Frequency.ofTHz(1);
- private final Frequency frequency3 = Frequency.ofTHz(193.1);
- private final Frequency sameFrequency3 = Frequency.ofGHz(193100);
-
- /**
- * Tests immutability of Frequency.
- */
- @Test
- public void testImmutability() {
- ImmutableClassChecker.assertThatClassIsImmutable(Frequency.class);
- }
-
- /**
- * Tests equality of Frequency instances.
- */
- @Test
- public void testEquality() {
- new EqualsTester()
- .addEqualityGroup(frequency1, sameFrequency1)
- .addEqualityGroup(frequency2, sameFrequency2, moreSameFrequency2)
- .addEqualityGroup(frequency3, sameFrequency3)
- .testEquals();
- }
-
- /**
- * Tests the first object is less than the second object.
- */
- @Test
- public void testLessThan() {
- assertThat(frequency1, is(lessThan(frequency2)));
- assertThat(frequency1.isLessThan(frequency2), is(true));
- }
-
- @Test
- public void testGreaterThan() {
- assertThat(frequency2, is(greaterThan(frequency1)));
- assertThat(frequency2.isGreaterThan(frequency1), is(true));
- }
-
- /**
- * Tests add operation of two Frequencies.
- */
- @Test
- public void testAdd() {
- Frequency low = Frequency.ofMHz(100);
- Frequency high = Frequency.ofGHz(1);
- Frequency expected = Frequency.ofMHz(1100);
-
- assertThat(low.add(high), is(expected));
- }
-
- /**
- * Tests subtract operation of two Frequencies.
- */
- @Test
- public void testSubtract() {
- Frequency high = Frequency.ofGHz(1);
- Frequency low = Frequency.ofMHz(100);
- Frequency expected = Frequency.ofMHz(900);
-
- assertThat(high.subtract(low), is(expected));
- }
-
- /**
- * Tests multiply operation of Frequency.
- */
- @Test
- public void testMultiply() {
- Frequency frequency = Frequency.ofMHz(1000);
- long factor = 5;
- Frequency expected = Frequency.ofGHz(5);
-
- assertThat(frequency.multiply(5), is(expected));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GeoLocationTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GeoLocationTest.java
deleted file mode 100644
index a497bcc4..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GeoLocationTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Test suite of the geo location.
- */
-public class GeoLocationTest {
-
- @Test
- public void basics() {
- GeoLocation nLoc = new GeoLocation(40.7127, -74.0059);
- GeoLocation wLoc = new GeoLocation(38.9047, -77.0164);
-
- assertEquals("incorrect latitude", 40.7127, nLoc.latitude(), 0.0001);
- assertEquals("incorrect longitude", -74.00598, nLoc.longitude(), 0.0001);
- assertEquals("incorrect distance", 326.74, nLoc.kilometersTo(wLoc), 0.01);
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java
deleted file mode 100644
index 5be1cda4..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/GroupedThreadFactoryTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-import org.onlab.junit.TestTools;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests of the group thread factory.
- */
-public class GroupedThreadFactoryTest {
-
- @Test
- public void basics() {
- GroupedThreadFactory a = GroupedThreadFactory.groupedThreadFactory("foo");
- GroupedThreadFactory b = GroupedThreadFactory.groupedThreadFactory("foo");
- assertSame("factories should be same", a, b);
-
- assertTrue("wrong toString", a.toString().contains("foo"));
- Thread t = a.newThread(() -> TestTools.print("yo"));
- assertSame("wrong group", a.threadGroup(), t.getThreadGroup());
- }
-
- @Test
- public void hierarchical() {
- GroupedThreadFactory a = GroupedThreadFactory.groupedThreadFactory("foo/bar");
- GroupedThreadFactory b = GroupedThreadFactory.groupedThreadFactory("foo/goo");
- GroupedThreadFactory p = GroupedThreadFactory.groupedThreadFactory("foo");
-
- assertSame("groups should be same", p.threadGroup(), a.threadGroup().getParent());
- assertSame("groups should be same", p.threadGroup(), b.threadGroup().getParent());
-
- assertEquals("wrong name", "foo/bar", a.threadGroup().getName());
- assertEquals("wrong name", "foo/goo", b.threadGroup().getName());
- assertEquals("wrong name", "foo", p.threadGroup().getName());
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java
deleted file mode 100644
index f4aadd15..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/HexStringTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-
-import com.esotericsoftware.minlog.Log;
-
-import junit.framework.TestCase;
-
-import static org.junit.Assert.fail;
-
-/**
- * Test of the Hexstring.
- *
- */
-
-public class HexStringTest {
-
- @Test
- public void testMarshalling() throws Exception {
- String dpidStr = "00:00:00:23:20:2d:16:71";
- long dpid = HexString.toLong(dpidStr);
- String testStr = HexString.toHexString(dpid);
- TestCase.assertEquals(dpidStr, testStr);
- }
-
- @Test
- public void testToLong() {
- String dpidStr = "3e:1f:01:fc:72:8c:63:31";
- long valid = 0x3e1f01fc728c6331L;
- long testLong = HexString.toLong(dpidStr);
- TestCase.assertEquals(valid, testLong);
- }
-
- @Test
- public void testToLongMsb() {
- String dpidStr = "ca:7c:5e:d1:64:7a:95:9b";
- long valid = -3856102927509056101L;
- long testLong = HexString.toLong(dpidStr);
- TestCase.assertEquals(valid, testLong);
- }
-
- @Test
- public void testToLongError() {
- String dpidStr = "09:08:07:06:05:04:03:02:01";
- try {
- HexString.toLong(dpidStr);
- fail("HexString.toLong() should have thrown a NumberFormatException");
- } catch (NumberFormatException expected) {
- Log.info("HexString.toLong() have thrown a NumberFormatException");
- }
- }
-
- @Test
- public void testToStringBytes() {
- byte[] dpid = {0, 0, 0, 0, 0, 0, 0, -1 };
- String valid = "00:00:00:00:00:00:00:ff";
- String testString = HexString.toHexString(dpid);
- TestCase.assertEquals(valid, testString);
- }
-
- @Test
- public void testFromHexStringError() {
- String invalidStr = "00:00:00:00:00:00:ffff";
- try {
- HexString.fromHexString(invalidStr);
- fail("HexString.fromHexString() should have thrown a NumberFormatException");
- } catch (NumberFormatException expected) {
- Log.info("HexString.toLong() have thrown a NumberFormatException");
- }
- }
-}
-
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimer.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimer.java
deleted file mode 100644
index 8fb008e8..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimer.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import com.google.common.collect.Lists;
-import org.onlab.junit.TestUtils;
-import org.slf4j.Logger;
-
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.junit.TestTools.delay;
-import static org.slf4j.LoggerFactory.getLogger;
-
-
-/**
- * Provides manually scheduled timer utility. All schedulable methods are subject to overflow (you can set a period of
- * max long). Additionally if a skip skips a period of time greater than one period for a periodic task that task will
- * only be executed once for that skip and scheduled it's period after the last execution.
- */
-public class ManuallyAdvancingTimer extends java.util.Timer {
-
- /* States whether or not the static values from timer task have been set ensures population will only occur once.*/
- private boolean staticsPopulated = false;
-
- /* Virgin value from timer task */
- private int virginState;
-
- /* Scheduled value from timer task */
- private int scheduledState;
-
- /* Executed value from timer task */
- private int executedState;
-
- /* Cancelled value from timer task */
- private int cancelledState;
-
- private final Logger logger = getLogger(getClass());
-
- /* Service for executing timer tasks */
- private final ExecutorService executorService = Executors.newSingleThreadExecutor();
-
- /* Internal time representation independent of system time, manually advanced */
- private final TimerKeeper timerKeeper = new TimerKeeper();
-
- /* Data structure for tracking tasks */
- private final TaskQueue queue = new TaskQueue();
-
- /* Whether execution should execute on the executor thread or the calling thread. */
- private final boolean runLocally;
-
- public ManuallyAdvancingTimer(boolean runLocally) {
- this.runLocally = runLocally;
- }
-
-
- @Override
- public void schedule(TimerTask task, long delay) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
- timerKeeper.currentTimeInMillis() - delay, 0)) {
- logger.error("Failed to submit task");
- }
- }
-
- @Override
- public void schedule(TimerTask task, Date time) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, time.getTime(), 0)) {
- logger.error("Failed to submit task");
- }
- }
-
- @Override
- public void schedule(TimerTask task, long delay, long period) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
- timerKeeper.currentTimeInMillis() - delay, period)) {
- logger.error("Failed to submit task");
- }
- }
-
- @Override
- public void schedule(TimerTask task, Date firstTime, long period) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, firstTime.getTime(), period)) {
- logger.error("Failed to submit task");
- }
- }
-
- /*################################################WARNING################################################*/
- /* Schedule at fixed rate methods do not work exactly as in the java timer. They are clones of the periodic
- *scheduling methods. */
- @Override
- public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
- timerKeeper.currentTimeInMillis() - delay, period)) {
- logger.error("Failed to submit task");
- }
- }
-
- @Override
- public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
- if (!staticsPopulated) {
- populateStatics(task);
- }
- if (!submitTask(task, firstTime.getTime(), period)) {
- logger.error("Failed to submit task");
- }
- }
-
- @Override
- public void cancel() {
- executorService.shutdown();
- queue.clear();
- }
-
- @Override
- public int purge() {
- return queue.removeCancelled();
- }
-
- /**
- * Returns the virtual current time in millis.
- *
- * @return long representing simulated current time.
- */
- public long currentTimeInMillis() {
- return timerKeeper.currentTimeInMillis();
- }
-
- /**
- * Returns the new simulated current time in millis after advancing the absolute value of millis to advance.
- * Triggers event execution of all events scheduled for execution at times up to and including the returned time.
- * Passing in the number zero has no effect.
- *
- * @param millisToAdvance the number of millis to advance.
- * @return a long representing the current simulated time in millis
- */
- public long advanceTimeMillis(long millisToAdvance) {
- return timerKeeper.advanceTimeMillis(millisToAdvance);
- }
-
- /**
- * Advances the virtual time a certain number of millis triggers execution delays a certain amount to
- * allow time for execution. If runLocally is true then all real time delays are ignored.
- *
- * @param virtualTimeAdvance the time to be advances in millis of simulated time.
- * @param realTimeDelay the time to delay in real time to allow for processing.
- */
- public void advanceTimeMillis(long virtualTimeAdvance, int realTimeDelay) {
- timerKeeper.advanceTimeMillis(virtualTimeAdvance);
- if (!runLocally) {
- delay(realTimeDelay);
- }
- }
-
- /**
- * Sets up the task and submits it to the queue.
- *
- * @param task the task to be added to the queue
- * @param runtime the first runtime of the task
- * @param period the period between runs thereafter
- * @return returns true if the task was successfully submitted, false otherwise
- */
- private boolean submitTask(TimerTask task, long runtime, long period) {
- checkNotNull(task);
- try {
- TestUtils.setField(task, "state", scheduledState);
- TestUtils.setField(task, "nextExecutionTime", runtime);
- TestUtils.setField(task, "period", period);
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- return false;
- }
- queue.insertOrdered(task);
- return true;
- }
-
- /**
- * Executes the given task (only if it is in the scheduled state) and proceeds to reschedule it or mark it as
- * executed. Does not remove from the queue (this must be done outside).
- *
- * @param task the timer task to be executed
- */
- private boolean executeTask(TimerTask task) {
- checkNotNull(task);
- int currentState;
- try {
- currentState = TestUtils.getField(task, "state");
- } catch (TestUtils.TestUtilsException e) {
- logger.error("Could not get state of task.");
- e.printStackTrace();
- return false;
- }
- //If cancelled or already executed stop here.
- if (currentState == executedState || currentState == cancelledState) {
- return false;
- } else if (currentState == virginState) {
- logger.error("Task was set for execution without being scheduled.");
- return false;
- } else if (currentState == scheduledState) {
- long period;
-
- try {
- period = TestUtils.getField(task, "period");
- } catch (TestUtils.TestUtilsException e) {
- logger.error("Could not read period of task.");
- e.printStackTrace();
- return false;
- }
- //Period of zero means one time execution.
- if (period == 0) {
- try {
- TestUtils.setField(task, "state", executedState);
- } catch (TestUtils.TestUtilsException e) {
- logger.error("Could not set executed state.");
- e.printStackTrace();
- return false;
- }
- if (runLocally) {
- task.run();
- } else {
- executorService.execute(task);
- }
- return true;
- } else {
- //Calculate next execution time, using absolute value of period
- long nextTime = (period > 0) ? (timerKeeper.currentTimeInMillis() + period) :
- (timerKeeper.currentTimeInMillis() - period);
- try {
- TestUtils.setField(task, "nextExecutionTime", nextTime);
- } catch (TestUtils.TestUtilsException e) {
- logger.error("Could not set next execution time.");
- e.printStackTrace();
- return false;
- }
- //Schedule next execution
- queue.insertOrdered(task);
- if (runLocally) {
- task.run();
- } else {
- executorService.execute(task);
- }
- return true;
- }
- }
- logger.error("State property of {} is in an illegal state and did not execute.", task);
- return false;
- }
-
- /**
- * Executes all tasks in the queue scheduled for execution up to and including the current time.
- *
- * @return the total number of tasks run, -1 if failure
- */
- private int executeEventsUpToPresent() {
- int totalRun = 0;
- if (queue.isEmpty()) {
- return -1;
- }
- TimerTask currTask = queue.peek();
- long currExecTime;
- try {
- currExecTime = TestUtils.getField(currTask, "nextExecutionTime");
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- throw new RuntimeException("Could not get nextExecutionTime");
- }
- while (currExecTime <= timerKeeper.currentTimeInMillis()) {
- if (executeTask(queue.pop())) {
- totalRun++;
- }
- if (queue.isEmpty()) {
- break;
- }
- currTask = queue.peek();
- try {
- currExecTime = TestUtils.getField(currTask, "nextExecutionTime");
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- throw new RuntimeException("Could not get nextExecutionTime");
- }
- }
- return totalRun;
- }
-
- /**
- * Populates the static fields from timer task. Should only be called once.
- */
- private void populateStatics(TimerTask task) {
- try {
- virginState = TestUtils.getField(task, "VIRGIN");
- scheduledState = TestUtils.getField(task, "SCHEDULED");
- executedState = TestUtils.getField(task, "EXECUTED");
- cancelledState = TestUtils.getField(task, "CANCELLED");
- staticsPopulated = true;
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * A class used to maintain the virtual time.
- */
- private class TimerKeeper {
-
- private long currentTime = 0;
-
- /**
- * Returns the virtual current time in millis.
- *
- * @return long representing simulated current time.
- */
- long currentTimeInMillis() {
- return currentTime;
- }
-
- /**
- * Returns the new simulated current time in millis after advancing the absolute value of millis to advance.
- * Triggers event execution of all events scheduled for execution at times up to and including the returned
- * time. Passing in the number zero has no effect.
- *
- * @param millisToAdvance the number of millis to advance.
- * @return a long representing the current simulated time in millis
- */
- long advanceTimeMillis(long millisToAdvance) {
- currentTime = (millisToAdvance >= 0) ? (currentTime + millisToAdvance) : (currentTime - millisToAdvance);
- if (millisToAdvance != 0) {
- executeEventsUpToPresent();
- }
- return currentTime;
- }
- }
-
- /**
- * A queue backed by a linked list. Keeps elements sorted in ascending order of execution time. All calls are safe
- * even on empty queue's.
- */
- private class TaskQueue {
- private final LinkedList<TimerTask> taskList = Lists.newLinkedList();
-
- /**
- * Adds the task to the queue in ascending order of scheduled execution. If execution time has already passed
- * execute immediately.
- *
- * @param task the task to be added to the queue
- */
- void insertOrdered(TimerTask task) {
- //Using O(N) insertion because random access is expensive in linked lists worst case is 2N links followed
- // for binary insertion vs N for simple insertion.
- checkNotNull(task);
- if (!staticsPopulated) {
- populateStatics(task);
- }
- long insertTime;
- try {
- insertTime = TestUtils.getField(task, "nextExecutionTime");
- TestUtils.setField(task, "state", scheduledState);
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- return;
- }
- //If the task was scheduled in the past or for the current time run it immediately and do not add to the
- // queue, subsequent executions will be scheduled as normal
- if (insertTime <= timerKeeper.currentTimeInMillis()) {
- executeTask(task);
- return;
- }
-
- Iterator<TimerTask> iter = taskList.iterator();
- int positionCounter = 0;
- long nextTaskTime;
- TimerTask currentTask;
- while (iter.hasNext()) {
- currentTask = iter.next();
- try {
- nextTaskTime = TestUtils.getField(currentTask, "nextExecutionTime");
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- return;
- }
- if (insertTime < nextTaskTime) {
- taskList.add(positionCounter, task);
- return;
- }
- positionCounter++;
- }
- taskList.addLast(task);
- }
-
- /**
- * Returns the first item in the queue (next scheduled for execution) without removing it, returns null if the
- * queue is empty.
- *
- * @return the next TimerTask to run or null if the queue is empty
- */
- TimerTask peek() {
- if (taskList.isEmpty()) {
- return null;
- }
- return taskList.getFirst();
- }
-
- /**
- * Returns and removes the first item in the queue or null if it is empty.
- *
- * @return the first element of the queue or null if the queue is empty
- */
- TimerTask pop() {
- if (taskList.isEmpty()) {
- return null;
- }
- return taskList.pop();
- }
-
- /**
- * Performs a sort on the set of timer tasks, earliest task is first. Does nothing if queue is empty.
- */
- void sort() {
- if (taskList.isEmpty()) {
- return;
- }
- taskList.sort((o1, o2) -> {
- checkNotNull(o1);
- checkNotNull(o2);
- long executionTimeOne;
- long executionTimeTwo;
- try {
- executionTimeOne = TestUtils.getField(o1, "nextExecutionTime");
- executionTimeTwo = TestUtils.getField(o2, "nextExecutionTime");
- } catch (TestUtils.TestUtilsException e) {
- e.printStackTrace();
- throw new RuntimeException("Could not get next execution time.");
- }
- if (executionTimeOne == executionTimeTwo) {
- return 0;
- } else if (executionTimeOne < executionTimeTwo) {
- return -1;
- } else {
- return 1;
- }
- });
- }
-
- /**
- * Returns whether the queue is currently empty.
- *
- * @return true if the queue is empty, false otherwise
- */
- boolean isEmpty() {
- return taskList.isEmpty();
- }
-
- /**
- * Clears the underlying list of the queue.
- */
- void clear() {
- taskList.clear();
- }
-
- /**
- * Removes all cancelled tasks from the queue. Has no effect on behavior.
- *
- * @return returns the total number of items removed, -1 if list is empty or failure occurs.
- */
- int removeCancelled() {
- if (taskList.isEmpty()) {
- return -1;
- }
- int removedCount = 0;
- Iterator<TimerTask> taskIterator = taskList.iterator();
- TimerTask currTask;
- int currState;
- while (taskIterator.hasNext()) {
- currTask = taskIterator.next();
- try {
- currState = TestUtils.getField(currTask, "state");
- } catch (TestUtils.TestUtilsException e) {
- logger.error("Could not get task state.");
- e.printStackTrace();
- return -1;
- }
- if (currState == cancelledState) {
- removedCount++;
- taskIterator.remove();
- }
- }
- return removedCount;
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java
deleted file mode 100644
index 36b50e67..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import com.google.common.collect.Lists;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.TimerTask;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.junit.TestTools.delay;
-
-/**
- * Testing class for manually advancing timer.
- */
-public class ManuallyAdvancingTimerTest {
-
- private ManuallyAdvancingTimer timer;
-
- /* Generates unique id's for TestTasks */
- private AtomicInteger idGenerator;
-
- /* Tracks TestTasks in order of creation, tasks are automatically added at creation. */
- private ArrayList<TestTask> taskList;
-
- /* Total number of tasks run */
- private AtomicInteger tasksRunCount;
-
- // FIXME if this class fails first try increasing the real time delay to account for heavy system load.
- private static final int REAL_TIME_DELAY = 10;
-
- /**
- * Sets up the testing environment.
- */
- @Before
- public void setup() {
- timer = new ManuallyAdvancingTimer(true);
- idGenerator = new AtomicInteger(1);
- tasksRunCount = new AtomicInteger(0);
- taskList = Lists.newArrayList();
- }
-
- /**
- * Tests the one time schedule with delay.
- *
- * @throws Exception throws an exception if the test fails
- */
- @Test
- public void testScheduleByDelay() throws Exception {
- /* Test scheduling in the future as normal. */
- timer.schedule(new TestTask(), 10);
- timer.advanceTimeMillis(5);
- assertFalse(taskList.get(0).hasRun());
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertTrue(taskList.get(0).hasRun());
-
- /* Test scheduling with negative numbers */
- timer.schedule(new TestTask(), -10);
- timer.advanceTimeMillis(5);
- assertFalse(taskList.get(1).hasRun());
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertTrue(taskList.get(1).hasRun());
-
- /* Reset list, counter and timer for next test */
- taskList.clear();
- idGenerator.set(1);
- tasksRunCount.set(0);
-
- for (int i = 0; i < 50; i++) {
- timer.schedule(new TestTask(), i);
- }
- /* Test that a task scheduled for present is run and not placed in the queue */
- assertEquals("Only the first task should have run.", 1, tasksRunCount.get());
-
- for (int i = 2; i <= 50; i++) {
- timer.advanceTimeMillis(1, REAL_TIME_DELAY);
- assertEquals("One task should be executed per loop", i, tasksRunCount.get());
- }
- /* Below tests ordered insertion, this will only be done once, it is the same for all schedule methods. */
-
- tasksRunCount.set(0);
-
- for (int i = 0; i < 10; i++) {
- timer.schedule(new TestTask(), 500);
- }
-
- assertEquals("No new tasks should have been run since run count reset.", 0, tasksRunCount.get());
- timer.schedule(new TestTask(), 10);
- assertEquals("No new tasks should have been run since run count reset.", 0, tasksRunCount.get());
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertEquals("One new tasks should have been run since run count reset.", 1, tasksRunCount.get());
- timer.advanceTimeMillis(510, REAL_TIME_DELAY);
- assertEquals("Eleven new tasks should have been run since run count reset.", 11, tasksRunCount.get());
- }
-
- /**
- * Tests scheduling for a particular date or time which may be in the past.
- *
- * @throws Exception throws an exception if the test fails
- */
- @Test
- public void testScheduleByDate() throws Exception {
- /* Tests basic scheduling for future times. */
- timer.schedule(new TestTask(), new Date(10));
- timer.advanceTimeMillis(5);
- assertFalse(taskList.get(0).hasRun());
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertTrue(taskList.get(0).hasRun());
-
- /* Test scheduling with past times numbers */
- timer.schedule(new TestTask(), new Date(0));
- delay(REAL_TIME_DELAY);
- assertTrue(taskList.get(1).hasRun());
-
- /* Tests cancellation on non-periodic events */
- TestTask task = new TestTask();
- timer.schedule(task, new Date(timer.currentTimeInMillis() + 10));
- task.cancel();
- timer.advanceTimeMillis(12, REAL_TIME_DELAY);
- assertFalse(task.hasRun());
-
- }
-
- /**
- * Test scheduling beginning after a delay and recurring periodically.
- *
- * @throws Exception throws an exception if the test fails
- */
- @Test
- public void testScheduleByDelayPeriodic() throws Exception {
- /* Test straightforward periodic execution */
- timer.schedule(new TestTask(), 0, 10);
- delay(REAL_TIME_DELAY);
- assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun());
-
- /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute
- immediately on add). */
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun());
-
- /* Tests whether cancellation works on periodic events. */
- taskList.get(0).cancel();
-
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun());
-
- TestTask task = new TestTask();
- timer.schedule(task, 0, 10);
- timer.advanceTimeMillis(100, REAL_TIME_DELAY);
- assertEquals("Should have run immeditaley and subsequently once during the larger skip", task.timesRun(), 2);
-
- }
-
- /**
- * Test scheduling beginning at a specified date and recurring periodically.
- *
- * @throws Exception throws an exception if the test fails
- */
- @Test
- public void testScheduleByDatePeriodic() throws Exception {
- /* Test straightforward periodic execution */
- timer.schedule(new TestTask(), new Date(timer.currentTimeInMillis()), 10);
- delay(REAL_TIME_DELAY);
- assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun());
-
- /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute
- immediately on add). */
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun());
-
- /* Tests whether cancellation works on periodic events. */
- taskList.get(0).cancel();
-
- timer.advanceTimeMillis(10, REAL_TIME_DELAY);
- assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun());
-
- TestTask task = new TestTask();
- timer.schedule(task, new Date(timer.currentTimeInMillis()), 10);
- timer.advanceTimeMillis(100, REAL_TIME_DELAY);
- assertEquals("Should have run immediately and subsequently once during the larger skip", task.timesRun(), 2);
- }
-
- /* Schedule at fixed rate runs exactly like the two scheduling methods just tested so tests are not included */
-
- /**
- * Timer task with added functions to make it better for testing.
- */
- private class TestTask extends TimerTask {
-
- /* Remains true once the task has been run at least once */
- private boolean hasRun;
-
- /* Unique id per event. */
- private int id;
-
- /* Specifies the number of times an event has run */
- private int timesRun;
-
- /**
- * Constructor initializes id, timesRun, and id fields.
- */
- public TestTask() {
- id = idGenerator.getAndIncrement();
- timesRun = 0;
- hasRun = false;
- taskList.add(this);
- }
-
- @Override
- public void run() {
- this.hasRun = true;
- tasksRunCount.incrementAndGet();
- timesRun++;
- }
-
- /**
- * Returns whether this event has run.
- *
- * @return true if the event has run, false otherwise.
- */
- public boolean hasRun() {
- return hasRun;
- }
-
- /**
- * Returns the number of times this task has run.
- *
- * @return an int representing the number of times this task has been run
- */
- public int timesRun() {
- return timesRun;
- }
-
- /**
- * Returns the unique identifier of this task.
- *
- * @return a unique integer identifier
- */
- public int getId() {
- return id;
- }
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java
deleted file mode 100644
index 9758511f..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/PositionalParameterStringFormatterTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onlab.util;
-
-import static org.junit.Assert.*;
-import static org.onlab.util.PositionalParameterStringFormatter.format;
-
-import org.junit.Test;
-
-public class PositionalParameterStringFormatterTest {
-
- @Test
- public void testFormat0() {
- String fmt = "Some string 1 2 3";
- assertEquals("Some string 1 2 3", format(fmt));
- }
-
- @Test
- public void testFormat1() {
- String fmt = "Some string {} 2 3";
- assertEquals("Some string 1 2 3", format(fmt, 1));
- }
-
- @Test
- public void testFormat2() {
- String fmt = "Some string {} 2 {}";
- assertEquals("Some string 1 2 3", format(fmt, 1, "3"));
- }
-
- @Test
- public void testFormatNull() {
- String fmt = "Some string {} 2 {}";
- assertEquals("Some string 1 2 null", format(fmt, 1, null));
- }
-
- @Test
- public void testFormatExtraBracket() {
- String fmt = "Some string {} 2 {}";
- assertEquals("Some string 1 2 {}", format(fmt, 1));
- }
-
- @Test
- public void testFormatMissingBracket() {
- String fmt = "Some string 1 2 3";
- assertEquals("Some string 1 2 3", format(fmt, 7));
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java
deleted file mode 100644
index 4b08d2fc..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/RetryingFunctionTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for RetryingFunction.
- *
- */
-public class RetryingFunctionTest {
-
- private int round;
-
- @Before
- public void setUp() {
- round = 1;
- }
-
- @After
- public void tearDown() {
- round = 0;
- }
-
- @Test(expected = RetryableException.class)
- public void testNoRetries() {
- new RetryingFunction<>(this::succeedAfterOneFailure, RetryableException.class, 0, 10).apply(null);
- }
-
- @Test
- public void testSuccessAfterOneRetry() {
- new RetryingFunction<>(this::succeedAfterOneFailure, RetryableException.class, 1, 10).apply(null);
- }
-
- @Test(expected = RetryableException.class)
- public void testFailureAfterOneRetry() {
- new RetryingFunction<>(this::succeedAfterTwoFailures, RetryableException.class, 1, 10).apply(null);
- }
-
- @Test
- public void testFailureAfterTwoRetries() {
- new RetryingFunction<>(this::succeedAfterTwoFailures, RetryableException.class, 2, 10).apply(null);
- }
-
- @Test(expected = NonRetryableException.class)
- public void testFailureWithNonRetryableFailure() {
- new RetryingFunction<>(this::failCompletely, RetryableException.class, 2, 10).apply(null);
- }
-
- private String succeedAfterOneFailure(String input) {
- if (round++ <= 1) {
- throw new RetryableException();
- } else {
- return "pass";
- }
- }
-
- private String succeedAfterTwoFailures(String input) {
- if (round++ <= 2) {
- throw new RetryableException();
- } else {
- return "pass";
- }
- }
-
- private String failCompletely(String input) {
- if (round++ <= 1) {
- throw new NonRetryableException();
- } else {
- return "pass";
- }
- }
-
- private class RetryableException extends RuntimeException {
- }
-
- private class NonRetryableException extends RuntimeException {
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java
deleted file mode 100644
index 1730ca1f..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SharedExecutorsTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-
-import java.util.concurrent.ExecutorService;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests of the SharedExecutors Test.
- */
-public class SharedExecutorsTest {
-
- @Test
- public void singleThread() {
- ExecutorService a = SharedExecutors.getSingleThreadExecutor();
- assertNotNull("ExecutorService must not be null", a);
- ExecutorService b = SharedExecutors.getSingleThreadExecutor();
- assertSame("factories should be same", a, b);
-
- }
-
- @Test
- public void poolThread() {
- ExecutorService a = SharedExecutors.getPoolThreadExecutor();
- assertNotNull("ExecutorService must not be null", a);
- ExecutorService b = SharedExecutors.getPoolThreadExecutor();
- assertSame("factories should be same", a, b);
-
- }
-
- @Test
- public void timer() {
- java.util.Timer a = SharedExecutors.getTimer();
- assertNotNull("Timer must not be null", a);
- java.util.Timer b = SharedExecutors.getTimer();
- assertSame("factories should be same", a, b);
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
deleted file mode 100644
index c15cc8a6..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import static junit.framework.TestCase.fail;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for the sliding window counter.
- */
-
-@Ignore("Disable these for now because of intermittent load related failures on Jenkins runs.")
-public class SlidingWindowCounterTest {
-
- private SlidingWindowCounter counter;
-
- @Before
- public void setUp() {
- counter = new SlidingWindowCounter(2);
- }
-
- @After
- public void tearDown() {
- counter.destroy();
- }
-
- @Test
- public void testIncrementCount() {
- assertEquals(0, counter.get(1));
- assertEquals(0, counter.get(2));
- counter.incrementCount();
- assertEquals(1, counter.get(1));
- assertEquals(1, counter.get(2));
- counter.incrementCount(2);
- assertEquals(3, counter.get(2));
- }
-
- @Test
- public void testSlide() {
- counter.incrementCount();
- counter.advanceHead();
- assertEquals(0, counter.get(1));
- assertEquals(1, counter.get(2));
- counter.incrementCount(2);
- assertEquals(2, counter.get(1));
- assertEquals(3, counter.get(2));
- }
-
- @Test
- public void testWrap() {
- counter.incrementCount();
- counter.advanceHead();
- counter.incrementCount(2);
- counter.advanceHead();
- assertEquals(0, counter.get(1));
- assertEquals(2, counter.get(2));
- counter.advanceHead();
- assertEquals(0, counter.get(1));
- assertEquals(0, counter.get(2));
-
- }
-
- @Test
- public void testCornerCases() {
- try {
- counter.get(3);
- fail("Exception should have been thrown");
- } catch (IllegalArgumentException e) {
- assertTrue(true);
- }
-
- try {
- new SlidingWindowCounter(0);
- fail("Exception should have been thrown");
- } catch (IllegalArgumentException e) {
- assertTrue(true);
- }
-
- try {
- new SlidingWindowCounter(-1);
- fail("Exception should have been thrown");
- } catch (IllegalArgumentException e) {
- assertTrue(true);
- }
- }
-}
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java
deleted file mode 100644
index 56f0f957..00000000
--- a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ToolsTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.util;
-
-import org.junit.Test;
-import org.onlab.junit.TestTools;
-
-import java.util.concurrent.ThreadFactory;
-
-import static org.junit.Assert.*;
-import static org.onlab.junit.TestTools.assertAfter;
-
-/**
- * Test of the miscellaneous tools.
- */
-public class ToolsTest {
-
- @Test
- public void fromHex() throws Exception {
- assertEquals(15, Tools.fromHex("0f"));
- assertEquals(16, Tools.fromHex("10"));
- assertEquals(65535, Tools.fromHex("ffff"));
- assertEquals(4096, Tools.fromHex("1000"));
- assertEquals(0xffffffffffffffffL, Tools.fromHex("ffffffffffffffff"));
- }
-
- @Test
- public void toHex() throws Exception {
- assertEquals("0f", Tools.toHex(15, 2));
- assertEquals("ffff", Tools.toHex(65535, 4));
- assertEquals("1000", Tools.toHex(4096, 4));
- assertEquals("000000000000000f", Tools.toHex(15));
- assertEquals("ffffffffffffffff", Tools.toHex(0xffffffffffffffffL));
-
- }
-
- @Test
- public void namedThreads() {
- ThreadFactory f = Tools.namedThreads("foo-%d");
- Thread t = f.newThread(() -> TestTools.print("yo"));
- assertTrue("wrong pattern", t.getName().startsWith("foo-"));
- }
-
- @Test
- public void groupedThreads() {
- ThreadFactory f = Tools.groupedThreads("foo/bar-me", "foo-%d");
- Thread t = f.newThread(() -> TestTools.print("yo"));
- assertTrue("wrong pattern", t.getName().startsWith("foo-bar-me-foo-"));
- assertTrue("wrong group", t.getThreadGroup().getName().equals("foo/bar-me"));
- }
-
- @Test
- public void exceptionHandler() throws InterruptedException {
- ThreadFactory f = Tools.namedThreads("foo");
- Thread t = f.newThread(() -> {
- throw new IllegalStateException("BOOM!");
- });
- assertNotNull("thread should have exception handler", t.getUncaughtExceptionHandler());
- t.start();
- assertAfter(100, () -> assertEquals("incorrect thread state", Thread.State.TERMINATED, t.getState()));
- }
-
-}
diff --git a/framework/src/onos/utils/netty/pom.xml b/framework/src/onos/utils/netty/pom.xml
deleted file mode 100644
index 7bae10aa..00000000
--- a/framework/src/onos/utils/netty/pom.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-netty</artifactId>
- <packaging>bundle</packaging>
-
- <description>Network I/O using Netty framework</description>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-misc</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-pool</groupId>
- <artifactId>commons-pool</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport-native-epoll</artifactId>
- <version>${netty4.version}</version>
- </dependency>
- </dependencies>
-</project>
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/DecoderState.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/DecoderState.java
deleted file mode 100644
index c4393018..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/DecoderState.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.netty;
-
-/**
- * State transitions a decoder goes through as it is decoding an incoming message.
- */
-public enum DecoderState {
- READ_MESSAGE_PREAMBLE,
- READ_MESSAGE_ID,
- READ_SENDER_IP_VERSION,
- READ_SENDER_IP,
- READ_SENDER_PORT,
- READ_MESSAGE_TYPE_LENGTH,
- READ_MESSAGE_TYPE,
- READ_CONTENT_LENGTH,
- READ_CONTENT
-}
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/InternalMessage.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/InternalMessage.java
deleted file mode 100644
index 102e2a22..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/InternalMessage.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.netty;
-
-import org.onlab.util.ByteArraySizeHashPrinter;
-import org.onosproject.store.cluster.messaging.Endpoint;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Internal message representation with additional attributes
- * for supporting, synchronous request/reply behavior.
- */
-public final class InternalMessage {
-
- private final long id;
- private final Endpoint sender;
- private final String type;
- private final byte[] payload;
-
- public InternalMessage(long id, Endpoint sender, String type, byte[] payload) {
- this.id = id;
- this.sender = sender;
- this.type = type;
- this.payload = payload;
- }
-
- public long id() {
- return id;
- }
-
- public String type() {
- return type;
- }
-
- public Endpoint sender() {
- return sender;
- }
-
- public byte[] payload() {
- return payload;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .add("type", type)
- .add("sender", sender)
- .add("payload", ByteArraySizeHashPrinter.of(payload))
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageDecoder.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageDecoder.java
deleted file mode 100644
index af52a41c..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageDecoder.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.netty;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ReplayingDecoder;
-
-import java.util.List;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onosproject.store.cluster.messaging.Endpoint;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-
-/**
- * Decoder for inbound messages.
- */
-public class MessageDecoder extends ReplayingDecoder<DecoderState> {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private final int correctPreamble;
- private long messageId;
- private int preamble;
- private Version ipVersion;
- private IpAddress senderIp;
- private int senderPort;
- private int messageTypeLength;
- private String messageType;
- private int contentLength;
-
- public MessageDecoder(int correctPreamble) {
- super(DecoderState.READ_MESSAGE_PREAMBLE);
- this.correctPreamble = correctPreamble;
- }
-
- @Override
- protected void decode(
- ChannelHandlerContext context,
- ByteBuf buffer,
- List<Object> out) throws Exception {
-
- switch (state()) {
- case READ_MESSAGE_PREAMBLE:
- preamble = buffer.readInt();
- if (preamble != correctPreamble) {
- throw new IllegalStateException("This message had an incorrect preamble.");
- }
- checkpoint(DecoderState.READ_MESSAGE_ID);
- case READ_MESSAGE_ID:
- messageId = buffer.readLong();
- checkpoint(DecoderState.READ_SENDER_IP_VERSION);
- case READ_SENDER_IP_VERSION:
- ipVersion = buffer.readByte() == 0x0 ? Version.INET : Version.INET6;
- checkpoint(DecoderState.READ_SENDER_IP);
- case READ_SENDER_IP:
- byte[] octets = new byte[IpAddress.byteLength(ipVersion)];
- buffer.readBytes(octets);
- senderIp = IpAddress.valueOf(ipVersion, octets);
- checkpoint(DecoderState.READ_SENDER_PORT);
- case READ_SENDER_PORT:
- senderPort = buffer.readInt();
- checkpoint(DecoderState.READ_MESSAGE_TYPE_LENGTH);
- case READ_MESSAGE_TYPE_LENGTH:
- messageTypeLength = buffer.readInt();
- checkpoint(DecoderState.READ_MESSAGE_TYPE);
- case READ_MESSAGE_TYPE:
- byte[] messageTypeBytes = new byte[messageTypeLength];
- buffer.readBytes(messageTypeBytes);
- messageType = new String(messageTypeBytes, Charsets.UTF_8);
- checkpoint(DecoderState.READ_CONTENT_LENGTH);
- case READ_CONTENT_LENGTH:
- contentLength = buffer.readInt();
- checkpoint(DecoderState.READ_CONTENT);
- case READ_CONTENT:
- //TODO Perform a sanity check on the size before allocating
- byte[] payload = new byte[contentLength];
- buffer.readBytes(payload);
- InternalMessage message = new InternalMessage(messageId,
- new Endpoint(senderIp, senderPort),
- messageType,
- payload);
- out.add(message);
- checkpoint(DecoderState.READ_MESSAGE_PREAMBLE);
- break;
- default:
- checkState(false, "Must not be here");
- }
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
- log.error("Exception inside channel handling pipeline.", cause);
- context.close();
- }
-}
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageEncoder.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageEncoder.java
deleted file mode 100644
index c74c1de9..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/MessageEncoder.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.netty;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-
-import java.io.IOException;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onosproject.store.cluster.messaging.Endpoint;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-
-/**
- * Encode InternalMessage out into a byte buffer.
- */
-@Sharable
-public class MessageEncoder extends MessageToByteEncoder<InternalMessage> {
-
- private final int preamble;
-
- public MessageEncoder(int preamble) {
- super();
- this.preamble = preamble;
- }
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Override
- protected void encode(
- ChannelHandlerContext context,
- InternalMessage message,
- ByteBuf out) throws Exception {
-
- out.writeInt(this.preamble);
-
- // write message id
- out.writeLong(message.id());
-
- Endpoint sender = message.sender();
-
- IpAddress senderIp = sender.host();
- if (senderIp.version() == Version.INET) {
- out.writeByte(0);
- } else {
- out.writeByte(1);
- }
- out.writeBytes(senderIp.toOctets());
-
- // write sender port
- out.writeInt(sender.port());
-
- byte[] messageTypeBytes = message.type().getBytes(Charsets.UTF_8);
-
- // write length of message type
- out.writeInt(messageTypeBytes.length);
-
- // write message type bytes
- out.writeBytes(messageTypeBytes);
-
- byte[] payload = message.payload();
-
- // write payload length
- out.writeInt(payload.length);
-
- // write payload.
- out.writeBytes(payload);
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
- if (cause instanceof IOException) {
- log.debug("IOException inside channel handling pipeline.", cause);
- } else {
- log.error("non-IOException inside channel handling pipeline.", cause);
- }
- context.close();
- }
-}
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/NettyMessaging.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/NettyMessaging.java
deleted file mode 100644
index 2dda747d..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/NettyMessaging.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.netty;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.buffer.PooledByteBufAllocator;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.ServerChannel;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.epoll.EpollServerSocketChannel;
-import io.netty.channel.epoll.EpollSocketChannel;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import org.apache.commons.pool.KeyedPoolableObjectFactory;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool;
-import org.onosproject.store.cluster.messaging.Endpoint;
-import org.onosproject.store.cluster.messaging.MessagingService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.TrustManagerFactory;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * Implementation of MessagingService based on <a href="http://netty.io/">Netty</a> framework.
- */
-public class NettyMessaging implements MessagingService {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private static final String REPLY_MESSAGE_TYPE = "NETTY_MESSAGING_REQUEST_REPLY";
-
- private Endpoint localEp;
- private int preamble;
- private final AtomicBoolean started = new AtomicBoolean(false);
- private final Map<String, Consumer<InternalMessage>> handlers = new ConcurrentHashMap<>();
- private final AtomicLong messageIdGenerator = new AtomicLong(0);
- private final Cache<Long, CompletableFuture<byte[]>> responseFutures = CacheBuilder.newBuilder()
- .expireAfterWrite(10, TimeUnit.SECONDS)
- .removalListener(new RemovalListener<Long, CompletableFuture<byte[]>>() {
- @Override
- public void onRemoval(RemovalNotification<Long, CompletableFuture<byte[]>> entry) {
- if (entry.wasEvicted()) {
- entry.getValue().completeExceptionally(new TimeoutException("Timedout waiting for reply"));
- }
- }
- })
- .build();
-
- private final GenericKeyedObjectPool<Endpoint, Channel> channels
- = new GenericKeyedObjectPool<Endpoint, Channel>(new OnosCommunicationChannelFactory());
-
- private EventLoopGroup serverGroup;
- private EventLoopGroup clientGroup;
- private Class<? extends ServerChannel> serverChannelClass;
- private Class<? extends Channel> clientChannelClass;
-
- protected static final boolean TLS_DISABLED = false;
- protected boolean enableNettyTls = TLS_DISABLED;
-
- protected String ksLocation;
- protected String tsLocation;
- protected char[] ksPwd;
- protected char[] tsPwd;
-
- private void initEventLoopGroup() {
- // try Epoll first and if that does work, use nio.
- try {
- clientGroup = new EpollEventLoopGroup();
- serverGroup = new EpollEventLoopGroup();
- serverChannelClass = EpollServerSocketChannel.class;
- clientChannelClass = EpollSocketChannel.class;
- return;
- } catch (Throwable e) {
- log.debug("Failed to initialize native (epoll) transport. "
- + "Reason: {}. Proceeding with nio.", e.getMessage());
- }
- clientGroup = new NioEventLoopGroup();
- serverGroup = new NioEventLoopGroup();
- serverChannelClass = NioServerSocketChannel.class;
- clientChannelClass = NioSocketChannel.class;
- }
-
- public void start(int preamble, Endpoint localEp) throws Exception {
- if (started.get()) {
- log.warn("Already running at local endpoint: {}", localEp);
- return;
- }
- this.preamble = preamble;
- this.localEp = localEp;
- channels.setLifo(true);
- channels.setTestOnBorrow(true);
- channels.setTestOnReturn(true);
- channels.setMinEvictableIdleTimeMillis(60_000L);
- channels.setTimeBetweenEvictionRunsMillis(30_000L);
- initEventLoopGroup();
- startAcceptingConnections();
- started.set(true);
- }
-
- public void stop() throws Exception {
- if (started.get()) {
- channels.close();
- serverGroup.shutdownGracefully();
- clientGroup.shutdownGracefully();
- started.set(false);
- }
- }
-
- @Override
- public CompletableFuture<Void> sendAsync(Endpoint ep, String type, byte[] payload) {
- InternalMessage message = new InternalMessage(messageIdGenerator.incrementAndGet(),
- localEp,
- type,
- payload);
- return sendAsync(ep, message);
- }
-
- protected CompletableFuture<Void> sendAsync(Endpoint ep, InternalMessage message) {
- CompletableFuture<Void> future = new CompletableFuture<>();
- try {
- if (ep.equals(localEp)) {
- dispatchLocally(message);
- future.complete(null);
- } else {
- Channel channel = null;
- try {
- channel = channels.borrowObject(ep);
- channel.writeAndFlush(message).addListener(channelFuture -> {
- if (!channelFuture.isSuccess()) {
- future.completeExceptionally(channelFuture.cause());
- } else {
- future.complete(null);
- }
- });
- } finally {
- channels.returnObject(ep, channel);
- }
- }
- } catch (Exception e) {
- future.completeExceptionally(e);
- }
- return future;
- }
-
- @Override
- public CompletableFuture<byte[]> sendAndReceive(Endpoint ep, String type, byte[] payload) {
- CompletableFuture<byte[]> response = new CompletableFuture<>();
- Long messageId = messageIdGenerator.incrementAndGet();
- responseFutures.put(messageId, response);
- InternalMessage message = new InternalMessage(messageId, localEp, type, payload);
- try {
- sendAsync(ep, message);
- } catch (Exception e) {
- responseFutures.invalidate(messageId);
- response.completeExceptionally(e);
- }
- return response;
- }
-
- @Override
- public void registerHandler(String type, Consumer<byte[]> handler, Executor executor) {
- handlers.put(type, message -> executor.execute(() -> handler.accept(message.payload())));
- }
-
- @Override
- public void registerHandler(String type, Function<byte[], byte[]> handler, Executor executor) {
- handlers.put(type, message -> executor.execute(() -> {
- byte[] responsePayload = handler.apply(message.payload());
- if (responsePayload != null) {
- InternalMessage response = new InternalMessage(message.id(),
- localEp,
- REPLY_MESSAGE_TYPE,
- responsePayload);
- sendAsync(message.sender(), response).whenComplete((result, error) -> {
- if (error != null) {
- log.debug("Failed to respond", error);
- }
- });
- }
- }));
- }
-
- @Override
- public void registerHandler(String type, Function<byte[], CompletableFuture<byte[]>> handler) {
- handlers.put(type, message -> {
- handler.apply(message.payload()).whenComplete((result, error) -> {
- if (error == null) {
- InternalMessage response = new InternalMessage(message.id(),
- localEp,
- REPLY_MESSAGE_TYPE,
- result);
- sendAsync(message.sender(), response).whenComplete((r, e) -> {
- if (e != null) {
- log.debug("Failed to respond", e);
- }
- });
- }
- });
- });
- }
-
- @Override
- public void unregisterHandler(String type) {
- handlers.remove(type);
- }
-
- private void startAcceptingConnections() throws InterruptedException {
- ServerBootstrap b = new ServerBootstrap();
- b.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024);
- b.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 8 * 1024);
- b.option(ChannelOption.SO_RCVBUF, 1048576);
- b.option(ChannelOption.TCP_NODELAY, true);
- b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
- b.group(serverGroup, clientGroup);
- b.channel(serverChannelClass);
- if (enableNettyTls) {
- b.childHandler(new SslServerCommunicationChannelInitializer());
- } else {
- b.childHandler(new OnosCommunicationChannelInitializer());
- }
- b.option(ChannelOption.SO_BACKLOG, 128);
- b.childOption(ChannelOption.SO_KEEPALIVE, true);
-
- // Bind and start to accept incoming connections.
- b.bind(localEp.port()).sync().addListener(future -> {
- if (future.isSuccess()) {
- log.info("{} accepting incoming connections on port {}", localEp.host(), localEp.port());
- } else {
- log.warn("{} failed to bind to port {}", localEp.host(), localEp.port(), future.cause());
- }
- });
- }
-
- private class OnosCommunicationChannelFactory
- implements KeyedPoolableObjectFactory<Endpoint, Channel> {
-
- @Override
- public void activateObject(Endpoint endpoint, Channel channel)
- throws Exception {
- }
-
- @Override
- public void destroyObject(Endpoint ep, Channel channel) throws Exception {
- log.debug("Closing connection to {}", ep);
- channel.close();
- }
-
- @Override
- public Channel makeObject(Endpoint ep) throws Exception {
- Bootstrap bootstrap = new Bootstrap();
- bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
- bootstrap.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 10 * 64 * 1024);
- bootstrap.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 10 * 32 * 1024);
- bootstrap.option(ChannelOption.SO_SNDBUF, 1048576);
- bootstrap.group(clientGroup);
- // TODO: Make this faster:
- // http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#37.0
- bootstrap.channel(clientChannelClass);
- bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
- if (enableNettyTls) {
- bootstrap.handler(new SslClientCommunicationChannelInitializer());
- } else {
- bootstrap.handler(new OnosCommunicationChannelInitializer());
- }
- // Start the client.
- ChannelFuture f = bootstrap.connect(ep.host().toString(), ep.port()).sync();
- log.debug("Established a new connection to {}", ep);
- return f.channel();
- }
-
- @Override
- public void passivateObject(Endpoint ep, Channel channel)
- throws Exception {
- }
-
- @Override
- public boolean validateObject(Endpoint ep, Channel channel) {
- return channel.isOpen();
- }
- }
-
- private class SslServerCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> {
-
- private final ChannelHandler dispatcher = new InboundMessageDispatcher();
- private final ChannelHandler encoder = new MessageEncoder(preamble);
-
- @Override
- protected void initChannel(SocketChannel channel) throws Exception {
- TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- KeyStore ts = KeyStore.getInstance("JKS");
- ts.load(new FileInputStream(tsLocation), tsPwd);
- tmFactory.init(ts);
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream(ksLocation), ksPwd);
- kmf.init(ks, ksPwd);
-
- SSLContext serverContext = SSLContext.getInstance("TLS");
- serverContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null);
-
- SSLEngine serverSslEngine = serverContext.createSSLEngine();
-
- serverSslEngine.setNeedClientAuth(true);
- serverSslEngine.setUseClientMode(false);
- serverSslEngine.setEnabledProtocols(serverSslEngine.getSupportedProtocols());
- serverSslEngine.setEnabledCipherSuites(serverSslEngine.getSupportedCipherSuites());
- serverSslEngine.setEnableSessionCreation(true);
-
- channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(serverSslEngine))
- .addLast("encoder", encoder)
- .addLast("decoder", new MessageDecoder(preamble))
- .addLast("handler", dispatcher);
- }
-
- }
-
- private class SslClientCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> {
-
- private final ChannelHandler dispatcher = new InboundMessageDispatcher();
- private final ChannelHandler encoder = new MessageEncoder(preamble);
-
- @Override
- protected void initChannel(SocketChannel channel) throws Exception {
- TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- KeyStore ts = KeyStore.getInstance("JKS");
- ts.load(new FileInputStream(tsLocation), tsPwd);
- tmFactory.init(ts);
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream(ksLocation), ksPwd);
- kmf.init(ks, ksPwd);
-
- SSLContext clientContext = SSLContext.getInstance("TLS");
- clientContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null);
-
- SSLEngine clientSslEngine = clientContext.createSSLEngine();
-
- clientSslEngine.setUseClientMode(true);
- clientSslEngine.setEnabledProtocols(clientSslEngine.getSupportedProtocols());
- clientSslEngine.setEnabledCipherSuites(clientSslEngine.getSupportedCipherSuites());
- clientSslEngine.setEnableSessionCreation(true);
-
- channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(clientSslEngine))
- .addLast("encoder", encoder)
- .addLast("decoder", new MessageDecoder(preamble))
- .addLast("handler", dispatcher);
- }
-
- }
-
- private class OnosCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> {
-
- private final ChannelHandler dispatcher = new InboundMessageDispatcher();
- private final ChannelHandler encoder = new MessageEncoder(preamble);
-
- @Override
- protected void initChannel(SocketChannel channel) throws Exception {
- channel.pipeline()
- .addLast("encoder", encoder)
- .addLast("decoder", new MessageDecoder(preamble))
- .addLast("handler", dispatcher);
- }
- }
-
- @ChannelHandler.Sharable
- private class InboundMessageDispatcher extends SimpleChannelInboundHandler<InternalMessage> {
-
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, InternalMessage message) throws Exception {
- try {
- dispatchLocally(message);
- } catch (RejectedExecutionException e) {
- log.warn("Unable to dispatch message due to {}", e.getMessage());
- }
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
- log.error("Exception inside channel handling pipeline.", cause);
- context.close();
- }
- }
- private void dispatchLocally(InternalMessage message) throws IOException {
- String type = message.type();
- if (REPLY_MESSAGE_TYPE.equals(type)) {
- try {
- CompletableFuture<byte[]> futureResponse =
- responseFutures.getIfPresent(message.id());
- if (futureResponse != null) {
- futureResponse.complete(message.payload());
- } else {
- log.warn("Received a reply for message id:[{}]. "
- + " from {}. But was unable to locate the"
- + " request handle", message.id(), message.sender());
- }
- } finally {
- responseFutures.invalidate(message.id());
- }
- return;
- }
- Consumer<InternalMessage> handler = handlers.get(type);
- if (handler != null) {
- handler.accept(message);
- } else {
- log.debug("No handler registered for {}", type);
- }
- }
-}
diff --git a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/package-info.java b/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/package-info.java
deleted file mode 100644
index 2d6257ff..00000000
--- a/framework/src/onos/utils/netty/src/main/java/org/onlab/netty/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Asynchronous messaging APIs implemented using the Netty framework.
- */
-package org.onlab.netty;
diff --git a/framework/src/onos/utils/nio/pom.xml b/framework/src/onos/utils/nio/pom.xml
deleted file mode 100644
index b92c9b7b..00000000
--- a/framework/src/onos/utils/nio/pom.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-nio</artifactId>
- <packaging>bundle</packaging>
-
- <description>Fast network I/O using Java NIO</description>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-pool</groupId>
- <artifactId>commons-pool</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-misc</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AbstractMessage.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AbstractMessage.java
deleted file mode 100644
index 16bb9359..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AbstractMessage.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-/**
- * Base {@link Message} implementation.
- */
-public abstract class AbstractMessage implements Message {
-
- protected int length;
-
- @Override
- public int length() {
- return length;
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AcceptorLoop.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AcceptorLoop.java
deleted file mode 100644
index e416f3be..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/AcceptorLoop.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.net.StandardSocketOptions;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ServerSocketChannel;
-import java.util.Iterator;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Selector loop derivative tailored to acceptConnection inbound connections.
- */
-public abstract class AcceptorLoop extends SelectorLoop {
-
- private SocketAddress listenAddress;
- private ServerSocketChannel socketChannel;
-
- /**
- * Creates an acceptor loop with the specified selection timeout and
- * accepting connections on the the given address.
- *
- * @param selectTimeout selection timeout; specified in millis
- * @param listenAddress socket address where to listen for connections
- * @throws IOException if the backing selector cannot be opened
- */
- public AcceptorLoop(long selectTimeout, SocketAddress listenAddress)
- throws IOException {
- super(selectTimeout);
- this.listenAddress = checkNotNull(listenAddress, "Address cannot be null");
- }
-
- /**
- * Hook to accept an inbound connection on the specified socket channel.
- *
- * @param channel socketChannel where an accept operation awaits
- * @throws IOException if the accept operation cannot be processed
- */
- protected abstract void acceptConnection(ServerSocketChannel channel) throws IOException;
-
- /**
- * Opens a new server socket channel configured in non-blocking mode and
- * bound to the loop's listen address.
- *
- * @throws IOException if unable to open or configure the socket channel
- */
- protected synchronized void openChannel() throws IOException {
- socketChannel = ServerSocketChannel.open();
- socketChannel.configureBlocking(false);
- socketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
- socketChannel.register(selector, SelectionKey.OP_ACCEPT);
- socketChannel.bind(listenAddress);
- }
-
- /**
- * Closes the server socket channel.
- *
- * @throws IOException if unable to close the socketChannel
- */
- protected synchronized void closechannel() throws IOException {
- if (socketChannel != null) {
- socketChannel.close();
- socketChannel = null;
- }
- }
-
- @Override
- public void shutdown() {
- try {
- closechannel();
- } catch (IOException e) {
- log.warn("Unable to close the socketChannel", e);
- }
- super.shutdown();
- }
-
- @Override
- protected void loop() throws IOException {
- openChannel();
- notifyReady();
-
- // Keep looping until told otherwise.
- while (isRunning()) {
- // Attempt a selection; if no operations selected or if signalled
- // to shutdown, spin through.
- int count = selector.select(selectTimeout);
- if (count == 0 || !isRunning()) {
- continue;
- }
-
- // Iterate over all keys selected for an operation and process them.
- Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
- while (keys.hasNext()) {
- // Fetch the key and remove it from the pending list.
- SelectionKey key = keys.next();
- keys.remove();
-
- // If the key has a pending acceptConnection operation, process it.
- if (key.isAcceptable()) {
- acceptConnection((ServerSocketChannel) key.channel());
- }
- }
- }
- }
-
-}
-
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/IOLoop.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/IOLoop.java
deleted file mode 100644
index 106df7b2..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/IOLoop.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import java.io.IOException;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.CancelledKeyException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-/**
- * I/O loop for driving inbound &amp; outbound {@link Message} transfer via
- * {@link MessageStream}.
- *
- * @param <M> message type
- * @param <S> message stream type
- */
-public abstract class IOLoop<M extends Message, S extends MessageStream<M>>
- extends SelectorLoop {
-
- // Queue of requests for new message streams to enter the IO loop processing.
- private final Queue<NewStreamRequest> newStreamRequests = new ConcurrentLinkedQueue<>();
-
- // Carries information required for admitting a new message stream.
- private class NewStreamRequest {
- private final S stream;
- private final SelectableChannel channel;
- private final int op;
-
- public NewStreamRequest(S stream, SelectableChannel channel, int op) {
- this.stream = stream;
- this.channel = channel;
- this.op = op;
- }
- }
-
- // Set of message streams currently admitted into the IO loop.
- private final Set<MessageStream<M>> streams = new CopyOnWriteArraySet<>();
-
- /**
- * Creates an IO loop with the given selection timeout.
- *
- * @param timeout selection timeout in milliseconds
- * @throws IOException if the backing selector cannot be opened
- */
- public IOLoop(long timeout) throws IOException {
- super(timeout);
- }
-
- /**
- * Returns the number of message stream in custody of the loop.
- *
- * @return number of message streams
- */
- public int streamCount() {
- return streams.size();
- }
-
- /**
- * Creates a new message stream backed by the specified socket channel.
- *
- * @param byteChannel backing byte channel
- * @return newly created message stream
- */
- protected abstract S createStream(ByteChannel byteChannel);
-
- /**
- * Removes the specified message stream from the IO loop.
- *
- * @param stream message stream to remove
- */
- protected void removeStream(MessageStream<M> stream) {
- streams.remove(stream);
- }
-
- /**
- * Processes the list of messages extracted from the specified message
- * stream.
- *
- * @param messages non-empty list of received messages
- * @param stream message stream from which the messages were extracted
- */
- protected abstract void processMessages(List<M> messages, MessageStream<M> stream);
-
- /**
- * Completes connection request pending on the given selection key.
- *
- * @param key selection key holding the pending connect operation.
- * @throws IOException when I/O exception of some sort has occurred
- */
- protected void connect(SelectionKey key) throws IOException {
- SocketChannel ch = (SocketChannel) key.channel();
- ch.finishConnect();
- if (key.isValid()) {
- key.interestOps(SelectionKey.OP_READ);
- }
- }
-
- /**
- * Processes an IO operation pending on the specified key.
- *
- * @param key selection key holding the pending I/O operation.
- */
- protected void processKeyOperation(SelectionKey key) {
- @SuppressWarnings("unchecked")
- S stream = (S) key.attachment();
-
- try {
- // If the key is not valid, bail out.
- if (!key.isValid()) {
- stream.close();
- return;
- }
-
- // If there is a pending connect operation, complete it.
- if (key.isConnectable()) {
- try {
- connect(key);
- } catch (IOException | IllegalStateException e) {
- log.warn("Unable to complete connection", e);
- }
- }
-
- // If there is a read operation, slurp as much data as possible.
- if (key.isReadable()) {
- List<M> messages = stream.read();
-
- // No messages or failed flush imply disconnect; bail.
- if (messages == null || stream.hadError()) {
- stream.close();
- return;
- }
-
- // If there were any messages read, process them.
- if (!messages.isEmpty()) {
- try {
- processMessages(messages, stream);
- } catch (RuntimeException e) {
- onError(stream, e);
- }
- }
- }
-
- // If there are pending writes, flush them
- if (key.isWritable()) {
- stream.flushIfPossible();
- }
-
- // If there were any issued flushing, close the stream.
- if (stream.hadError()) {
- stream.close();
- }
-
- } catch (CancelledKeyException e) {
- // Key was cancelled, so silently close the stream
- stream.close();
- } catch (IOException e) {
- if (!stream.isClosed() && !isResetByPeer(e)) {
- log.warn("Unable to process IO", e);
- }
- stream.close();
- }
- }
-
- // Indicates whether or not this exception is caused by 'reset by peer'.
- private boolean isResetByPeer(IOException e) {
- Throwable cause = e.getCause();
- return cause != null && cause instanceof IOException &&
- cause.getMessage().contains("reset by peer");
- }
-
- /**
- * Hook to allow intercept of any errors caused during message processing.
- * Default behaviour is to rethrow the error.
- *
- * @param stream message stream involved in the error
- * @param error the runtime exception
- */
- protected void onError(S stream, RuntimeException error) {
- throw error;
- }
-
- /**
- * Admits a new message stream backed by the specified socket channel
- * with a pending accept operation.
- *
- * @param channel backing socket channel
- * @return newly accepted message stream
- */
- public S acceptStream(SocketChannel channel) {
- return createAndAdmit(channel, SelectionKey.OP_READ);
- }
-
-
- /**
- * Admits a new message stream backed by the specified socket channel
- * with a pending connect operation.
- *
- * @param channel backing socket channel
- * @return newly connected message stream
- */
- public S connectStream(SocketChannel channel) {
- return createAndAdmit(channel, SelectionKey.OP_CONNECT);
- }
-
- /**
- * Creates a new message stream backed by the specified socket channel
- * and admits it into the IO loop.
- *
- * @param channel socket channel
- * @param op pending operations mask to be applied to the selection
- * key as a set of initial interestedOps
- * @return newly created message stream
- */
- private synchronized S createAndAdmit(SocketChannel channel, int op) {
- S stream = createStream(channel);
- streams.add(stream);
- newStreamRequests.add(new NewStreamRequest(stream, channel, op));
- selector.wakeup();
- return stream;
- }
-
- /**
- * Safely admits new streams into the IO loop.
- */
- private void admitNewStreams() {
- Iterator<NewStreamRequest> it = newStreamRequests.iterator();
- while (isRunning() && it.hasNext()) {
- try {
- NewStreamRequest request = it.next();
- it.remove();
- SelectionKey key = request.channel.register(selector, request.op,
- request.stream);
- request.stream.setKey(key);
- } catch (ClosedChannelException e) {
- log.warn("Unable to admit new message stream", e);
- }
- }
- }
-
- @Override
- protected void loop() throws IOException {
- notifyReady();
-
- // Keep going until told otherwise.
- while (isRunning()) {
- admitNewStreams();
-
- // Process flushes & write selects on all streams
- for (MessageStream<M> stream : streams) {
- stream.flushIfWriteNotPending();
- }
-
- // Select keys and process them.
- int count = selector.select(selectTimeout);
- if (count > 0 && isRunning()) {
- Iterator<SelectionKey> it = selector.selectedKeys().iterator();
- while (it.hasNext()) {
- SelectionKey key = it.next();
- it.remove();
- processKeyOperation(key);
- }
- }
- }
- }
-
- /**
- * Prunes the registered streams by discarding any stale ones.
- *
- * @return number of remaining streams
- */
- public synchronized int pruneStaleStreams() {
- for (MessageStream<M> stream : streams) {
- if (stream.isStale()) {
- stream.close();
- }
- }
- return streams.size();
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/Message.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/Message.java
deleted file mode 100644
index c1a339e0..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/Message.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-/**
- * Representation of a message transferred via {@link MessageStream}.
- */
-public interface Message {
-
- /**
- * Gets the message length in bytes.
- *
- * @return number of bytes
- */
- int length();
-
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/MessageStream.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/MessageStream.java
deleted file mode 100644
index a19e8aac..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/MessageStream.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.onlab.util.Counter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.SelectionKey;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.System.currentTimeMillis;
-import static java.nio.ByteBuffer.allocateDirect;
-
-/**
- * Bi-directional message stream for transferring messages to &amp; from the
- * network via two byte buffers.
- *
- * @param <M> message type
- */
-public abstract class MessageStream<M extends Message> {
-
- protected Logger log = LoggerFactory.getLogger(getClass());
-
- private final IOLoop<M, ?> loop;
- private final ByteChannel channel;
- private final int maxIdleMillis;
-
- private final ByteBuffer inbound;
- private ByteBuffer outbound;
- private SelectionKey key;
-
- private volatile boolean closed = false;
- private volatile boolean writePending;
- private volatile boolean writeOccurred;
-
- private Exception ioError;
- private long lastActiveTime;
-
- private final Counter bytesIn = new Counter();
- private final Counter messagesIn = new Counter();
- private final Counter bytesOut = new Counter();
- private final Counter messagesOut = new Counter();
-
- /**
- * Creates a message stream associated with the specified IO loop and
- * backed by the given byte channel.
- *
- * @param loop IO loop
- * @param byteChannel backing byte channel
- * @param bufferSize size of the backing byte buffers
- * @param maxIdleMillis maximum number of millis the stream can be idle
- * before it will be closed
- */
- protected MessageStream(IOLoop<M, ?> loop, ByteChannel byteChannel,
- int bufferSize, int maxIdleMillis) {
- this.loop = checkNotNull(loop, "Loop cannot be null");
- this.channel = checkNotNull(byteChannel, "Byte channel cannot be null");
-
- checkArgument(maxIdleMillis > 0, "Idle time must be positive");
- this.maxIdleMillis = maxIdleMillis;
-
- inbound = allocateDirect(bufferSize);
- outbound = allocateDirect(bufferSize);
- }
-
- /**
- * Gets a single message from the specified byte buffer; this is
- * to be done without manipulating the buffer via flip, reset or clear.
- *
- * @param buffer byte buffer
- * @return read message or null if there are not enough bytes to read
- * a complete message
- */
- protected abstract M read(ByteBuffer buffer);
-
- /**
- * Puts the specified message into the specified byte buffer; this is
- * to be done without manipulating the buffer via flip, reset or clear.
- *
- * @param message message to be write into the buffer
- * @param buffer byte buffer
- */
- protected abstract void write(M message, ByteBuffer buffer);
-
- /**
- * Closes the message buffer.
- */
- public void close() {
- synchronized (this) {
- if (closed) {
- return;
- }
- closed = true;
- }
-
- bytesIn.freeze();
- bytesOut.freeze();
- messagesIn.freeze();
- messagesOut.freeze();
-
- loop.removeStream(this);
- if (key != null) {
- try {
- key.cancel();
- key.channel().close();
- } catch (IOException e) {
- log.warn("Unable to close stream", e);
- }
- }
- }
-
- /**
- * Indicates whether this buffer has been closed.
- *
- * @return true if this stream has been closed
- */
- public synchronized boolean isClosed() {
- return closed;
- }
-
- /**
- * Returns the stream IO selection key.
- *
- * @return socket channel registration selection key
- */
- public SelectionKey key() {
- return key;
- }
-
- /**
- * Binds the selection key to be used for driving IO operations on the stream.
- *
- * @param key IO selection key
- */
- public void setKey(SelectionKey key) {
- this.key = key;
- this.lastActiveTime = currentTimeMillis();
- }
-
- /**
- * Returns the IO loop to which this stream is bound.
- *
- * @return I/O loop used to drive this stream
- */
- public IOLoop<M, ?> loop() {
- return loop;
- }
-
- /**
- * Indicates whether the any prior IO encountered an error.
- *
- * @return true if a write failed
- */
- public boolean hadError() {
- return ioError != null;
- }
-
- /**
- * Gets the prior IO error, if one occurred.
- *
- * @return IO error; null if none occurred
- */
- public Exception getError() {
- return ioError;
- }
-
- /**
- * Reads, without blocking, a list of messages from the stream.
- * The list will be empty if there were not messages pending.
- *
- * @return list of messages or null if backing channel has been closed
- * @throws IOException if messages could not be read
- */
- public List<M> read() throws IOException {
- try {
- int read = channel.read(inbound);
- if (read != -1) {
- // Read the messages one-by-one and add them to the list.
- List<M> messages = new ArrayList<>();
- M message;
- inbound.flip();
- while ((message = read(inbound)) != null) {
- messages.add(message);
- messagesIn.add(1);
- bytesIn.add(message.length());
- }
- inbound.compact();
-
- // Mark the stream with current time to indicate liveness.
- lastActiveTime = currentTimeMillis();
- return messages;
- }
- return null;
-
- } catch (Exception e) {
- throw new IOException("Unable to read messages", e);
- }
- }
-
- /**
- * Writes the specified list of messages to the stream.
- *
- * @param messages list of messages to write
- * @throws IOException if error occurred while writing the data
- */
- public void write(List<M> messages) throws IOException {
- synchronized (this) {
- // First write all messages.
- for (M m : messages) {
- append(m);
- }
- flushUnlessAlreadyPlanningTo();
- }
- }
-
- /**
- * Writes the given message to the stream.
- *
- * @param message message to write
- * @throws IOException if error occurred while writing the data
- */
- public void write(M message) throws IOException {
- synchronized (this) {
- append(message);
- flushUnlessAlreadyPlanningTo();
- }
- }
-
- // Appends the specified message into the internal buffer, growing the
- // buffer if required.
- private void append(M message) {
- // If the buffer does not have sufficient length double it.
- while (outbound.remaining() < message.length()) {
- doubleSize();
- }
- write(message, outbound);
- messagesOut.add(1);
- bytesOut.add(message.length());
- }
-
- // Forces a flush, unless one is planned already.
- private void flushUnlessAlreadyPlanningTo() throws IOException {
- if (!writeOccurred && !writePending) {
- flush();
- }
- }
-
- /**
- * Flushes any pending writes.
- *
- * @throws IOException if flush failed
- */
- public void flush() throws IOException {
- synchronized (this) {
- if (!writeOccurred && !writePending) {
- outbound.flip();
- try {
- channel.write(outbound);
- } catch (IOException e) {
- if (!closed && !Objects.equals(e.getMessage(), "Broken pipe")) {
- log.warn("Unable to write data", e);
- ioError = e;
- }
- }
- lastActiveTime = currentTimeMillis();
- writeOccurred = true;
- writePending = outbound.hasRemaining();
- outbound.compact();
- }
- }
- }
-
- /**
- * Indicates whether the stream has bytes to be written to the channel.
- *
- * @return true if there are bytes to be written
- */
- boolean isWritePending() {
- synchronized (this) {
- return writePending;
- }
- }
-
-
- /**
- * Indicates whether data has been written but not flushed yet.
- *
- * @return true if flush is required
- */
- boolean isFlushRequired() {
- synchronized (this) {
- return outbound.position() > 0;
- }
- }
-
- /**
- * Attempts to flush data, internal stream state and channel availability
- * permitting. Invoked by the driver I/O loop during handling of writable
- * selection key.
- * <p>
- * Resets the internal state flags {@code writeOccurred} and
- * {@code writePending}.
- * </p>
- * @throws IOException if implicit flush failed
- */
- void flushIfPossible() throws IOException {
- synchronized (this) {
- writePending = false;
- writeOccurred = false;
- if (outbound.position() > 0) {
- flush();
- }
- }
- key.interestOps(SelectionKey.OP_READ);
- }
-
- /**
- * Attempts to flush data, internal stream state and channel availability
- * permitting and if other writes are not pending. Invoked by the driver
- * I/O loop prior to entering select wait. Resets the internal
- * {@code writeOccurred} state flag.
- *
- * @throws IOException if implicit flush failed
- */
- void flushIfWriteNotPending() throws IOException {
- synchronized (this) {
- writeOccurred = false;
- if (!writePending && outbound.position() > 0) {
- flush();
- }
- }
- if (isWritePending()) {
- key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
- }
- }
-
- /**
- * Doubles the size of the outbound buffer.
- */
- private void doubleSize() {
- ByteBuffer newBuffer = allocateDirect(outbound.capacity() * 2);
- outbound.flip();
- newBuffer.put(outbound);
- outbound = newBuffer;
- }
-
- /**
- * Returns the maximum number of milliseconds the stream is allowed
- * without any read/write operations.
- *
- * @return number if millis of permissible idle time
- */
- protected int maxIdleMillis() {
- return maxIdleMillis;
- }
-
-
- /**
- * Returns true if the given stream has gone stale.
- *
- * @return true if the stream is stale
- */
- boolean isStale() {
- return currentTimeMillis() - lastActiveTime > maxIdleMillis() && key != null;
- }
-
- /**
- * Returns the inbound bytes counter.
- *
- * @return inbound bytes counter
- */
- public Counter bytesIn() {
- return bytesIn;
- }
-
- /**
- * Returns the outbound bytes counter.
- *
- * @return outbound bytes counter
- */
- public Counter bytesOut() {
- return bytesOut;
- }
-
- /**
- * Returns the inbound messages counter.
- *
- * @return inbound messages counter
- */
- public Counter messagesIn() {
- return messagesIn;
- }
-
- /**
- * Returns the outbound messages counter.
- *
- * @return outbound messages counter
- */
- public Counter messagesOut() {
- return messagesOut;
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/SelectorLoop.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/SelectorLoop.java
deleted file mode 100644
index 95a9b61e..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/SelectorLoop.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.nio.channels.Selector;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.lang.System.currentTimeMillis;
-
-/**
- * Abstraction of an I/O processing loop based on an NIO selector.
- */
-public abstract class SelectorLoop implements Runnable {
-
- protected final Logger log = LoggerFactory.getLogger(getClass());
-
- /**
- * Selector used by this loop to pace the I/O operations.
- */
- protected final Selector selector;
-
- /**
- * Selection operations timeout; specified in millis.
- */
- protected long selectTimeout;
-
- /**
- * Retains the error that caused the loop to exit prematurely.
- */
- private Throwable error;
-
- // State indicator
- private enum State { STARTING, STARTED, STOPPING, STOPPED };
- private volatile State state = State.STOPPED;
-
- /**
- * Creates a new selector loop with the given selection timeout.
- *
- * @param selectTimeout selection timeout; specified in millis
- * @throws IOException if the backing selector cannot be opened
- */
- public SelectorLoop(long selectTimeout) throws IOException {
- checkArgument(selectTimeout > 0, "Timeout must be positive");
- this.selectTimeout = selectTimeout;
- this.selector = openSelector();
- }
-
- /**
- * Opens a new selector for the use by the loop.
- *
- * @return newly open selector
- * @throws IOException if the backing selector cannot be opened
- */
- protected Selector openSelector() throws IOException {
- return Selector.open();
- }
-
- /**
- * Indicates that the loop is marked to run.
- * @return true if the loop is marked to run
- */
- protected boolean isRunning() {
- return state == State.STARTED || state == State.STARTING;
- }
-
- /**
- * Returns the error, if there was one, that caused the loop to terminate
- * prematurely.
- *
- * @return error or null if there was none
- */
- public Throwable getError() {
- return error;
- }
-
- /**
- * Contains the body of the I/O selector loop.
- *
- * @throws IOException if an error is encountered while selecting I/O
- */
- protected abstract void loop() throws IOException;
-
- @Override
- public void run() {
- error = null;
- state = State.STARTING;
- try {
- loop();
- } catch (Exception e) {
- error = e;
- log.error("Loop aborted", e);
- }
- notifyDone();
- }
-
- /**
- * Notifies observers waiting for loop to become ready.
- */
- protected synchronized void notifyReady() {
- state = State.STARTED;
- notifyAll();
- }
-
- /**
- * Triggers loop shutdown.
- */
- public void shutdown() {
- // Mark the loop as no longer running and wake up the selector.
- state = State.STOPPING;
- selector.wakeup();
- }
-
- /**
- * Notifies observers waiting for loop to fully stop.
- */
- private synchronized void notifyDone() {
- state = State.STOPPED;
- notifyAll();
- }
-
- /**
- * Waits for the loop execution to start.
- *
- * @param timeout number of milliseconds to wait
- * @return true if loop started in time
- */
- public final synchronized boolean awaitStart(long timeout) {
- long max = currentTimeMillis() + timeout;
- while (state != State.STARTED && (currentTimeMillis() < max)) {
- try {
- wait(timeout);
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted", e);
- }
- }
- return state == State.STARTED;
- }
-
- /**
- * Waits for the loop execution to stop.
- *
- * @param timeout number of milliseconds to wait
- * @return true if loop finished in time
- */
- public final synchronized boolean awaitStop(long timeout) {
- long max = currentTimeMillis() + timeout;
- while (state != State.STOPPED && (currentTimeMillis() < max)) {
- try {
- wait(timeout);
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted", e);
- }
- }
- return state == State.STOPPED;
- }
-
-
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/package-info.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/package-info.java
deleted file mode 100644
index 0d58b568..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Mechanism to transfer messages over network using IO loop and
- * message stream, backed by NIO byte buffers.
- */
-package org.onlab.nio;
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultIOLoop.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultIOLoop.java
deleted file mode 100644
index 0d977929..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultIOLoop.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio.service;
-
-import java.io.IOException;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.SelectionKey;
-import java.util.List;
-import java.util.function.Consumer;
-
-import org.onlab.nio.IOLoop;
-import org.onlab.nio.MessageStream;
-
-/**
- * IOLoop for transporting DefaultMessages.
- */
-public class DefaultIOLoop extends IOLoop<DefaultMessage, DefaultMessageStream> {
-
- public static final int SELECT_TIMEOUT_MILLIS = 500;
- private static final int MAX_IDLE_TIMEOUT_MILLIS = 1000;
- private static final int BUFFER_SIZE = 1024 * 1024;
- private final Consumer<DefaultMessage> consumer;
-
- public DefaultIOLoop(Consumer<DefaultMessage> consumer) throws IOException {
- this(SELECT_TIMEOUT_MILLIS, consumer);
- }
-
- public DefaultIOLoop(long timeout, Consumer<DefaultMessage> consumer) throws IOException {
- super(timeout);
- this.consumer = consumer;
- }
-
- @Override
- protected DefaultMessageStream createStream(ByteChannel byteChannel) {
- return new DefaultMessageStream(this, byteChannel, BUFFER_SIZE, MAX_IDLE_TIMEOUT_MILLIS);
- }
-
- @Override
- protected void processMessages(List<DefaultMessage> messages, MessageStream<DefaultMessage> stream) {
- messages.forEach(consumer);
- }
-
- @Override
- protected void connect(SelectionKey key) throws IOException {
- DefaultMessageStream stream = (DefaultMessageStream) key.attachment();
- try {
- super.connect(key);
- stream.connected();
- } catch (Exception e) {
- stream.connectFailed(e);
- }
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessage.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessage.java
deleted file mode 100644
index 591d49b3..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessage.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio.service;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onlab.nio.AbstractMessage;
-import org.onlab.packet.IpAddress;
-import org.onlab.util.ByteArraySizeHashPrinter;
-import org.onosproject.store.cluster.messaging.Endpoint;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.MoreObjects;
-
-/**
- * Default message.
- */
-public class DefaultMessage extends AbstractMessage {
-
- private long id;
- private Endpoint sender;
- private String type;
- private byte[] payload;
-
- /**
- * Creates a new message with the specified data.
- *
- * @param id message id
- * @param type message type
- * @param sender sender endpoint
- * @param payload message payload
- */
- DefaultMessage(long id, Endpoint sender, String type, byte[] payload) {
- this.id = id;
- this.type = checkNotNull(type, "Type cannot be null");
- this.sender = checkNotNull(sender, "Sender cannot be null");
- this.payload = checkNotNull(payload, "Payload cannot be null");
-
- byte[] messageTypeBytes = type.getBytes(Charsets.UTF_8);
- IpAddress senderIp = sender.host();
- byte[] ipOctets = senderIp.toOctets();
-
- length = 25 + ipOctets.length + messageTypeBytes.length + payload.length;
- }
-
- /**
- * Returns message id.
- *
- * @return message id
- */
- public long id() {
- return id;
- }
-
- /**
- * Returns message sender.
- *
- * @return message sender
- */
- public Endpoint sender() {
- return sender;
- }
-
- /**
- * Returns message type.
- *
- * @return message type
- */
- public String type() {
- return type;
- }
-
- /**
- * Returns message payload.
- *
- * @return payload
- */
- public byte[] payload() {
- return payload;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .add("type", type)
- .add("sender", sender)
- .add("payload", ByteArraySizeHashPrinter.of(payload))
- .toString();
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessageStream.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessageStream.java
deleted file mode 100644
index a7dd3c04..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/DefaultMessageStream.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio.service;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.onlab.nio.IOLoop;
-import org.onlab.nio.MessageStream;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onosproject.store.cluster.messaging.Endpoint;
-
-import com.google.common.base.Charsets;
-
-/**
- * Default bi-directional message stream for transferring messages to &amp; from the
- * network via two byte buffers.
- */
-public class DefaultMessageStream extends MessageStream<DefaultMessage> {
-
- private final CompletableFuture<Void> connectFuture = new CompletableFuture<>();
-
- public DefaultMessageStream(
- IOLoop<DefaultMessage, ?> loop,
- ByteChannel byteChannel,
- int bufferSize,
- int maxIdleMillis) {
- super(loop, byteChannel, bufferSize, maxIdleMillis);
- }
-
- public CompletableFuture<DefaultMessageStream> connectedFuture() {
- return connectFuture.thenApply(v -> this);
- }
-
- private final AtomicInteger messageLength = new AtomicInteger(-1);
-
- @Override
- protected DefaultMessage read(ByteBuffer buffer) {
- if (messageLength.get() == -1) {
- // check if we can read the message length.
- if (buffer.remaining() < Integer.BYTES) {
- return null;
- } else {
- messageLength.set(buffer.getInt());
- }
- }
-
- if (buffer.remaining() < messageLength.get()) {
- return null;
- }
-
- long id = buffer.getLong();
- Version ipVersion = buffer.get() == 0x0 ? Version.INET : Version.INET6;
- byte[] octects = new byte[IpAddress.byteLength(ipVersion)];
- buffer.get(octects);
- IpAddress senderIp = IpAddress.valueOf(ipVersion, octects);
- int senderPort = buffer.getInt();
- int messageTypeByteLength = buffer.getInt();
- byte[] messageTypeBytes = new byte[messageTypeByteLength];
- buffer.get(messageTypeBytes);
- String messageType = new String(messageTypeBytes, Charsets.UTF_8);
- int payloadLength = buffer.getInt();
- byte[] payloadBytes = new byte[payloadLength];
- buffer.get(payloadBytes);
-
- // reset for next message
- messageLength.set(-1);
-
- return new DefaultMessage(id, new Endpoint(senderIp, senderPort), messageType, payloadBytes);
- }
-
- @Override
- protected void write(DefaultMessage message, ByteBuffer buffer) {
- Endpoint sender = message.sender();
- byte[] messageTypeBytes = message.type().getBytes(Charsets.UTF_8);
- IpAddress senderIp = sender.host();
- byte[] ipOctets = senderIp.toOctets();
- byte[] payload = message.payload();
-
- int messageLength = 21 + ipOctets.length + messageTypeBytes.length + payload.length;
-
- buffer.putInt(messageLength);
-
- buffer.putLong(message.id());
-
- if (senderIp.version() == Version.INET) {
- buffer.put((byte) 0x0);
- } else {
- buffer.put((byte) 0x1);
- }
- buffer.put(ipOctets);
-
- // write sender port
- buffer.putInt(sender.port());
-
- // write length of message type
- buffer.putInt(messageTypeBytes.length);
-
- // write message type bytes
- buffer.put(messageTypeBytes);
-
- // write payload length
- buffer.putInt(payload.length);
-
- // write payload.
- buffer.put(payload);
- }
-
- /**
- * Callback invoked when the stream is successfully connected.
- */
- public void connected() {
- connectFuture.complete(null);
- }
-
- /**
- * Callback invoked when the stream fails to connect.
- * @param cause failure cause
- */
- public void connectFailed(Throwable cause) {
- connectFuture.completeExceptionally(cause);
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/IOLoopMessaging.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/IOLoopMessaging.java
deleted file mode 100644
index c195d160..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/IOLoopMessaging.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio.service;
-
-import static org.onlab.util.Tools.groupedThreads;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import org.apache.commons.pool.KeyedPoolableObjectFactory;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool;
-import org.onlab.nio.AcceptorLoop;
-import org.onlab.nio.SelectorLoop;
-import org.onosproject.store.cluster.messaging.Endpoint;
-import org.onosproject.store.cluster.messaging.MessagingService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import com.google.common.collect.Lists;
-
-/**
- * MessagingService implementation based on IOLoop.
- */
-public class IOLoopMessaging implements MessagingService {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private static final String REPLY_MESSAGE_TYPE = "ONOS_REQUEST_REPLY";
-
- static final long TIMEOUT = 1000;
-
- static final boolean SO_NO_DELAY = false;
- static final int SO_SEND_BUFFER_SIZE = 128 * 1024;
- static final int SO_RCV_BUFFER_SIZE = 128 * 1024;
-
- private static final int NUM_WORKERS = 8;
-
- private AcceptorLoop acceptorLoop;
- private final ExecutorService acceptorThreadPool =
- Executors.newSingleThreadExecutor(groupedThreads("onos/nio/messaging", "acceptor"));
- private final ExecutorService ioThreadPool =
- Executors.newFixedThreadPool(NUM_WORKERS, groupedThreads("onos/nio/messaging", "io-loop-worker-%d"));
-
- private final List<DefaultIOLoop> ioLoops = Lists.newArrayList();
-
- private int lastWorker = -1;
-
- private final AtomicBoolean started = new AtomicBoolean(false);
- private Endpoint localEp;
-
- private GenericKeyedObjectPool<Endpoint, DefaultMessageStream> streams =
- new GenericKeyedObjectPool<>(new DefaultMessageStreamFactory());
-
- private final ConcurrentMap<String, Consumer<DefaultMessage>> handlers = new ConcurrentHashMap<>();
- private final AtomicLong messageIdGenerator = new AtomicLong(0);
- private final Cache<Long, CompletableFuture<byte[]>> responseFutures = CacheBuilder.newBuilder()
- .removalListener(new RemovalListener<Long, CompletableFuture<byte[]>>() {
- @Override
- public void onRemoval(RemovalNotification<Long, CompletableFuture<byte[]>> entry) {
- if (entry.wasEvicted()) {
- entry.getValue().completeExceptionally(new TimeoutException("Timedout waiting for reply"));
- }
- }
- })
- .build();
-
- /**
- * Activates IO Loops.
- *
- * @param localEp local end-point
- * @throws IOException is activation fails
- */
- public void start(Endpoint localEp) throws IOException {
- if (started.get()) {
- log.warn("IOMessaging is already running at {}", localEp);
- return;
- }
- this.localEp = localEp;
- streams.setLifo(false);
- this.acceptorLoop = new DefaultAcceptorLoop(new InetSocketAddress(localEp.host().toString(), localEp.port()));
-
- for (int i = 0; i < NUM_WORKERS; i++) {
- ioLoops.add(new DefaultIOLoop(this::dispatchLocally));
- }
-
- ioLoops.forEach(ioThreadPool::execute);
- acceptorThreadPool.execute(acceptorLoop);
- ioLoops.forEach(loop -> loop.awaitStart(TIMEOUT));
- acceptorLoop.awaitStart(TIMEOUT);
- started.set(true);
- }
-
- /**
- * Shuts down IO loops.
- */
- public void stop() {
- if (started.get()) {
- ioLoops.forEach(SelectorLoop::shutdown);
- acceptorLoop.shutdown();
- ioThreadPool.shutdown();
- acceptorThreadPool.shutdown();
- started.set(false);
- }
- }
-
-
- @Override
- public CompletableFuture<Void> sendAsync(Endpoint ep, String type, byte[] payload) {
- DefaultMessage message = new DefaultMessage(
- messageIdGenerator.incrementAndGet(),
- localEp,
- type,
- payload);
- return sendAsync(ep, message);
- }
-
- protected CompletableFuture<Void> sendAsync(Endpoint ep, DefaultMessage message) {
- CompletableFuture<Void> future = new CompletableFuture<>();
- if (ep.equals(localEp)) {
- dispatchLocally(message);
- future.complete(null);
- return future;
- }
-
- DefaultMessageStream stream = null;
- try {
- stream = streams.borrowObject(ep);
- stream.write(message);
- future.complete(null);
- } catch (Exception e) {
- future.completeExceptionally(e);
- } finally {
- try {
- streams.returnObject(ep, stream);
- } catch (Exception e) {
- log.warn("Failed to return stream to pool");
- }
- }
- return future;
- }
-
- @Override
- public CompletableFuture<byte[]> sendAndReceive(
- Endpoint ep,
- String type,
- byte[] payload) {
- CompletableFuture<byte[]> response = new CompletableFuture<>();
- Long messageId = messageIdGenerator.incrementAndGet();
- responseFutures.put(messageId, response);
- DefaultMessage message = new DefaultMessage(messageId, localEp, type, payload);
- try {
- sendAsync(ep, message);
- } catch (Exception e) {
- responseFutures.invalidate(messageId);
- response.completeExceptionally(e);
- }
- return response;
- }
-
- @Override
- public void registerHandler(String type, Consumer<byte[]> handler, Executor executor) {
- handlers.put(type, message -> executor.execute(() -> handler.accept(message.payload())));
- }
-
- @Override
- public void registerHandler(String type, Function<byte[], byte[]> handler, Executor executor) {
- handlers.put(type, message -> executor.execute(() -> {
- byte[] responsePayload = handler.apply(message.payload());
- if (responsePayload != null) {
- DefaultMessage response = new DefaultMessage(message.id(),
- localEp,
- REPLY_MESSAGE_TYPE,
- responsePayload);
- sendAsync(message.sender(), response).whenComplete((result, error) -> {
- log.debug("Failed to respond", error);
- });
- }
- }));
- }
-
- @Override
- public void registerHandler(String type, Function<byte[], CompletableFuture<byte[]>> handler) {
- handlers.put(type, message -> {
- handler.apply(message.payload()).whenComplete((result, error) -> {
- if (error == null) {
- DefaultMessage response = new DefaultMessage(message.id(),
- localEp,
- REPLY_MESSAGE_TYPE,
- result);
- sendAsync(message.sender(), response).whenComplete((r, e) -> {
- if (e != null) {
- log.debug("Failed to respond", e);
- }
- });
- }
- });
- });
- }
-
- @Override
- public void unregisterHandler(String type) {
- handlers.remove(type);
- }
-
- protected void dispatchLocally(DefaultMessage message) {
- String type = message.type();
- if (REPLY_MESSAGE_TYPE.equals(type)) {
- try {
- CompletableFuture<byte[]> futureResponse =
- responseFutures.getIfPresent(message.id());
- if (futureResponse != null) {
- futureResponse.complete(message.payload());
- } else {
- log.warn("Received a reply for message id:[{}]. "
- + " from {}. But was unable to locate the"
- + " request handle", message.id(), message.sender());
- }
- } finally {
- responseFutures.invalidate(message.id());
- }
- return;
- }
- Consumer<DefaultMessage> handler = handlers.get(type);
- if (handler != null) {
- handler.accept(message);
- } else {
- log.debug("No handler registered for {}", type);
- }
- }
-
- // Get the next worker to which a client should be assigned
- private synchronized DefaultIOLoop nextWorker() {
- lastWorker = (lastWorker + 1) % NUM_WORKERS;
- return ioLoops.get(lastWorker);
- }
-
- /**
- * Initiates open connection request and registers the pending socket
- * channel with the given IO loop.
- *
- * @param loop loop with which the channel should be registered
- * @throws java.io.IOException if the socket could not be open or connected
- */
- private DefaultMessageStream createConnection(Endpoint ep, DefaultIOLoop loop) throws IOException {
- SocketAddress sa = new InetSocketAddress(ep.host().toString(), ep.port());
- SocketChannel ch = SocketChannel.open();
- ch.configureBlocking(false);
- DefaultMessageStream stream = loop.connectStream(ch);
- ch.connect(sa);
- return stream;
- }
-
- // Loop for accepting client connections
- private class DefaultAcceptorLoop extends AcceptorLoop {
-
- public DefaultAcceptorLoop(SocketAddress address) throws IOException {
- super(DefaultIOLoop.SELECT_TIMEOUT_MILLIS, address);
- }
-
- @Override
- protected void acceptConnection(ServerSocketChannel channel) throws IOException {
- SocketChannel sc = channel.accept();
- sc.configureBlocking(false);
-
- Socket so = sc.socket();
- so.setTcpNoDelay(SO_NO_DELAY);
- so.setReceiveBufferSize(SO_RCV_BUFFER_SIZE);
- so.setSendBufferSize(SO_SEND_BUFFER_SIZE);
-
- nextWorker().acceptStream(sc);
- }
- }
-
- private class DefaultMessageStreamFactory implements KeyedPoolableObjectFactory<Endpoint, DefaultMessageStream> {
-
- @Override
- public void activateObject(Endpoint endpoint, DefaultMessageStream stream) throws Exception {
- }
-
- @Override
- public void destroyObject(Endpoint ep, DefaultMessageStream stream) throws Exception {
- stream.close();
- }
-
- @Override
- public DefaultMessageStream makeObject(Endpoint ep) throws Exception {
- DefaultMessageStream stream = createConnection(ep, nextWorker()).connectedFuture().get();
- log.info("Established a new connection to {}", ep);
- return stream;
- }
-
- @Override
- public void passivateObject(Endpoint ep, DefaultMessageStream stream) throws Exception {
- }
-
- @Override
- public boolean validateObject(Endpoint ep, DefaultMessageStream stream) {
- return stream.isClosed();
- }
- }
-}
diff --git a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/package-info.java b/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/package-info.java
deleted file mode 100644
index 399a2b95..00000000
--- a/framework/src/onos/utils/nio/src/main/java/org/onlab/nio/service/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Assembly for sending and receiving messages using the I/O loop mechanism.
- */
-package org.onlab.nio.service; \ No newline at end of file
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AbstractLoopTest.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AbstractLoopTest.java
deleted file mode 100644
index 2b4a85cd..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AbstractLoopTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.junit.Before;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
-import static org.junit.Assert.fail;
-import static org.onlab.util.Tools.namedThreads;
-
-/**
- * Base class for various NIO loop unit tests.
- */
-public abstract class AbstractLoopTest {
-
- protected static final long MAX_MS_WAIT = 1500;
-
- /** Block on specified countdown latch. Return when countdown reaches
- * zero, or fail the test if the {@value #MAX_MS_WAIT} ms timeout expires.
- *
- * @param latch the latch
- * @param label an identifying label
- */
- protected void waitForLatch(CountDownLatch latch, String label) {
- try {
- boolean ok = latch.await(MAX_MS_WAIT, TimeUnit.MILLISECONDS);
- if (!ok) {
- fail("Latch await timeout! [" + label + "]");
- }
- } catch (InterruptedException e) {
- System.out.println("Latch interrupt [" + label + "] : " + e);
- fail("Unexpected interrupt");
- }
- }
-
- protected ExecutorService exec;
-
- @Before
- public void setUp() {
- exec = newSingleThreadExecutor(namedThreads("test"));
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AcceptorLoopTest.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AcceptorLoopTest.java
deleted file mode 100644
index f04a0126..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/AcceptorLoopTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.junit.Test;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.ServerSocketChannel;
-import java.util.concurrent.CountDownLatch;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.junit.TestTools.delay;
-
-/**
- * Unit tests for AcceptLoop.
- */
-public class AcceptorLoopTest extends AbstractLoopTest {
-
- private static final int PICK_EPHEMERAL = 0;
-
- private static final SocketAddress SOCK_ADDR = new InetSocketAddress("127.0.0.1", PICK_EPHEMERAL);
-
- private static class MyAcceptLoop extends AcceptorLoop {
- private final CountDownLatch loopStarted = new CountDownLatch(1);
- private final CountDownLatch loopFinished = new CountDownLatch(1);
- private final CountDownLatch runDone = new CountDownLatch(1);
- private final CountDownLatch ceaseLatch = new CountDownLatch(1);
-
- private int acceptCount = 0;
-
- MyAcceptLoop() throws IOException {
- super(500, SOCK_ADDR);
- }
-
- @Override
- protected void acceptConnection(ServerSocketChannel ssc) throws IOException {
- acceptCount++;
- }
-
- @Override
- public void loop() throws IOException {
- loopStarted.countDown();
- super.loop();
- loopFinished.countDown();
- }
-
- @Override
- public void run() {
- super.run();
- runDone.countDown();
- }
-
- @Override
- public void shutdown() {
- super.shutdown();
- ceaseLatch.countDown();
- }
- }
-
- @Test
- public void basic() throws IOException {
- MyAcceptLoop myAccLoop = new MyAcceptLoop();
- AcceptorLoop accLoop = myAccLoop;
- exec.execute(accLoop);
- waitForLatch(myAccLoop.loopStarted, "loopStarted");
- delay(200); // take a quick nap
- accLoop.shutdown();
- waitForLatch(myAccLoop.loopFinished, "loopFinished");
- waitForLatch(myAccLoop.runDone, "runDone");
- assertEquals(0, myAccLoop.acceptCount);
- }
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopIntegrationTest.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopIntegrationTest.java
deleted file mode 100644
index f42c8dc5..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopIntegrationTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.net.InetAddress;
-import java.util.Random;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static org.onlab.junit.TestTools.delay;
-
-/**
- * Integration test for the select, accept and IO loops.
- */
-public class IOLoopIntegrationTest {
-
- private static final int THREADS = 6;
- private static final int TIMEOUT = 60;
- private static final int MESSAGE_LENGTH = 128;
-
- private static final int MILLION = 1000000;
- private static final int MSG_COUNT = 40 * MILLION;
-
- @Before
- public void warmUp() throws Exception {
- Logger.getLogger("").setLevel(Level.SEVERE);
- try {
- runTest(MILLION, MESSAGE_LENGTH, 15);
- } catch (Throwable e) {
- System.err.println("Failed warmup but moving on.");
- e.printStackTrace();
- }
- }
-
- // TODO: this test can not pass in some environments, need to be improved
- @Ignore
- @Test
- public void basic() throws Exception {
- runTest(MILLION, MESSAGE_LENGTH, TIMEOUT);
- }
-
- public void longHaul() throws Exception {
- runTest(MSG_COUNT, MESSAGE_LENGTH, TIMEOUT);
- }
-
- private void runTest(int count, int size, int timeout) throws Exception {
- // Use a random port to prevent conflicts.
- int port = IOLoopTestServer.PORT + new Random().nextInt(100);
-
- InetAddress ip = InetAddress.getLoopbackAddress();
- IOLoopTestServer server = new IOLoopTestServer(ip, THREADS, size, port);
- IOLoopTestClient client = new IOLoopTestClient(ip, THREADS, count, size, port);
-
- server.start();
- client.start();
- delay(100); // Pause to allow loops to get going
-
- client.await(timeout);
- client.report();
-
- server.stop();
- server.report();
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java
deleted file mode 100644
index acc9a08f..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import com.google.common.collect.Lists;
-import org.onlab.util.Counter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import static java.lang.String.format;
-import static java.lang.System.nanoTime;
-import static java.lang.System.out;
-import static org.onlab.nio.IOLoopTestServer.PORT;
-import static org.onlab.util.Tools.delay;
-import static org.onlab.util.Tools.namedThreads;
-
-/**
- * Auxiliary test fixture to measure speed of NIO-based channels.
- */
-public class IOLoopTestClient {
-
- private static Logger log = LoggerFactory.getLogger(IOLoopTestClient.class);
-
- private final InetAddress ip;
- private final int port;
- private final int msgCount;
- private final int msgLength;
-
- private final List<CustomIOLoop> iloops = new ArrayList<>();
- private final ExecutorService ipool;
- private final ExecutorService wpool;
-
- Counter messages;
- Counter bytes;
- long latencyTotal = 0;
- long latencyCount = 0;
-
-
- /**
- * Main entry point to launch the client.
- *
- * @param args command-line arguments
- * @throws java.io.IOException if unable to connect to server
- * @throws InterruptedException if latch wait gets interrupted
- * @throws java.util.concurrent.ExecutionException if wait gets interrupted
- * @throws java.util.concurrent.TimeoutException if timeout occurred while waiting for completion
- */
- public static void main(String[] args)
- throws IOException, InterruptedException, ExecutionException, TimeoutException {
- startStandalone(args);
-
- System.exit(0);
- }
-
- /**
- * Starts a standalone IO loop test client.
- *
- * @param args command-line arguments
- */
- public static void startStandalone(String[] args)
- throws IOException, InterruptedException, ExecutionException, TimeoutException {
- InetAddress ip = InetAddress.getByName(args.length > 0 ? args[0] : "127.0.0.1");
- int wc = args.length > 1 ? Integer.parseInt(args[1]) : 6;
- int mc = args.length > 2 ? Integer.parseInt(args[2]) : 50 * 1000000;
- int ml = args.length > 3 ? Integer.parseInt(args[3]) : 128;
- int to = args.length > 4 ? Integer.parseInt(args[4]) : 60;
-
- log.info("Setting up client with {} workers sending {} {}-byte messages to {} server... ",
- wc, mc, ml, ip);
- IOLoopTestClient client = new IOLoopTestClient(ip, wc, mc, ml, PORT);
-
- client.start();
- delay(500);
-
- client.await(to);
- client.report();
- }
-
- /**
- * Creates a speed client.
- *
- * @param ip ip address of server
- * @param wc worker count
- * @param mc message count to send per client
- * @param ml message length in bytes
- * @param port socket port
- * @throws java.io.IOException if unable to create IO loops
- */
- public IOLoopTestClient(InetAddress ip, int wc, int mc, int ml, int port) throws IOException {
- this.ip = ip;
- this.port = port;
- this.msgCount = mc;
- this.msgLength = ml;
- this.wpool = Executors.newFixedThreadPool(wc, namedThreads("worker"));
- this.ipool = Executors.newFixedThreadPool(wc, namedThreads("io-loop"));
-
- for (int i = 0; i < wc; i++) {
- iloops.add(new CustomIOLoop());
- }
- }
-
- /**
- * Starts the client workers.
- *
- * @throws java.io.IOException if unable to open connection
- */
- public void start() throws IOException {
- messages = new Counter();
- bytes = new Counter();
-
- // First start up all the IO loops
- for (CustomIOLoop l : iloops) {
- ipool.execute(l);
- }
-
- // Wait for all of them to get going
- for (CustomIOLoop l : iloops) {
- l.awaitStart(1000);
- }
-
- // ... and Next open all connections; one-per-loop
- for (CustomIOLoop l : iloops) {
- openConnection(l);
- }
- }
-
-
- /**
- * Initiates open connection request and registers the pending socket
- * channel with the given IO loop.
- *
- * @param loop loop with which the channel should be registered
- * @throws java.io.IOException if the socket could not be open or connected
- */
- private void openConnection(CustomIOLoop loop) throws IOException {
- SocketAddress sa = new InetSocketAddress(ip, port);
- SocketChannel ch = SocketChannel.open();
- ch.configureBlocking(false);
- loop.connectStream(ch);
- ch.connect(sa);
- }
-
-
- /**
- * Waits for the client workers to complete.
- *
- * @param secs timeout in seconds
- * @throws java.util.concurrent.ExecutionException if execution failed
- * @throws InterruptedException if interrupt occurred while waiting
- * @throws java.util.concurrent.TimeoutException if timeout occurred
- */
- public void await(int secs) throws InterruptedException,
- ExecutionException, TimeoutException {
- for (CustomIOLoop l : iloops) {
- if (l.worker.task != null) {
- l.worker.task.get(secs, TimeUnit.SECONDS);
- latencyTotal += l.latencyTotal;
- latencyCount += l.latencyCount;
- }
- }
- messages.freeze();
- bytes.freeze();
- }
-
- /**
- * Reports on the accumulated throughput and latency.
- */
- public void report() {
- DecimalFormat f = new DecimalFormat("#,##0");
- out.println(format("Client: %s messages; %s bytes; %s mps; %s MBs; %s ns latency",
- f.format(messages.total()), f.format(bytes.total()),
- f.format(messages.throughput()),
- f.format(bytes.throughput() / (1024 * msgLength)),
- f.format(latencyTotal / latencyCount)));
- }
-
-
- // Loop for transfer of fixed-length messages
- private class CustomIOLoop extends IOLoop<TestMessage, TestMessageStream> {
-
- Worker worker = new Worker();
- long latencyTotal = 0;
- long latencyCount = 0;
-
-
- public CustomIOLoop() throws IOException {
- super(500);
- }
-
-
- @Override
- protected TestMessageStream createStream(ByteChannel channel) {
- return new TestMessageStream(msgLength, channel, this);
- }
-
- @Override
- protected synchronized void removeStream(MessageStream<TestMessage> stream) {
- super.removeStream(stream);
- messages.add(stream.messagesIn().total());
- bytes.add(stream.bytesIn().total());
- stream.messagesOut().reset();
- stream.bytesOut().reset();
- }
-
- @Override
- protected void processMessages(List<TestMessage> messages,
- MessageStream<TestMessage> stream) {
- for (TestMessage message : messages) {
- // TODO: summarize latency data better
- latencyTotal += nanoTime() - message.requestorTime();
- latencyCount++;
- }
- worker.release(messages.size());
- }
-
- @Override
- protected void connect(SelectionKey key) throws IOException {
- super.connect(key);
- TestMessageStream b = (TestMessageStream) key.attachment();
- Worker w = ((CustomIOLoop) b.loop()).worker;
- w.pump(b);
- }
-
- }
-
- /**
- * Auxiliary worker to connect and pump batched messages using blocking I/O.
- */
- private class Worker implements Runnable {
-
- private static final int BATCH_SIZE = 50;
- private static final int PERMITS = 2 * BATCH_SIZE;
-
- private TestMessageStream stream;
- private FutureTask<Worker> task;
-
- // Stuff to throttle pump
- private final Semaphore semaphore = new Semaphore(PERMITS);
- private int msgWritten;
-
- void pump(TestMessageStream stream) {
- this.stream = stream;
- task = new FutureTask<>(this, this);
- wpool.execute(task);
- }
-
- @Override
- public void run() {
- try {
- log.info("Worker started...");
-
- while (msgWritten < msgCount) {
- int size = Math.min(BATCH_SIZE, msgCount - msgWritten);
- writeBatch(size);
- msgWritten += size;
- }
-
- // Now try to get all the permits back before sending poison pill
- semaphore.acquireUninterruptibly(PERMITS);
- stream.close();
-
- log.info("Worker done...");
-
- } catch (IOException e) {
- log.error("Worker unable to perform I/O", e);
- }
- }
-
-
- private void writeBatch(int size) throws IOException {
- // Build a batch of messages
- List<TestMessage> batch = Lists.newArrayListWithCapacity(size);
- for (int i = 0; i < size; i++) {
- batch.add(new TestMessage(msgLength, nanoTime(), 0, stream.padding()));
- }
- acquire(size);
- stream.write(batch);
- }
-
-
- // Release permits based on the specified number of message credits
- private void release(int permits) {
- semaphore.release(permits);
- }
-
- // Acquire permit for a single batch
- private void acquire(int permits) {
- semaphore.acquireUninterruptibly(permits);
- }
-
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java
deleted file mode 100644
index d5ce5f39..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import com.google.common.collect.Lists;
-import org.onlab.util.Counter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static java.lang.String.format;
-import static java.lang.System.out;
-import static org.onlab.util.Tools.delay;
-import static org.onlab.util.Tools.namedThreads;
-
-/**
- * Auxiliary test fixture to measure speed of NIO-based channels.
- */
-public class IOLoopTestServer {
-
- private static Logger log = LoggerFactory.getLogger(IOLoopTestServer.class);
-
- private static final int PRUNE_FREQUENCY = 1000;
-
- static final int PORT = 9876;
- static final long TIMEOUT = 1000;
-
- static final boolean SO_NO_DELAY = false;
- static final int SO_SEND_BUFFER_SIZE = 128 * 1024;
- static final int SO_RCV_BUFFER_SIZE = 128 * 1024;
-
- static final DecimalFormat FORMAT = new DecimalFormat("#,##0");
-
- private final AcceptorLoop aloop;
- private final ExecutorService apool = Executors.newSingleThreadExecutor(namedThreads("accept"));
-
- private final List<CustomIOLoop> iloops = new ArrayList<>();
- private final ExecutorService ipool;
-
- private final int workerCount;
- private final int msgLength;
- private int lastWorker = -1;
-
- Counter messages;
- Counter bytes;
-
- /**
- * Main entry point to launch the server.
- *
- * @param args command-line arguments
- * @throws java.io.IOException if unable to crate IO loops
- */
- public static void main(String[] args) throws IOException {
- startStandalone(args);
- System.exit(0);
- }
-
- /**
- * Starts a standalone IO loop test server.
- *
- * @param args command-line arguments
- */
- public static void startStandalone(String[] args) throws IOException {
- InetAddress ip = InetAddress.getByName(args.length > 0 ? args[0] : "127.0.0.1");
- int wc = args.length > 1 ? Integer.parseInt(args[1]) : 6;
- int ml = args.length > 2 ? Integer.parseInt(args[2]) : 128;
-
- log.info("Setting up the server with {} workers, {} byte messages on {}... ",
- wc, ml, ip);
- IOLoopTestServer server = new IOLoopTestServer(ip, wc, ml, PORT);
- server.start();
-
- // Start pruning clients and keep going until their number goes to 0.
- int remaining = -1;
- while (remaining == -1 || remaining > 0) {
- delay(PRUNE_FREQUENCY);
- int r = server.prune();
- remaining = remaining == -1 && r == 0 ? remaining : r;
- }
- server.stop();
- }
-
- /**
- * Creates a speed server.
- *
- * @param ip optional ip of the adapter where to bind
- * @param wc worker count
- * @param ml message length in bytes
- * @param port listen port
- * @throws java.io.IOException if unable to create IO loops
- */
- public IOLoopTestServer(InetAddress ip, int wc, int ml, int port) throws IOException {
- this.workerCount = wc;
- this.msgLength = ml;
- this.ipool = Executors.newFixedThreadPool(workerCount, namedThreads("io-loop"));
-
- this.aloop = new CustomAcceptLoop(new InetSocketAddress(ip, port));
- for (int i = 0; i < workerCount; i++) {
- iloops.add(new CustomIOLoop());
- }
- }
-
- /**
- * Start the server IO loops and kicks off throughput tracking.
- */
- public void start() {
- messages = new Counter();
- bytes = new Counter();
-
- for (CustomIOLoop l : iloops) {
- ipool.execute(l);
- }
- apool.execute(aloop);
-
- for (CustomIOLoop l : iloops) {
- l.awaitStart(TIMEOUT);
- }
- aloop.awaitStart(TIMEOUT);
- }
-
- /**
- * Stop the server IO loops and freezes throughput tracking.
- */
- public void stop() {
- aloop.shutdown();
- for (CustomIOLoop l : iloops) {
- l.shutdown();
- }
-
- for (CustomIOLoop l : iloops) {
- l.awaitStop(TIMEOUT);
- }
- aloop.awaitStop(TIMEOUT);
-
- messages.freeze();
- bytes.freeze();
- }
-
- /**
- * Reports on the accumulated throughput and latency.
- */
- public void report() {
- DecimalFormat f = new DecimalFormat("#,##0");
- out.println(format("Server: %s messages; %s bytes; %s mps; %s MBs",
- f.format(messages.total()), f.format(bytes.total()),
- f.format(messages.throughput()),
- f.format(bytes.throughput() / (1024 * msgLength))));
- }
-
- /**
- * Prunes the IO loops of stale message buffers.
- *
- * @return number of remaining IO loops among all workers.
- */
- public int prune() {
- int count = 0;
- for (CustomIOLoop l : iloops) {
- count += l.pruneStaleStreams();
- }
- return count;
- }
-
- // Get the next worker to which a client should be assigned
- private synchronized CustomIOLoop nextWorker() {
- lastWorker = (lastWorker + 1) % workerCount;
- return iloops.get(lastWorker);
- }
-
- // Loop for transfer of fixed-length messages
- private class CustomIOLoop extends IOLoop<TestMessage, TestMessageStream> {
-
- public CustomIOLoop() throws IOException {
- super(500);
- }
-
- @Override
- protected TestMessageStream createStream(ByteChannel channel) {
- return new TestMessageStream(msgLength, channel, this);
- }
-
- @Override
- protected void removeStream(MessageStream<TestMessage> stream) {
- super.removeStream(stream);
- messages.add(stream.messagesIn().total());
- bytes.add(stream.bytesIn().total());
- }
-
- @Override
- protected void processMessages(List<TestMessage> messages,
- MessageStream<TestMessage> stream) {
- try {
- stream.write(createResponses(messages));
- } catch (IOException e) {
- log.error("Unable to echo messages", e);
- }
- }
-
- private List<TestMessage> createResponses(List<TestMessage> messages) {
- List<TestMessage> responses = Lists.newArrayListWithCapacity(messages.size());
- for (TestMessage message : messages) {
- responses.add(new TestMessage(message.length(), message.requestorTime(),
- System.nanoTime(), message.padding()));
- }
- return responses;
- }
- }
-
- // Loop for accepting client connections
- private class CustomAcceptLoop extends AcceptorLoop {
-
- public CustomAcceptLoop(SocketAddress address) throws IOException {
- super(500, address);
- }
-
- @Override
- protected void acceptConnection(ServerSocketChannel channel) throws IOException {
- SocketChannel sc = channel.accept();
- sc.configureBlocking(false);
-
- Socket so = sc.socket();
- so.setTcpNoDelay(SO_NO_DELAY);
- so.setReceiveBufferSize(SO_RCV_BUFFER_SIZE);
- so.setSendBufferSize(SO_SEND_BUFFER_SIZE);
-
- nextWorker().acceptStream(sc);
- log.info("Connected client");
- }
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MessageStreamTest.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MessageStreamTest.java
deleted file mode 100644
index 9965d389..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MessageStreamTest.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-/**
- * Tests of the message message stream implementation.
- */
-public class MessageStreamTest {
-
- private static final int SIZE = 64;
- private static final int BIG_SIZE = 32 * 1024;
-
- private TestMessage message;
-
- private TestIOLoop loop;
- private TestByteChannel channel;
- private TestMessageStream stream;
- private TestKey key;
-
- @Before
- public void setUp() throws IOException {
- loop = new TestIOLoop();
- channel = new TestByteChannel();
- key = new TestKey(channel);
- stream = loop.createStream(channel);
- stream.setKey(key);
- stream.setNonStrict();
- message = new TestMessage(SIZE, 0, 0, stream.padding());
- }
-
- @After
- public void tearDown() {
- loop.shutdown();
- stream.close();
- }
-
- // Validates the state of the message stream
- private void validate(boolean wp, boolean fr, int read, int written) {
- assertEquals(wp, stream.isWritePending());
- assertEquals(fr, stream.isFlushRequired());
- assertEquals(read, channel.readBytes);
- assertEquals(written, channel.writtenBytes);
- }
-
- @Test
- public void endOfStream() throws IOException {
- channel.close();
- List<TestMessage> messages = stream.read();
- assertNull(messages);
- }
-
- @Test
- public void bufferGrowth() throws IOException {
- // Create a stream for big messages and test the growth.
- stream = new TestMessageStream(BIG_SIZE, channel, loop);
- TestMessage bigMessage = new TestMessage(BIG_SIZE, 0, 0, stream.padding());
-
- stream.write(bigMessage);
- stream.write(bigMessage);
- stream.write(bigMessage);
- stream.write(bigMessage);
- stream.write(bigMessage);
- }
-
- @Test
- public void discardBeforeKey() {
- // Create a stream that does not yet have the key set and discard it.
- stream = loop.createStream(channel);
- assertNull(stream.key());
- stream.close();
- // There is not key, so nothing to check; we just expect no problem.
- }
-
- @Test
- public void bufferedRead() throws IOException {
- channel.bytesToRead = SIZE + 4;
- List<TestMessage> messages = stream.read();
- assertEquals(1, messages.size());
- validate(false, false, SIZE + 4, 0);
-
- channel.bytesToRead = SIZE - 4;
- messages = stream.read();
- assertEquals(1, messages.size());
- validate(false, false, SIZE * 2, 0);
- }
-
- @Test
- public void bufferedWrite() throws IOException {
- validate(false, false, 0, 0);
-
- // First write is immediate...
- stream.write(message);
- validate(false, false, 0, SIZE);
-
- // Second and third get buffered...
- stream.write(message);
- validate(false, true, 0, SIZE);
- stream.write(message);
- validate(false, true, 0, SIZE);
-
- // Reset write, which will flush if needed; the next write is again buffered
- stream.flushIfWriteNotPending();
- validate(false, false, 0, SIZE * 3);
- stream.write(message);
- validate(false, true, 0, SIZE * 3);
-
- // Select reset, which will flush if needed; the next write is again buffered
- stream.flushIfPossible();
- validate(false, false, 0, SIZE * 4);
- stream.write(message);
- validate(false, true, 0, SIZE * 4);
- stream.flush();
- validate(false, true, 0, SIZE * 4);
- }
-
- @Test
- public void bufferedWriteList() throws IOException {
- validate(false, false, 0, 0);
-
- // First write is immediate...
- List<TestMessage> messages = new ArrayList<>();
- messages.add(message);
- messages.add(message);
- messages.add(message);
- messages.add(message);
-
- stream.write(messages);
- validate(false, false, 0, SIZE * 4);
-
- stream.write(messages);
- validate(false, true, 0, SIZE * 4);
-
- stream.flushIfPossible();
- validate(false, false, 0, SIZE * 8);
- }
-
- @Test
- public void bufferedPartialWrite() throws IOException {
- validate(false, false, 0, 0);
-
- // First write is immediate...
- stream.write(message);
- validate(false, false, 0, SIZE);
-
- // Tell test channel to accept only half.
- channel.bytesToWrite = SIZE / 2;
-
- // Second and third get buffered...
- stream.write(message);
- validate(false, true, 0, SIZE);
- stream.flushIfPossible();
- validate(true, true, 0, SIZE + SIZE / 2);
- }
-
- @Test
- public void bufferedPartialWrite2() throws IOException {
- validate(false, false, 0, 0);
-
- // First write is immediate...
- stream.write(message);
- validate(false, false, 0, SIZE);
-
- // Tell test channel to accept only half.
- channel.bytesToWrite = SIZE / 2;
-
- // Second and third get buffered...
- stream.write(message);
- validate(false, true, 0, SIZE);
- stream.flushIfWriteNotPending();
- validate(true, true, 0, SIZE + SIZE / 2);
- }
-
- @Test
- public void bufferedReadWrite() throws IOException {
- channel.bytesToRead = SIZE + 4;
- List<TestMessage> messages = stream.read();
- assertEquals(1, messages.size());
- validate(false, false, SIZE + 4, 0);
-
- stream.write(message);
- validate(false, false, SIZE + 4, SIZE);
-
- channel.bytesToRead = SIZE - 4;
- messages = stream.read();
- assertEquals(1, messages.size());
- validate(false, false, SIZE * 2, SIZE);
- }
-
- // Fake IO driver loop
- private static class TestIOLoop extends IOLoop<TestMessage, TestMessageStream> {
-
- public TestIOLoop() throws IOException {
- super(500);
- }
-
- @Override
- protected TestMessageStream createStream(ByteChannel channel) {
- return new TestMessageStream(SIZE, channel, this);
- }
-
- @Override
- protected void processMessages(List<TestMessage> messages,
- MessageStream<TestMessage> stream) {
- }
-
- }
-
- // Byte channel test fixture
- private static class TestByteChannel extends SelectableChannel implements ByteChannel {
-
- private static final int BUFFER_LENGTH = 1024;
- byte[] bytes = new byte[BUFFER_LENGTH];
- int bytesToWrite = BUFFER_LENGTH;
- int bytesToRead = BUFFER_LENGTH;
- int writtenBytes = 0;
- int readBytes = 0;
-
- @Override
- public int read(ByteBuffer dst) throws IOException {
- int l = Math.min(dst.remaining(), bytesToRead);
- if (bytesToRead > 0) {
- readBytes += l;
- dst.put(bytes, 0, l);
- }
- return l;
- }
-
- @Override
- public int write(ByteBuffer src) throws IOException {
- int l = Math.min(src.remaining(), bytesToWrite);
- writtenBytes += l;
- src.get(bytes, 0, l);
- return l;
- }
-
- @Override
- public Object blockingLock() {
- return null;
- }
-
- @Override
- public SelectableChannel configureBlocking(boolean arg0) throws IOException {
- return null;
- }
-
- @Override
- public boolean isBlocking() {
- return false;
- }
-
- @Override
- public boolean isRegistered() {
- return false;
- }
-
- @Override
- public SelectionKey keyFor(Selector arg0) {
- return null;
- }
-
- @Override
- public SelectorProvider provider() {
- return null;
- }
-
- @Override
- public SelectionKey register(Selector arg0, int arg1, Object arg2)
- throws ClosedChannelException {
- return null;
- }
-
- @Override
- public int validOps() {
- return 0;
- }
-
- @Override
- protected void implCloseChannel() throws IOException {
- bytesToRead = -1;
- }
-
- }
-
- // Selection key text fixture
- private static class TestKey extends SelectionKey {
-
- private SelectableChannel channel;
-
- public TestKey(TestByteChannel channel) {
- this.channel = channel;
- }
-
- @Override
- public void cancel() {
- }
-
- @Override
- public SelectableChannel channel() {
- return channel;
- }
-
- @Override
- public int interestOps() {
- return 0;
- }
-
- @Override
- public SelectionKey interestOps(int ops) {
- return null;
- }
-
- @Override
- public boolean isValid() {
- return true;
- }
-
- @Override
- public int readyOps() {
- return 0;
- }
-
- @Override
- public Selector selector() {
- return null;
- }
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MockSelector.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MockSelector.java
deleted file mode 100644
index cf5b2bb9..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/MockSelector.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import java.io.IOException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.AbstractSelectableChannel;
-import java.nio.channels.spi.AbstractSelector;
-import java.util.Set;
-
-/**
- * A selector instrumented for unit tests.
- */
-public class MockSelector extends AbstractSelector {
-
- int wakeUpCount = 0;
-
- /**
- * Creates a mock selector, specifying null as the SelectorProvider.
- */
- public MockSelector() {
- super(null);
- }
-
- @Override
- public String toString() {
- return "{MockSelector: wake=" + wakeUpCount + "}";
- }
-
- @Override
- protected void implCloseSelector() throws IOException {
- }
-
- @Override
- protected SelectionKey register(AbstractSelectableChannel ch, int ops,
- Object att) {
- return null;
- }
-
- @Override
- public Set<SelectionKey> keys() {
- return null;
- }
-
- @Override
- public Set<SelectionKey> selectedKeys() {
- return null;
- }
-
- @Override
- public int selectNow() throws IOException {
- return 0;
- }
-
- @Override
- public int select(long timeout) throws IOException {
- return 0;
- }
-
- @Override
- public int select() throws IOException {
- return 0;
- }
-
- @Override
- public Selector wakeup() {
- wakeUpCount++;
- return null;
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessage.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessage.java
deleted file mode 100644
index 825479b5..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessage.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Test message for measuring rate and round-trip latency.
- */
-public class TestMessage extends AbstractMessage {
-
- private final byte[] padding;
-
- private final long requestorTime;
- private final long responderTime;
-
- /**
- * Creates a new message with the specified data.
- *
- * @param requestorTime requester time
- * @param responderTime responder time
- * @param padding message padding
- */
- TestMessage(int length, long requestorTime, long responderTime, byte[] padding) {
- this.length = length;
- this.requestorTime = requestorTime;
- this.responderTime = responderTime;
- this.padding = checkNotNull(padding, "Padding cannot be null");
- }
-
- public long requestorTime() {
- return requestorTime;
- }
-
- public long responderTime() {
- return responderTime;
- }
-
- public byte[] padding() {
- return padding;
- }
-
-}
diff --git a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessageStream.java b/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessageStream.java
deleted file mode 100644
index fc86beb9..00000000
--- a/framework/src/onos/utils/nio/src/test/java/org/onlab/nio/TestMessageStream.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * Fixed-length message transfer buffer.
- */
-public class TestMessageStream extends MessageStream<TestMessage> {
-
- private static final String E_WRONG_LEN = "Illegal message length: ";
- private static final long START_TAG = 0xfeedcafedeaddeedL;
- private static final long END_TAG = 0xbeadcafedeaddeedL;
- private static final int META_LENGTH = 40;
-
- private final int length;
- private boolean isStrict = true;
-
- public TestMessageStream(int length, ByteChannel ch, IOLoop<TestMessage, ?> loop) {
- super(loop, ch, 64 * 1024, 500);
- checkArgument(length >= META_LENGTH, "Length must be greater than header length of 40");
- this.length = length;
- }
-
- void setNonStrict() {
- isStrict = false;
- }
-
- @Override
- protected TestMessage read(ByteBuffer rb) {
- if (rb.remaining() < length) {
- return null;
- }
-
- long startTag = rb.getLong();
- if (isStrict) {
- checkState(startTag == START_TAG, "Incorrect message start");
- }
-
- long size = rb.getLong();
- long requestorTime = rb.getLong();
- long responderTime = rb.getLong();
- byte[] padding = padding();
- rb.get(padding);
-
- long endTag = rb.getLong();
- if (isStrict) {
- checkState(endTag == END_TAG, "Incorrect message end");
- }
-
- return new TestMessage((int) size, requestorTime, responderTime, padding);
- }
-
- @Override
- protected void write(TestMessage message, ByteBuffer wb) {
- if (message.length() != length) {
- throw new IllegalArgumentException(E_WRONG_LEN + message.length());
- }
-
- wb.putLong(START_TAG);
- wb.putLong(message.length());
- wb.putLong(message.requestorTime());
- wb.putLong(message.responderTime());
- wb.put(message.padding(), 0, length - META_LENGTH);
- wb.putLong(END_TAG);
- }
-
- public byte[] padding() {
- return new byte[length - META_LENGTH];
- }
-}
diff --git a/framework/src/onos/utils/osgi/pom.xml b/framework/src/onos/utils/osgi/pom.xml
deleted file mode 100644
index 25690cab..00000000
--- a/framework/src/onos/utils/osgi/pom.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-osgi</artifactId>
- <packaging>bundle</packaging>
-
- <description>ON.Lab OSGI utilities</description>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/DefaultServiceDirectory.java b/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/DefaultServiceDirectory.java
deleted file mode 100644
index b3421485..00000000
--- a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/DefaultServiceDirectory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.osgi;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Default implementation of the service directory using OSGi framework utilities.
- */
-public class DefaultServiceDirectory implements ServiceDirectory {
-
- /**
- * Returns the reference to the implementation of the specified service.
- *
- * @param serviceClass service class
- * @param <T> type of service
- * @return service implementation
- */
- public static <T> T getService(Class<T> serviceClass) {
- BundleContext bc = FrameworkUtil.getBundle(serviceClass).getBundleContext();
- if (bc != null) {
- ServiceReference<T> reference = bc.getServiceReference(serviceClass);
- if (reference != null) {
- T impl = bc.getService(reference);
- if (impl != null) {
- return impl;
- }
- }
- }
- throw new ServiceNotFoundException("Service " + serviceClass.getName() + " not found");
- }
-
- @Override
- public <T> T get(Class<T> serviceClass) {
- return getService(serviceClass);
- }
-
-}
diff --git a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceDirectory.java b/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceDirectory.java
deleted file mode 100644
index f9ffed74..00000000
--- a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceDirectory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.osgi;
-
-/**
- * Simple abstraction of a service directory where service implementations can
- * be found by the class name of the interfaces they provide.
- */
-public interface ServiceDirectory {
-
- /**
- * Returns implementation of the specified service class.
- *
- * @param serviceClass service class
- * @param <T> type of service
- * @return implementation class
- * @throws ServiceNotFoundException if no implementation found
- */
- <T> T get(Class<T> serviceClass);
-
-}
diff --git a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceNotFoundException.java b/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceNotFoundException.java
deleted file mode 100644
index 8b14227e..00000000
--- a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/ServiceNotFoundException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.osgi;
-
-/**
- * Represents condition where some service is not found or not available.
- */
-public class ServiceNotFoundException extends RuntimeException {
-
- /**
- * Creates a new exception with no message.
- */
- public ServiceNotFoundException() {
- }
-
- /**
- * Creates a new exception with the supplied message.
- * @param message error message
- */
- public ServiceNotFoundException(String message) {
- super(message);
- }
-
- /**
- * Creates a new exception with the supplied message and cause.
- * @param message error message
- * @param cause cause of the error
- */
- public ServiceNotFoundException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/package-info.java b/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/package-info.java
deleted file mode 100644
index 289c60a4..00000000
--- a/framework/src/onos/utils/osgi/src/main/java/org/onlab/osgi/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Facilities for building testable components in OSGi independent fashion.
- */
-package org.onlab.osgi;
diff --git a/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/ComponentContextAdapter.java b/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/ComponentContextAdapter.java
deleted file mode 100644
index b8718c3c..00000000
--- a/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/ComponentContextAdapter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.osgi;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.ComponentInstance;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-/**
- * Adapter implementation of OSGI component context.
- */
-public class ComponentContextAdapter implements ComponentContext {
- private static class MockDictionary extends Dictionary {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public Enumeration keys() {
- return null;
- }
-
- @Override
- public Enumeration elements() {
- return null;
- }
-
- @Override
- public Object get(Object key) {
- return null;
- }
-
- @Override
- public Object put(Object key, Object value) {
- return null;
- }
-
- @Override
- public Object remove(Object key) {
- return null;
- }
- }
-
- @Override
- public Dictionary getProperties() {
- return new MockDictionary();
- }
-
- @Override
- public Object locateService(String name) {
- return null;
- }
-
- @Override
- public Object locateService(String name, ServiceReference reference) {
- return null;
- }
-
- @Override
- public Object[] locateServices(String name) {
- return new Object[0];
- }
-
- @Override
- public BundleContext getBundleContext() {
- return null;
- }
-
- @Override
- public Bundle getUsingBundle() {
- return null;
- }
-
- @Override
- public ComponentInstance getComponentInstance() {
- return null;
- }
-
- @Override
- public void enableComponent(String name) {
-
- }
-
- @Override
- public void disableComponent(String name) {
-
- }
-
- @Override
- public ServiceReference getServiceReference() {
- return null;
- }
-}
diff --git a/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/TestServiceDirectory.java b/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/TestServiceDirectory.java
deleted file mode 100644
index 08089ada..00000000
--- a/framework/src/onos/utils/osgi/src/test/java/org/onlab/osgi/TestServiceDirectory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.osgi;
-
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.MutableClassToInstanceMap;
-
-/**
- * Service directory implementation suitable for testing.
- */
-@SuppressWarnings("unchecked")
-public class TestServiceDirectory implements ServiceDirectory {
-
- private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
-
- @Override
- public <T> T get(Class<T> serviceClass) {
- return services.getInstance(serviceClass);
- }
-
- /**
- * Adds a new service to the directory.
- *
- * @param serviceClass service class
- * @param service service instance
- * @return self
- */
- public TestServiceDirectory add(Class serviceClass, Object service) {
- services.putInstance(serviceClass, service);
- return this;
- }
-
-}
diff --git a/framework/src/onos/utils/pom.xml b/framework/src/onos/utils/pom.xml
deleted file mode 100644
index d3cd5a5b..00000000
--- a/framework/src/onos/utils/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onos</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-utils</artifactId>
- <packaging>pom</packaging>
-
- <description>Domain agnostic ON.Lab utilities</description>
-
- <modules>
- <module>junit</module>
- <module>misc</module>
- <module>netty</module>
- <module>nio</module>
- <module>osgi</module>
- <module>rest</module>
- <module>thirdparty</module>
- <module>stc</module>
- <module>jdvue</module>
- <module>jnc</module>
- <module>catalyst</module> <!-- FIXME publish and remove before release -->
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/utils/rest/pom.xml b/framework/src/onos/utils/rest/pom.xml
deleted file mode 100644
index 80a2e32e..00000000
--- a/framework/src/onos/utils/rest/pom.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-rest</artifactId>
- <packaging>bundle</packaging>
-
- <description>ON.Lab JAX-RS utilities</description>
-
- <dependencies>
- <dependency>
- <groupId>com.sun.jersey.jersey-test-framework</groupId>
- <artifactId>jersey-test-framework-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey.jersey-test-framework</groupId>
- <artifactId>jersey-test-framework-grizzly2</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-osgi</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/BaseResource.java b/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/BaseResource.java
deleted file mode 100644
index 50b4d0f1..00000000
--- a/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/BaseResource.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.rest;
-
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onlab.osgi.ServiceDirectory;
-
-import javax.ws.rs.core.Response;
-
-/**
- * Base abstraction of a JAX-RS resource.
- */
-public abstract class BaseResource {
-
- private static ServiceDirectory services = new DefaultServiceDirectory();
-
- /**
- * Sets alternate service directory to be used for lookups.
- * <p>
- * Intended to ease unit testing and not intended for use in production.
- * </p>
- *
- * @param serviceDirectory alternate service directory
- */
- public static void setServiceDirectory(ServiceDirectory serviceDirectory) {
- services = serviceDirectory;
- }
-
- /**
- * Returns reference to the specified service implementation.
- *
- * @param service service class
- * @param <T> type of service
- * @return service implementation
- */
- public <T> T get(Class<T> service) {
- return services.get(service);
- }
-
- protected static Response.ResponseBuilder ok(Object obj) {
- return Response.ok(obj);
- }
-
-}
diff --git a/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/package-info.java b/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/package-info.java
deleted file mode 100644
index 4f9c523d..00000000
--- a/framework/src/onos/utils/rest/src/main/java/org/onlab/rest/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Facilities for building JAX-RS web resources.
- */
-package org.onlab.rest;
diff --git a/framework/src/onos/utils/stc/bin/stc b/framework/src/onos/utils/stc/bin/stc
deleted file mode 100755
index 541ddcbb..00000000
--- a/framework/src/onos/utils/stc/bin/stc
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-# System Test Coordinator
-#-------------------------------------------------------------------------------
-
-STC_ROOT=${STC_ROOT:-$(dirname $0)/..}
-cd $STC_ROOT
-VER=1.4.0-rc1
-
-PATH=$PWD/bin:$PATH
-
-java -jar target/onlab-stc-$VER.jar "$@"
diff --git a/framework/src/onos/utils/stc/bin/stc-launcher b/framework/src/onos/utils/stc/bin/stc-launcher
deleted file mode 100755
index 0d56017e..00000000
--- a/framework/src/onos/utils/stc/bin/stc-launcher
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-# System Test Coordinator process launcher
-#-------------------------------------------------------------------------------
-
-env=$1 && shift
-cwd=$1 && shift
-
-if [ $env != "-" ]; then
- [ ! -f $env ] && echo "$env file not found" && exit 1
- source $env
-fi
-
-if [ $cwd != "-" ]; then
- [ ! -d $cwd ] && echo "$cwd directory not found" && exit 1
- cd $cwd
-fi
-
-"$@" 2>&1
diff --git a/framework/src/onos/utils/stc/pom.xml b/framework/src/onos/utils/stc/pom.xml
deleted file mode 100644
index 568aa74c..00000000
--- a/framework/src/onos/utils/stc/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-stc</artifactId>
- <packaging>jar</packaging>
-
- <description>System Test Coordinator</description>
-
- <dependencies>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-misc</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>commons-configuration</groupId>
- <artifactId>commons-configuration</artifactId>
- </dependency>
-
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.4.2</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.4.2</version>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>8.1.17.v20150415</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlet</artifactId>
- <version>8.1.17.v20150415</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-websocket</artifactId>
- <version>8.1.17.v20150415</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.onlab.stc.Main
- </mainClass>
- </transformer>
- </transformers>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/utils/stc/sample/scenario.xml b/framework/src/onos/utils/stc/sample/scenario.xml
deleted file mode 100644
index 8cee6319..00000000
--- a/framework/src/onos/utils/stc/sample/scenario.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="sample" description="Sample Test Scenario">
- <step name="alpha" exec="/bin/ls -l"/>
- <step name="beta" exec="/bin/ls -lF"/>
- <step name="gamma" exec="/bin/ls" requires="alpha,beta"/>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Compiler.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Compiler.java
deleted file mode 100644
index 919cbd5b..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Compiler.java
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.onlab.graph.DepthFirstSearch;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.*;
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.graph.DepthFirstSearch.EdgeType.BACK_EDGE;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Entity responsible for loading a scenario and producing a redy-to-execute
- * process flow graph.
- */
-public class Compiler {
-
- private static final String DEFAULT_LOG_DIR = "${WORKSPACE}/tmp/stc/";
-
- private static final String IMPORT = "import";
- private static final String GROUP = "group";
- private static final String STEP = "step";
- private static final String PARALLEL = "parallel";
- private static final String SEQUENTIAL = "sequential";
- private static final String DEPENDENCY = "dependency";
-
- private static final String LOG_DIR = "[@logDir]";
- private static final String NAME = "[@name]";
- private static final String COMMAND = "[@exec]";
- private static final String ENV = "[@env]";
- private static final String CWD = "[@cwd]";
- private static final String REQUIRES = "[@requires]";
- private static final String IF = "[@if]";
- private static final String UNLESS = "[@unless]";
- private static final String VAR = "[@var]";
- private static final String STARTS = "[@starts]";
- private static final String ENDS = "[@ends]";
- private static final String FILE = "[@file]";
- private static final String NAMESPACE = "[@namespace]";
-
- static final String PROP_START = "${";
- static final String PROP_END = "}";
-
- private static final String HASH = "#";
- private static final String HASH_PREV = "#-1";
-
- private final Scenario scenario;
-
- private final Map<String, Step> steps = Maps.newHashMap();
- private final Map<String, Step> inactiveSteps = Maps.newHashMap();
- private final Map<String, String> requirements = Maps.newHashMap();
- private final Set<Dependency> dependencies = Sets.newHashSet();
- private final List<Integer> clonables = Lists.newArrayList();
-
- private ProcessFlow processFlow;
- private File logDir;
-
- private String previous = null;
- private String pfx = "";
- private boolean debugOn = System.getenv("debug") != null;
-
- /**
- * Creates a new compiler for the specified scenario.
- *
- * @param scenario scenario to be compiled
- */
- public Compiler(Scenario scenario) {
- this.scenario = scenario;
- }
-
- /**
- * Returns the scenario being compiled.
- *
- * @return test scenario
- */
- public Scenario scenario() {
- return scenario;
- }
-
- /**
- * Compiles the specified scenario to produce a final process flow graph.
- */
- public void compile() {
- compile(scenario.definition(), null, null);
- compileRequirements();
-
- // Produce the process flow
- processFlow = new ProcessFlow(ImmutableSet.copyOf(steps.values()),
- ImmutableSet.copyOf(dependencies));
-
- scanForCycles();
-
- // Extract the log directory if there was one specified
- String defaultPath = DEFAULT_LOG_DIR + scenario.name();
- String path = scenario.definition().getString(LOG_DIR, defaultPath);
- logDir = new File(expand(path));
- }
-
- /**
- * Returns the step with the specified name.
- *
- * @param name step or group name
- * @return test step or group
- */
- public Step getStep(String name) {
- return steps.get(name);
- }
-
- /**
- * Returns the process flow generated from this scenario definition.
- *
- * @return process flow as a graph
- */
- public ProcessFlow processFlow() {
- return processFlow;
- }
-
- /**
- * Returns the log directory where scenario logs should be kept.
- *
- * @return scenario logs directory
- */
- public File logDir() {
- return logDir;
- }
-
- /**
- * Recursively elaborates this definition to produce a final process flow graph.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void compile(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String opfx = pfx;
- pfx = pfx + ">";
- print("pfx=%s namespace=%s", pfx, namespace);
-
- // Scan all imports
- cfg.configurationsAt(IMPORT)
- .forEach(c -> processImport(c, namespace, parentGroup));
-
- // Scan all steps
- cfg.configurationsAt(STEP)
- .forEach(c -> processStep(c, namespace, parentGroup));
-
- // Scan all groups
- cfg.configurationsAt(GROUP)
- .forEach(c -> processGroup(c, namespace, parentGroup));
-
- // Scan all parallel groups
- cfg.configurationsAt(PARALLEL)
- .forEach(c -> processParallelGroup(c, namespace, parentGroup));
-
- // Scan all sequential groups
- cfg.configurationsAt(SEQUENTIAL)
- .forEach(c -> processSequentialGroup(c, namespace, parentGroup));
-
- // Scan all dependencies
- cfg.configurationsAt(DEPENDENCY)
- .forEach(c -> processDependency(c, namespace));
-
- pfx = opfx;
- }
-
- /**
- * Compiles requirements for all steps and groups accrued during the
- * overall compilation process.
- */
- private void compileRequirements() {
- requirements.forEach((name, requires) ->
- compileRequirements(getStep(name), requires));
- }
-
- private void compileRequirements(Step src, String requires) {
- split(requires).forEach(n -> {
- boolean isSoft = n.startsWith("~");
- String name = n.replaceFirst("^~", "");
- Step dst = getStep(name);
- if (dst != null) {
- dependencies.add(new Dependency(src, dst, isSoft));
- }
- });
- }
-
- /**
- * Processes an import directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void processImport(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String file = checkNotNull(expand(cfg.getString(FILE)),
- "Import directive must specify 'file'");
- String newNamespace = expand(prefix(cfg.getString(NAMESPACE), namespace));
- print("import file=%s namespace=%s", file, newNamespace);
- try {
- Scenario importScenario = loadScenario(new FileInputStream(file));
- compile(importScenario.definition(), newNamespace, parentGroup);
- } catch (IOException e) {
- throw new IllegalArgumentException("Unable to import scenario", e);
- }
- }
-
- /**
- * Processes a step directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void processStep(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String name = expand(prefix(cfg.getString(NAME), namespace));
- String command = expand(cfg.getString(COMMAND, parentGroup != null ? parentGroup.command() : null), true);
- String env = expand(cfg.getString(ENV, parentGroup != null ? parentGroup.env() : null));
- String cwd = expand(cfg.getString(CWD, parentGroup != null ? parentGroup.cwd() : null));
-
- print("step name=%s command=%s env=%s cwd=%s", name, command, env, cwd);
- Step step = new Step(name, command, env, cwd, parentGroup);
- registerStep(step, cfg, namespace, parentGroup);
- }
-
- /**
- * Processes a group directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void processGroup(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String name = expand(prefix(cfg.getString(NAME), namespace));
- String command = expand(cfg.getString(COMMAND, parentGroup != null ? parentGroup.command() : null), true);
- String env = expand(cfg.getString(ENV, parentGroup != null ? parentGroup.env() : null));
- String cwd = expand(cfg.getString(CWD, parentGroup != null ? parentGroup.cwd() : null));
-
- print("group name=%s command=%s env=%s cwd=%s", name, command, env, cwd);
- Group group = new Group(name, command, env, cwd, parentGroup);
- if (registerStep(group, cfg, namespace, parentGroup)) {
- compile(cfg, namespace, group);
- }
- }
-
- /**
- * Registers the specified step or group.
- *
- * @param step step or group
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- * @return true of the step or group was registered as active
- */
- private boolean registerStep(Step step, HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- checkState(!steps.containsKey(step.name()), "Step %s already exists", step.name());
- String ifClause = expand(cfg.getString(IF));
- String unlessClause = expand(cfg.getString(UNLESS));
-
- if ((ifClause != null && ifClause.length() == 0) ||
- (unlessClause != null && unlessClause.length() > 0) ||
- (parentGroup != null && inactiveSteps.containsValue(parentGroup))) {
- inactiveSteps.put(step.name(), step);
- return false;
- }
-
- if (parentGroup != null) {
- parentGroup.addChild(step);
- }
-
- steps.put(step.name(), step);
- processRequirements(step, expand(cfg.getString(REQUIRES)), namespace);
- previous = step.name();
- return true;
- }
-
- /**
- * Processes a parallel clone group directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void processParallelGroup(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String var = cfg.getString(VAR);
- print("parallel var=%s", var);
-
- int i = 1;
- while (condition(var, i).length() > 0) {
- clonables.add(0, i);
- compile(cfg, namespace, parentGroup);
- clonables.remove(0);
- i++;
- }
- }
-
- /**
- * Processes a sequential clone group directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- * @param parentGroup optional parent group
- */
- private void processSequentialGroup(HierarchicalConfiguration cfg,
- String namespace, Group parentGroup) {
- String var = cfg.getString(VAR);
- String starts = cfg.getString(STARTS);
- String ends = cfg.getString(ENDS);
- print("sequential var=%s", var);
-
- int i = 1;
- while (condition(var, i).length() > 0) {
- clonables.add(0, i);
- compile(cfg, namespace, parentGroup);
- if (i > 1) {
- processSequentialRequirements(starts, ends, namespace);
- }
- clonables.remove(0);
- i++;
- }
- }
-
- /**
- * Hooks starts of this sequence tier to the previous tier.
- *
- * @param starts comma-separated list of start steps
- * @param ends comma-separated list of end steps
- * @param namespace optional namespace
- */
- private void processSequentialRequirements(String starts, String ends,
- String namespace) {
- for (String s : split(starts)) {
- String start = expand(prefix(s, namespace));
- String reqs = requirements.get(s);
- for (String n : split(ends)) {
- boolean isSoft = n.startsWith("~");
- String name = n.replaceFirst("^~", "");
- name = (isSoft ? "~" : "") + expand(prefix(name, namespace));
- reqs = reqs == null ? name : (reqs + "," + name);
- }
- requirements.put(start, reqs);
- }
- }
-
- /**
- * Returns the elaborated repetition construct conditional.
- *
- * @param var repetition var property
- * @param i index to elaborate
- * @return elaborated string
- */
- private String condition(String var, Integer i) {
- return expand(var.replaceFirst("#", i.toString())).trim();
- }
-
- /**
- * Processes a dependency directive.
- *
- * @param cfg hierarchical definition
- * @param namespace optional namespace
- */
- private void processDependency(HierarchicalConfiguration cfg, String namespace) {
- String name = expand(prefix(cfg.getString(NAME), namespace));
- String requires = expand(cfg.getString(REQUIRES));
-
- print("dependency name=%s requires=%s", name, requires);
- Step step = getStep(name, namespace);
- if (!inactiveSteps.containsValue(step)) {
- processRequirements(step, requires, namespace);
- }
- }
-
- /**
- * Processes the specified requiremenst string and adds dependency for
- * each requirement of the given step.
- *
- * @param src source step
- * @param requires comma-separated list of required steps
- * @param namespace optional namespace
- */
- private void processRequirements(Step src, String requires, String namespace) {
- String reqs = requirements.get(src.name());
- for (String n : split(requires)) {
- boolean isSoft = n.startsWith("~");
- String name = n.replaceFirst("^~", "");
- name = previous != null && name.equals("^") ? previous : name;
- name = (isSoft ? "~" : "") + expand(prefix(name, namespace));
- reqs = reqs == null ? name : (reqs + "," + name);
- }
- requirements.put(src.name(), reqs);
- }
-
- /**
- * Retrieves the step or group with the specified name.
- *
- * @param name step or group name
- * @param namespace optional namespace
- * @return step or group; null if none found in active or inactive steps
- */
- private Step getStep(String name, String namespace) {
- String dName = prefix(name, namespace);
- Step step = steps.get(dName);
- step = step != null ? step : inactiveSteps.get(dName);
- checkArgument(step != null, "Unknown step %s", dName);
- return step;
- }
-
- /**
- * Prefixes the specified name with the given namespace.
- *
- * @param name name of a step or a group
- * @param namespace optional namespace
- * @return composite name
- */
- private String prefix(String name, String namespace) {
- return isNullOrEmpty(namespace) ? name : namespace + "." + name;
- }
-
- /**
- * Expands any environment variables in the specified string. These are
- * specified as ${property} tokens.
- *
- * @param string string to be processed
- * @param keepTokens true if the original unresolved tokens should be kept
- * @return original string with expanded substitutions
- */
- private String expand(String string, boolean... keepTokens) {
- if (string == null) {
- return null;
- }
-
- String pString = string;
- StringBuilder sb = new StringBuilder();
- int start, end, last = 0;
- while ((start = pString.indexOf(PROP_START, last)) >= 0) {
- end = pString.indexOf(PROP_END, start + PROP_START.length());
- checkArgument(end > start, "Malformed property in %s", pString);
- sb.append(pString.substring(last, start));
- String prop = pString.substring(start + PROP_START.length(), end);
- String value;
- if (prop.equals(HASH)) {
- value = Integer.toString(clonables.get(0));
- } else if (prop.equals(HASH_PREV)) {
- value = Integer.toString(clonables.get(0) - 1);
- } else if (prop.endsWith(HASH)) {
- pString = pString.replaceFirst("#}", clonables.get(0) + "}");
- last = start;
- continue;
- } else {
- // Try system property first, then fall back to env. variable.
- value = System.getProperty(prop);
- if (value == null) {
- value = System.getenv(prop);
- }
- }
- if (value == null && keepTokens.length == 1 && keepTokens[0]) {
- sb.append("${").append(prop).append("}");
- } else {
- sb.append(value != null ? value : "");
- }
- last = end + 1;
- }
- sb.append(pString.substring(last));
- return sb.toString().replace('\n', ' ').replace('\r', ' ');
- }
-
- /**
- * Splits the comma-separated string into a list of strings.
- *
- * @param string string to split
- * @return list of strings
- */
- private List<String> split(String string) {
- ImmutableList.Builder<String> builder = ImmutableList.builder();
- String[] fields = string != null ? string.split(",") : new String[0];
- for (String field : fields) {
- builder.add(field.trim());
- }
- return builder.build();
- }
-
- /**
- * Scans the process flow graph for cyclic dependencies.
- */
- private void scanForCycles() {
- DepthFirstSearch<Step, Dependency> dfs = new DepthFirstSearch<>();
- // Use a brute-force method of searching paths from all vertices.
- processFlow().getVertexes().forEach(s -> {
- DepthFirstSearch<Step, Dependency>.SpanningTreeResult r =
- dfs.search(processFlow, s, null, null, ALL_PATHS);
- r.edges().forEach((e, et) -> checkArgument(et != BACK_EDGE,
- "Process flow has a cycle involving dependency from %s to %s",
- e.src().name, e.dst().name));
- });
- }
-
-
- /**
- * Prints formatted output.
- *
- * @param format printf format string
- * @param args arguments to be printed
- */
- private void print(String format, Object... args) {
- if (debugOn) {
- System.err.println(pfx + String.format(format, args));
- }
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java
deleted file mode 100644
index 228e7834..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Coordinator.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newFixedThreadPool;
-import static org.onlab.stc.Compiler.PROP_END;
-import static org.onlab.stc.Compiler.PROP_START;
-import static org.onlab.stc.Coordinator.Directive.*;
-import static org.onlab.stc.Coordinator.Status.*;
-
-/**
- * Coordinates execution of a scenario process flow.
- */
-public class Coordinator {
-
- private static final int MAX_THREADS = 64;
-
- private final ExecutorService executor = newFixedThreadPool(MAX_THREADS);
-
- private final ProcessFlow processFlow;
-
- private final StepProcessListener delegate;
- private final CountDownLatch latch;
- private final ScenarioStore store;
-
- private static final Pattern PROP_ERE = Pattern.compile("^@stc ([a-zA-Z0-9_.]+)=(.*$)");
- private final Map<String, String> properties = Maps.newConcurrentMap();
-
- private final Set<StepProcessListener> listeners = Sets.newConcurrentHashSet();
- private File logDir;
-
- /**
- * Represents action to be taken on a test step.
- */
- public enum Directive {
- NOOP, RUN, SKIP
- }
-
- /**
- * Represents processor state.
- */
- public enum Status {
- WAITING, IN_PROGRESS, SUCCEEDED, FAILED, SKIPPED
- }
-
- /**
- * Creates a process flow coordinator.
- *
- * @param scenario test scenario to coordinate
- * @param processFlow process flow to coordinate
- * @param logDir scenario log directory
- */
- public Coordinator(Scenario scenario, ProcessFlow processFlow, File logDir) {
- this.processFlow = processFlow;
- this.logDir = logDir;
- this.store = new ScenarioStore(processFlow, logDir, scenario.name());
- this.delegate = new Delegate();
- this.latch = new CountDownLatch(1);
- }
-
- /**
- * Resets any previously accrued status and events.
- */
- public void reset() {
- store.reset();
- }
-
- /**
- * Resets all previously accrued status and events for steps that lie
- * in the range between the steps or groups whose names match the specified
- * patterns.
- *
- * @param runFromPatterns list of starting step patterns
- * @param runToPatterns list of ending step patterns
- */
- public void reset(List<String> runFromPatterns, List<String> runToPatterns) {
- List<Step> fromSteps = matchSteps(runFromPatterns);
- List<Step> toSteps = matchSteps(runToPatterns);
-
- // FIXME: implement this
- }
-
- /**
- * Returns number of milliseconds it took to execute.
- *
- * @return number of millis elapsed during the run
- */
- public long duration() {
- return store.endTime() - store.startTime();
- }
-
- /**
- * Returns a list of steps that match the specified list of patterns.
- *
- * @param runToPatterns list of patterns
- * @return list of steps with matching names
- */
- private List<Step> matchSteps(List<String> runToPatterns) {
- ImmutableList.Builder<Step> builder = ImmutableList.builder();
- store.getSteps().forEach(step -> {
- runToPatterns.forEach(p -> {
- if (step.name().matches(p)) {
- builder.add(step);
- }
- });
- });
- return builder.build();
- }
-
- /**
- * Starts execution of the process flow graph.
- */
- public void start() {
- executeRoots(null);
- }
-
- /**
- * Waits for completion of the entire process flow.
- *
- * @return exit code to use
- * @throws InterruptedException if interrupted while waiting for completion
- */
- public int waitFor() throws InterruptedException {
- while (!store.isComplete()) {
- latch.await(1, TimeUnit.SECONDS);
- }
- return store.hasFailures() ? 1 : 0;
- }
-
- /**
- * Returns set of all test steps.
- *
- * @return set of steps
- */
- public Set<Step> getSteps() {
- return store.getSteps();
- }
-
- /**
- * Returns a chronological list of step or group records.
- *
- * @return list of events
- */
- List<StepEvent> getRecords() {
- return store.getEvents();
- }
-
- /**
- * Returns the status record of the specified test step.
- *
- * @param step test step or group
- * @return step status record
- */
- public Status getStatus(Step step) {
- return store.getStatus(step);
- }
-
- /**
- * Adds the specified listener.
- *
- * @param listener step process listener
- */
- public void addListener(StepProcessListener listener) {
- listeners.add(checkNotNull(listener, "Listener cannot be null"));
- }
-
- /**
- * Removes the specified listener.
- *
- * @param listener step process listener
- */
- public void removeListener(StepProcessListener listener) {
- listeners.remove(checkNotNull(listener, "Listener cannot be null"));
- }
-
- /**
- * Executes the set of roots in the scope of the specified group or globally
- * if no group is given.
- *
- * @param group optional group
- */
- private void executeRoots(Group group) {
- // FIXME: add ability to skip past completed steps
- Set<Step> steps =
- group != null ? group.children() : processFlow.getVertexes();
- steps.forEach(step -> {
- if (processFlow.getEdgesFrom(step).isEmpty() && step.group() == group) {
- execute(step);
- }
- });
- }
-
- /**
- * Executes the specified step.
- *
- * @param step step to execute
- */
- private synchronized void execute(Step step) {
- Directive directive = nextAction(step);
- if (directive == RUN) {
- store.markStarted(step);
- if (step instanceof Group) {
- Group group = (Group) step;
- delegate.onStart(group, null);
- executeRoots(group);
- } else {
- executor.execute(new StepProcessor(step, logDir, delegate,
- substitute(step.command())));
- }
- } else if (directive == SKIP) {
- skipStep(step);
- }
- }
-
- /**
- * Recursively skips the specified step or group and any steps/groups within.
- *
- * @param step step or group
- */
- private void skipStep(Step step) {
- if (step instanceof Group) {
- Group group = (Group) step;
- store.markComplete(step, SKIPPED);
- group.children().forEach(this::skipStep);
- }
- delegate.onCompletion(step, SKIPPED);
-
- }
-
- /**
- * Determines the state of the specified step.
- *
- * @param step test step
- * @return state of the step process
- */
- private Directive nextAction(Step step) {
- Status status = store.getStatus(step);
- if (status != WAITING) {
- return NOOP;
- }
-
- for (Dependency dependency : processFlow.getEdgesFrom(step)) {
- Status depStatus = store.getStatus(dependency.dst());
- if (depStatus == WAITING || depStatus == IN_PROGRESS) {
- return NOOP;
- } else if (((depStatus == FAILED || depStatus == SKIPPED) && !dependency.isSoft()) ||
- (step.group() != null && store.getStatus(step.group()) == SKIPPED)) {
- return SKIP;
- }
- }
- return RUN;
- }
-
- /**
- * Executes the successors to the specified step.
- *
- * @param step step whose successors are to be executed
- */
- private void executeSucessors(Step step) {
- processFlow.getEdgesTo(step).forEach(dependency -> execute(dependency.src()));
- completeParentIfNeeded(step.group());
- }
-
- /**
- * Checks whether the specified parent group, if any, should be marked
- * as complete.
- *
- * @param group parent group that should be checked
- */
- private synchronized void completeParentIfNeeded(Group group) {
- if (group != null && getStatus(group) == IN_PROGRESS) {
- boolean done = true;
- boolean failed = false;
- for (Step child : group.children()) {
- Status status = store.getStatus(child);
- done = done && (status == SUCCEEDED || status == FAILED || status == SKIPPED);
- failed = failed || status == FAILED;
- }
- if (done) {
- delegate.onCompletion(group, failed ? FAILED : SUCCEEDED);
- }
- }
- }
-
- /**
- * Expands the var references with values from the properties map.
- *
- * @param string string to perform substitutions on
- */
- private String substitute(String string) {
- StringBuilder sb = new StringBuilder();
- int start, end, last = 0;
- while ((start = string.indexOf(PROP_START, last)) >= 0) {
- end = string.indexOf(PROP_END, start + PROP_START.length());
- checkArgument(end > start, "Malformed property in %s", string);
- sb.append(string.substring(last, start));
- String prop = string.substring(start + PROP_START.length(), end);
- String value = properties.get(prop);
- sb.append(value != null ? value : "");
- last = end + 1;
- }
- sb.append(string.substring(last));
- return sb.toString().replace('\n', ' ').replace('\r', ' ');
- }
-
- /**
- * Scrapes the line of output for any variables to be captured and posted
- * in the properties for later use.
- *
- * @param line line of output to scrape for property exports
- */
- private void scrapeForVariables(String line) {
- Matcher matcher = PROP_ERE.matcher(line);
- if (matcher.matches()) {
- String prop = matcher.group(1);
- String value = matcher.group(2);
- properties.put(prop, value);
- }
- }
-
-
- /**
- * Prints formatted output.
- *
- * @param format printf format string
- * @param args arguments to be printed
- */
- public static void print(String format, Object... args) {
- System.out.println(String.format(format, args));
- }
-
- /**
- * Internal delegate to monitor the process execution.
- */
- private class Delegate implements StepProcessListener {
- @Override
- public void onStart(Step step, String command) {
- listeners.forEach(listener -> listener.onStart(step, command));
- }
-
- @Override
- public void onCompletion(Step step, Status status) {
- store.markComplete(step, status);
- listeners.forEach(listener -> listener.onCompletion(step, status));
- executeSucessors(step);
- if (store.isComplete()) {
- latch.countDown();
- }
- }
-
- @Override
- public void onOutput(Step step, String line) {
- scrapeForVariables(line);
- listeners.forEach(listener -> listener.onOutput(step, line));
- }
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Dependency.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Dependency.java
deleted file mode 100644
index 9025d2e5..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Dependency.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.base.MoreObjects;
-import org.onlab.graph.AbstractEdge;
-
-import java.util.Objects;
-
-/**
- * Representation of a dependency from one step on completion of another.
- */
-public class Dependency extends AbstractEdge<Step> {
-
- private boolean isSoft;
-
- /**
- * Creates a new edge between the specified source and destination vertexes.
- *
- * @param src source vertex
- * @param dst destination vertex
- * @param isSoft indicates whether this is a hard or soft dependency
- */
- public Dependency(Step src, Step dst, boolean isSoft) {
- super(src, dst);
- this.isSoft = isSoft;
- }
-
- /**
- * Indicates whether this is a soft or hard dependency, i.e. one that
- * requires successful completion of the dependency or just any completion.
- *
- * @return true if dependency is a soft one
- */
- public boolean isSoft() {
- return isSoft;
- }
-
- @Override
- public int hashCode() {
- return 31 * super.hashCode() + Objects.hash(isSoft);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Dependency) {
- final Dependency other = (Dependency) obj;
- return super.equals(other) && Objects.equals(this.isSoft, other.isSoft);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("name", src().name())
- .add("requires", dst().name())
- .add("isSoft", isSoft)
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Group.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Group.java
deleted file mode 100644
index 0281c364..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Group.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * Represenation of a related group of steps.
- */
-public class Group extends Step {
-
- private final Set<Step> children = Sets.newHashSet();
-
- /**
- * Creates a new test step.
- *
- * @param name group name
- * @param command default command
- * @param env default path to file to be sourced into the environment
- * @param cwd default path to current working directory for the step
- * @param group optional group to which this step belongs
- */
- public Group(String name, String command, String env, String cwd, Group group) {
- super(name, command, env, cwd, group);
- }
-
- /**
- * Returns the set of child steps and groups contained within this group.
- *
- * @return set of children
- */
- public Set<Step> children() {
- return ImmutableSet.copyOf(children);
- }
-
- /**
- * Adds the specified step or group as a child of this group.
- *
- * @param child child step or group to add
- */
- public void addChild(Step child) {
- children.add(child);
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java
deleted file mode 100644
index ca04a7c2..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Main.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHandler;
-import org.eclipse.jetty.util.log.Logger;
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import static java.lang.System.currentTimeMillis;
-import static org.onlab.stc.Coordinator.Status.*;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Main program for executing system test coordinator.
- */
-public final class Main {
-
- private static final String NONE = "\u001B[0m";
- private static final String GRAY = "\u001B[30;1m";
- private static final String RED = "\u001B[31;1m";
- private static final String GREEN = "\u001B[32;1m";
- private static final String BLUE = "\u001B[36m";
-
- private static final String SUCCESS_SUMMARY =
- "%s %sPassed! %d steps succeeded%s";
- private static final String MIXED_SUMMARY =
- "%s%d steps succeeded; %s%d steps failed; %s%d steps skipped%s";
- private static final String FAILURE_SUMMARY = "%s %sFailed! " + MIXED_SUMMARY;
- private static final String ABORTED_SUMMARY = "%s %sAborted! " + MIXED_SUMMARY;
-
- private boolean isReported = false;
-
- private enum Command {
- LIST, RUN, RUN_RANGE, HELP
- }
-
- private final String scenarioFile;
-
- private Command command = Command.HELP;
- private String runFromPatterns = "";
- private String runToPatterns = "";
-
- private Coordinator coordinator;
- private Compiler compiler;
- private Monitor monitor;
- private Listener delegate = new Listener();
-
- private static boolean useColor = Objects.equals("true", System.getenv("stcColor"));
- private static boolean dumpLogs = Objects.equals("true", System.getenv("stcDumpLogs"));
-
- // usage: stc [<scenario-file>] [run]
- // usage: stc [<scenario-file>] run [from <from-patterns>] [to <to-patterns>]]
- // usage: stc [<scenario-file>] list
-
- // Public construction forbidden
- private Main(String[] args) {
- this.scenarioFile = args[0];
-
- if (args.length <= 1 || args.length == 2 && args[1].equals("run")) {
- command = Command.RUN;
- } else if (args.length == 2 && args[1].equals("list")) {
- command = Command.LIST;
- } else if (args.length >= 4 && args[1].equals("run")) {
- int i = 2;
- if (args[i].equals("from")) {
- command = Command.RUN_RANGE;
- runFromPatterns = args[i + 1];
- i += 2;
- }
-
- if (args.length >= i + 2 && args[i].equals("to")) {
- command = Command.RUN_RANGE;
- runToPatterns = args[i + 1];
- }
- }
- }
-
- /**
- * Main entry point for coordinating test scenario execution.
- *
- * @param args command-line arguments
- */
- public static void main(String[] args) {
- Main main = new Main(args);
- main.run();
- }
-
- // Runs the scenario processing
- private void run() {
- try {
- // Load scenario
- Scenario scenario = Scenario.loadScenario(new FileInputStream(scenarioFile));
-
- // Elaborate scenario
- compiler = new Compiler(scenario);
- compiler.compile();
-
- // Setup the process flow coordinator
- coordinator = new Coordinator(scenario, compiler.processFlow(),
- compiler.logDir());
- coordinator.addListener(delegate);
-
- // Prepare the GUI monitor
- monitor = new Monitor(coordinator, compiler);
- startMonitorServer(monitor);
-
- // Execute process flow
- processCommand();
-
- } catch (FileNotFoundException e) {
- print("Unable to find scenario file %s", scenarioFile);
- }
- }
-
- // Initiates a web-server for the monitor GUI.
- private static void startMonitorServer(Monitor monitor) {
- org.eclipse.jetty.util.log.Log.setLog(new NullLogger());
- Server server = new Server(9999);
- ServletHandler handler = new ServletHandler();
- server.setHandler(handler);
- MonitorWebSocketServlet.setMonitor(monitor);
- handler.addServletWithMapping(MonitorWebSocketServlet.class, "/*");
- try {
- server.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // Processes the appropriate command
- private void processCommand() {
- switch (command) {
- case RUN:
- processRun();
- break;
- case LIST:
- processList();
- break;
- case RUN_RANGE:
- processRunRange();
- break;
- default:
- print("Unsupported command %s", command);
- }
- }
-
- // Processes the scenario 'run' command.
- private void processRun() {
- coordinator.reset();
- runCoordinator();
- }
-
- // Processes the scenario 'run' command for range of steps.
- private void processRunRange() {
- coordinator.reset(list(runFromPatterns), list(runToPatterns));
- runCoordinator();
- }
-
- // Processes the scenario 'list' command.
- private void processList() {
- coordinator.getRecords()
- .forEach(event -> logStatus(event.time(), event.name(), event.status(), event.command()));
- printSummary(0, false);
- System.exit(0);
- }
-
- // Runs the coordinator and waits for it to finish.
- private void runCoordinator() {
- try {
- Runtime.getRuntime().addShutdownHook(new ShutdownHook());
- coordinator.start();
- int exitCode = coordinator.waitFor();
- pause(100); // allow stdout to flush
- printSummary(exitCode, false);
- System.exit(exitCode);
- } catch (InterruptedException e) {
- print("Unable to execute scenario %s", scenarioFile);
- }
- }
-
- private synchronized void printSummary(int exitCode, boolean isAborted) {
- if (!isReported) {
- isReported = true;
- Set<Step> steps = coordinator.getSteps();
- String duration = formatDuration((int) (coordinator.duration() / 1_000));
- int count = steps.size();
- if (exitCode == 0) {
- print(SUCCESS_SUMMARY, duration, color(SUCCEEDED), count, color(null));
- } else {
- long success = steps.stream().filter(s -> coordinator.getStatus(s) == SUCCEEDED).count();
- long failed = steps.stream().filter(s -> coordinator.getStatus(s) == FAILED).count();
- long skipped = steps.stream().filter(s -> coordinator.getStatus(s) == SKIPPED).count();
- print(isAborted ? ABORTED_SUMMARY : FAILURE_SUMMARY, duration,
- color(FAILED), color(SUCCEEDED), success,
- color(FAILED), failed, color(SKIPPED), skipped, color(null));
- }
- }
- }
-
- /**
- * Internal delegate to monitor the process execution.
- */
- private class Listener implements StepProcessListener {
- @Override
- public void onStart(Step step, String command) {
- logStatus(currentTimeMillis(), step.name(), IN_PROGRESS, command);
- }
-
- @Override
- public void onCompletion(Step step, Status status) {
- logStatus(currentTimeMillis(), step.name(), status, null);
- if (dumpLogs && !(step instanceof Group) && status == FAILED) {
- dumpLogs(step);
- }
- }
-
- @Override
- public void onOutput(Step step, String line) {
- }
- }
-
- // Logs the step status.
- private static void logStatus(long time, String name, Status status, String cmd) {
- if (cmd != null) {
- print("%s %s%s %s%s -- %s", time(time), color(status), name, action(status), color(null), cmd);
- } else {
- print("%s %s%s %s%s", time(time), color(status), name, action(status), color(null));
- }
- }
-
- // Dumps the step logs to standard output.
- private void dumpLogs(Step step) {
- File logFile = new File(compiler.logDir(), step.name() + ".log");
- try {
- print(">>>>>");
- Files.copy(logFile, System.out);
- print("<<<<<");
- } catch (IOException e) {
- print("Unable to dump log file %s", logFile.getName());
- }
- }
-
- // Produces a description of event using the specified step status.
- private static String action(Status status) {
- return status == IN_PROGRESS ? "started" :
- (status == SUCCEEDED ? "completed" :
- (status == FAILED ? "failed" :
- (status == SKIPPED ? "skipped" : "waiting")));
- }
-
- // Produces an ANSI escape code for color using the specified step status.
- private static String color(Status status) {
- if (!useColor) {
- return "";
- }
- return status == null ? NONE :
- (status == IN_PROGRESS ? BLUE :
- (status == SUCCEEDED ? GREEN :
- (status == FAILED ? RED : GRAY)));
- }
-
- // Produces a list from the specified comma-separated string.
- private static List<String> list(String patterns) {
- return ImmutableList.copyOf(patterns.split(","));
- }
-
- // Produces a formatted time stamp.
- private static String time(long time) {
- return new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date(time));
- }
-
- // Pauses for the specified number of millis.
- private static void pause(int ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- print("Interrupted!");
- }
- }
-
- // Formats time duration
- private static String formatDuration(int totalSeconds) {
- int seconds = totalSeconds % 60;
- int totalMinutes = totalSeconds / 60;
- int minutes = totalMinutes % 60;
- int hours = totalMinutes / 60;
- return hours > 0 ?
- String.format("%d:%02d:%02d", hours, minutes, seconds) :
- String.format("%d:%02d", minutes, seconds);
- }
-
- // Shutdown hook to report status even when aborted.
- private class ShutdownHook extends Thread {
- @Override
- public void run() {
- printSummary(1, true);
- }
- }
-
- // Logger to quiet Jetty down
- private static class NullLogger implements Logger {
- @Override
- public String getName() {
- return "quiet";
- }
-
- @Override
- public void warn(String msg, Object... args) {
- }
-
- @Override
- public void warn(Throwable thrown) {
- }
-
- @Override
- public void warn(String msg, Throwable thrown) {
- }
-
- @Override
- public void info(String msg, Object... args) {
- }
-
- @Override
- public void info(Throwable thrown) {
- }
-
- @Override
- public void info(String msg, Throwable thrown) {
- }
-
- @Override
- public boolean isDebugEnabled() {
- return false;
- }
-
- @Override
- public void setDebugEnabled(boolean enabled) {
- }
-
- @Override
- public void debug(String msg, Object... args) {
- }
-
- @Override
- public void debug(Throwable thrown) {
- }
-
- @Override
- public void debug(String msg, Throwable thrown) {
- }
-
- @Override
- public Logger getLogger(String name) {
- return this;
- }
-
- @Override
- public void ignore(Throwable ignored) {
- }
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Monitor.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Monitor.java
deleted file mode 100644
index 4e6f63fa..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Monitor.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-import org.onlab.stc.MonitorLayout.Box;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Map;
-
-import static org.onlab.stc.Coordinator.Status.IN_PROGRESS;
-
-/**
- * Scenario test monitor.
- */
-public class Monitor implements StepProcessListener {
-
- private final ObjectMapper mapper = new ObjectMapper();
-
- private final Coordinator coordinator;
- private final Compiler compiler;
- private final MonitorLayout layout;
-
- private MonitorDelegate delegate;
-
- private Map<Step, Box> boxes = Maps.newHashMap();
-
- /**
- * Creates a new shared process flow monitor.
- *
- * @param coordinator process flow coordinator
- * @param compiler scenario compiler
- */
- Monitor(Coordinator coordinator, Compiler compiler) {
- this.coordinator = coordinator;
- this.compiler = compiler;
- this.layout = new MonitorLayout(compiler);
- coordinator.addListener(this);
- }
-
- /**
- * Sets the process monitor delegate.
- *
- * @param delegate process monitor delegate
- */
- void setDelegate(MonitorDelegate delegate) {
- this.delegate = delegate;
- }
-
- /**
- * Notifies the process monitor delegate with the specified event.
- *
- * @param event JSON event data
- */
- public void notify(ObjectNode event) {
- if (delegate != null) {
- delegate.notify(event);
- }
- }
-
- /**
- * Returns the scenario process flow as JSON data.
- *
- * @return scenario process flow data
- */
- ObjectNode scenarioData() {
- ObjectNode root = mapper.createObjectNode();
- ArrayNode steps = mapper.createArrayNode();
- ArrayNode requirements = mapper.createArrayNode();
-
- ProcessFlow pf = compiler.processFlow();
- pf.getVertexes().forEach(step -> add(step, steps));
- pf.getEdges().forEach(requirement -> add(requirement, requirements));
-
- root.set("steps", steps);
- root.set("requirements", requirements);
-
- try (FileWriter fw = new FileWriter("/tmp/data.json");
- PrintWriter pw = new PrintWriter(fw)) {
- pw.println(root.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- return root;
- }
-
-
- private void add(Step step, ArrayNode steps) {
- Box box = layout.get(step);
- ObjectNode sn = mapper.createObjectNode()
- .put("name", step.name())
- .put("isGroup", step instanceof Group)
- .put("status", status(coordinator.getStatus(step)))
- .put("tier", box.tier())
- .put("depth", box.depth());
- if (step.group() != null) {
- sn.put("group", step.group().name());
- }
- steps.add(sn);
- }
-
- private String status(Coordinator.Status status) {
- return status.toString().toLowerCase();
- }
-
- private void add(Dependency requirement, ArrayNode requirements) {
- ObjectNode rn = mapper.createObjectNode();
- rn.put("src", requirement.src().name())
- .put("dst", requirement.dst().name())
- .put("isSoft", requirement.isSoft());
- requirements.add(rn);
- }
-
- @Override
- public void onStart(Step step, String command) {
- notify(event(step, status(IN_PROGRESS)));
- }
-
- @Override
- public void onCompletion(Step step, Coordinator.Status status) {
- notify(event(step, status(status)));
- }
-
- @Override
- public void onOutput(Step step, String line) {
-
- }
-
- private ObjectNode event(Step step, String status) {
- ObjectNode event = mapper.createObjectNode()
- .put("name", step.name())
- .put("status", status);
- return event;
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java
deleted file mode 100644
index d11542a7..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Delegate to which monitor can send notifications.
- */
-public interface MonitorDelegate {
-
- /**
- * Issues JSON event to be sent to any connected monitor clients.
- *
- * @param event JSON event data
- */
- void notify(ObjectNode event);
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
deleted file mode 100644
index 1c0e7313..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-/**
- * Computes scenario process flow layout for the Monitor GUI.
- */
-public class MonitorLayout {
-
- public static final int WIDTH = 210;
- public static final int HEIGHT = 30;
- public static final int W_GAP = 40;
- public static final int H_GAP = 50;
- public static final int SLOT_WIDTH = WIDTH + H_GAP;
-
- private final Compiler compiler;
- private final ProcessFlow flow;
-
- private Map<Step, Box> boxes = Maps.newHashMap();
-
- /**
- * Creates a new shared process flow monitor.
- *
- * @param compiler scenario compiler
- */
- MonitorLayout(Compiler compiler) {
- this.compiler = compiler;
- this.flow = compiler.processFlow();
-
- // Extract the flow and create initial bounding boxes.
- boxes.put(null, new Box(null, 0));
- flow.getVertexes().forEach(this::createBox);
-
- computeLayout(null, 0, 1);
- }
-
- // Computes the graph layout giving preference to group associations.
- private void computeLayout(Group group, int absoluteTier, int tier) {
- Box box = boxes.get(group);
-
- // Find all children of the group, or items with no group if at top.
- Set<Step> children = group != null ? group.children() :
- flow.getVertexes().stream().filter(s -> s.group() == null)
- .collect(Collectors.toSet());
-
- children.forEach(s -> visit(s, absoluteTier, 1, group));
-
- // Figure out what the group root vertexes are.
- Set<Step> roots = findRoots(group);
-
- // Compute the boxes for each of the roots.
- roots.forEach(s -> updateBox(s, absoluteTier + 1, 1, group));
-
- // Update the tier and depth of the group bounding box.
- computeTiersAndDepth(group, box, absoluteTier, tier, children);
-
- // Compute the minimum breadth of this group's bounding box.
- computeBreadth(group, box, children);
-
- // Compute child placements
- computeChildPlacements(group, box, children);
- }
-
- // Updates the box for the specified step, given the tier number, which
- // is relative to the parent.
- private Box updateBox(Step step, int absoluteTier, int tier, Group group) {
- Box box = boxes.get(step);
- if (step instanceof Group) {
- computeLayout((Group) step, absoluteTier, tier);
- } else {
- box.setTierAndDepth(absoluteTier, tier, 1, group);
- }
-
- // Follow the steps downstream of this one.
- follow(step, absoluteTier + box.depth(), box.tier() + box.depth());
- return box;
- }
-
- // Backwards follows edges leading towards the specified step to visit
- // the source vertex and compute layout of those vertices that had
- // sufficient number of visits to compute their tier.
- private void follow(Step step, int absoluteTier, int tier) {
- Group from = step.group();
- flow.getEdgesTo(step).stream()
- .filter(d -> visit(d.src(), absoluteTier, tier, from))
- .forEach(d -> updateBox(d.src(), absoluteTier, tier, from));
- }
-
- // Visits each step, records maximum tier and returns true if this
- // was the last expected visit.
- private boolean visit(Step step, int absoluteTier, int tier, Group from) {
- Box box = boxes.get(step);
- return box.visitAndLatchMaxTier(absoluteTier, tier, from);
- }
-
- // Computes the absolute and relative tiers and the depth of the group
- // bounding box.
- private void computeTiersAndDepth(Group group, Box box,
- int absoluteTier, int tier, Set<Step> children) {
- int depth = children.stream().mapToInt(this::bottomMostTier).max().getAsInt();
- box.setTierAndDepth(absoluteTier, tier, depth, group);
- }
-
- // Returns the bottom-most tier this step occupies relative to its parent.
- private int bottomMostTier(Step step) {
- Box box = boxes.get(step);
- return box.tier() + box.depth();
- }
-
- // Computes breadth of the specified group.
- private void computeBreadth(Group group, Box box, Set<Step> children) {
- if (box.breadth() == 0) {
- // Scan through all tiers and determine the maximum breadth of each.
- IntStream.range(1, box.depth)
- .forEach(t -> computeTierBreadth(t, box, children));
- box.latchBreadth(children.stream()
- .mapToInt(s -> boxes.get(s).breadth())
- .max().getAsInt());
- }
- }
-
- // Computes tier width.
- private void computeTierBreadth(int t, Box box, Set<Step> children) {
- box.latchBreadth(children.stream().map(boxes::get)
- .filter(b -> isSpanningTier(b, t))
- .mapToInt(Box::breadth).sum());
- }
-
- // Computes the actual child box placements relative to the parent using
- // the previously established tier, depth and breadth attributes.
- private void computeChildPlacements(Group group, Box box,
- Set<Step> children) {
- // Order the root-nodes in alphanumeric order first.
- List<Box> tierBoxes = Lists.newArrayList(boxesOnTier(1, children));
- tierBoxes.sort((a, b) -> a.step().name().compareTo(b.step().name()));
-
- // Place the boxes centered on the parent box; left to right.
- int tierBreadth = tierBoxes.stream().mapToInt(Box::breadth).sum();
- int slot = 1;
- for (Box b : tierBoxes) {
- b.updateCenter(1, slot(slot, tierBreadth));
- slot += b.breadth();
- }
- }
-
- // Returns the horizontal offset off the parent center.
- private int slot(int slot, int tierBreadth) {
- boolean even = tierBreadth % 2 == 0;
- int multiplier = -tierBreadth / 2 + slot - 1;
- return even ? multiplier * SLOT_WIDTH + SLOT_WIDTH / 2 : multiplier * SLOT_WIDTH;
- }
-
- // Returns a list of all child step boxes that start on the specified tier.
- private List<Box> boxesOnTier(int tier, Set<Step> children) {
- return boxes.values().stream()
- .filter(b -> b.tier() == tier && children.contains(b.step()))
- .collect(Collectors.toList());
- }
-
- // Determines whether the specified box spans, or occupies a tier.
- private boolean isSpanningTier(Box b, int tier) {
- return (b.depth() == 1 && b.tier() == tier) ||
- (b.tier() <= tier && tier < b.tier() + b.depth());
- }
-
-
- // Determines roots of the specified group or of the entire graph.
- private Set<Step> findRoots(Group group) {
- Set<Step> steps = group != null ? group.children() : flow.getVertexes();
- return steps.stream().filter(s -> isRoot(s, group)).collect(Collectors.toSet());
- }
-
- private boolean isRoot(Step step, Group group) {
- if (step.group() != group) {
- return false;
- }
-
- Set<Dependency> requirements = flow.getEdgesFrom(step);
- return requirements.stream().filter(r -> r.dst().group() == group)
- .collect(Collectors.toSet()).isEmpty();
- }
-
- /**
- * Returns the bounding box for the specified step. If null is given, it
- * returns the overall bounding box.
- *
- * @param step step or group; null for the overall bounding box
- * @return bounding box
- */
- public Box get(Step step) {
- return boxes.get(step);
- }
-
- /**
- * Returns the bounding box for the specified step name. If null is given,
- * it returns the overall bounding box.
- *
- * @param name name of step or group; null for the overall bounding box
- * @return bounding box
- */
- public Box get(String name) {
- return get(name == null ? null : compiler.getStep(name));
- }
-
- // Creates a bounding box for the specified step or group.
- private void createBox(Step step) {
- boxes.put(step, new Box(step, flow.getEdgesFrom(step).size()));
- }
-
- /**
- * Bounding box data for a step or group.
- */
- final class Box {
-
- private Step step;
- private int remainingRequirements;
-
- private int absoluteTier = 0;
- private int tier;
- private int depth = 1;
- private int breadth;
- private int center, top;
-
- private Box(Step step, int remainingRequirements) {
- this.step = step;
- this.remainingRequirements = remainingRequirements + 1;
- breadth = step == null || step instanceof Group ? 0 : 1;
- }
-
- private void latchTiers(int absoluteTier, int tier, Group from) {
- this.absoluteTier = Math.max(this.absoluteTier, absoluteTier);
- if (step == null || step.group() == from) {
- this.tier = Math.max(this.tier, tier);
- }
- }
-
- public void latchBreadth(int breadth) {
- this.breadth = Math.max(this.breadth, breadth);
- }
-
- void setTierAndDepth(int absoluteTier, int tier, int depth, Group from) {
- latchTiers(absoluteTier, tier, from);
- this.depth = depth;
- }
-
- boolean visitAndLatchMaxTier(int absoluteTier, int tier, Group from) {
- latchTiers(absoluteTier, tier, from);
- --remainingRequirements;
- return remainingRequirements == 0;
- }
-
- Step step() {
- return step;
- }
-
- public int absoluteTier() {
- return absoluteTier;
- }
-
- int tier() {
- return tier;
- }
-
- int depth() {
- return depth;
- }
-
- int breadth() {
- return breadth;
- }
-
- int top() {
- return top;
- }
-
- int center() {
- return center;
- }
-
- public void updateCenter(int top, int center) {
- this.top = top;
- this.center = center;
- }
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java
deleted file mode 100644
index cd146070..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.eclipse.jetty.websocket.WebSocket;
-
-import java.io.IOException;
-
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Web socket capable of interacting with the STC monitor GUI.
- */
-public class MonitorWebSocket implements WebSocket.OnTextMessage, WebSocket.OnControl {
-
- private static final long MAX_AGE_MS = 30_000;
-
- private static final byte PING = 0x9;
- private static final byte PONG = 0xA;
- private static final byte[] PING_DATA = new byte[]{(byte) 0xde, (byte) 0xad};
-
- private final Monitor monitor;
-
- private Connection connection;
- private FrameConnection control;
-
- private final ObjectMapper mapper = new ObjectMapper();
-
- private long lastActive = System.currentTimeMillis();
-
- /**
- * Creates a new monitor client GUI web-socket.
- *
- * @param monitor shared process flow monitor
- */
- MonitorWebSocket(Monitor monitor) {
- this.monitor = monitor;
- }
-
- /**
- * Issues a close on the connection.
- */
- synchronized void close() {
- destroyHandlers();
- if (connection.isOpen()) {
- connection.close();
- }
- }
-
- /**
- * Indicates if this connection is idle.
- *
- * @return true if idle or closed
- */
- synchronized boolean isIdle() {
- long quietFor = System.currentTimeMillis() - lastActive;
- boolean idle = quietFor > MAX_AGE_MS;
- if (idle || (connection != null && !connection.isOpen())) {
- return true;
- } else if (connection != null) {
- try {
- control.sendControl(PING, PING_DATA, 0, PING_DATA.length);
- } catch (IOException e) {
- print("Unable to send ping message due to: %s", e);
- }
- }
- return false;
- }
-
- @Override
- public void onOpen(Connection connection) {
- this.connection = connection;
- this.control = (FrameConnection) connection;
- try {
- createHandlers();
- sendMessage(message("flow", monitor.scenarioData()));
-
- } catch (Exception e) {
- print("Unable to open monitor connection: %s", e);
- this.connection.close();
- this.connection = null;
- this.control = null;
- }
- }
-
- @Override
- public synchronized void onClose(int closeCode, String message) {
- destroyHandlers();
- }
-
- @Override
- public boolean onControl(byte controlCode, byte[] data, int offset, int length) {
- lastActive = System.currentTimeMillis();
- return true;
- }
-
- @Override
- public void onMessage(String data) {
- lastActive = System.currentTimeMillis();
- try {
- ObjectNode message = (ObjectNode) mapper.reader().readTree(data);
- // TODO:
- print("Got message: %s", message);
- } catch (Exception e) {
- print("Unable to parse GUI message %s due to %s", data, e);
- }
- }
-
- public synchronized void sendMessage(ObjectNode message) {
- try {
- if (connection.isOpen()) {
- connection.sendMessage(message.toString());
- }
- } catch (IOException e) {
- print("Unable to send message %s to GUI due to %s", message, e);
- }
- }
-
- public ObjectNode message(String type, ObjectNode payload) {
- ObjectNode message = mapper.createObjectNode().put("event", type);
- message.set("payload", payload);
- return message;
- }
-
- // Creates new message handlers.
- private synchronized void createHandlers() {
- }
-
- // Destroys message handlers.
- private synchronized void destroyHandlers() {
- }
-
-}
-
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java
deleted file mode 100644
index a8705003..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.io.ByteStreams;
-import com.google.common.net.MediaType;
-import org.eclipse.jetty.websocket.WebSocket;
-import org.eclipse.jetty.websocket.WebSocketServlet;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * Web socket servlet capable of creating web sockets for the STC monitor.
- */
-public class MonitorWebSocketServlet extends WebSocketServlet
- implements MonitorDelegate {
-
- private static final long PING_DELAY_MS = 5000;
- private static final String DOT = ".";
-
- private static Monitor monitor;
- private static MonitorWebSocketServlet instance;
-
- private final Set<MonitorWebSocket> sockets = new HashSet<>();
- private final Timer timer = new Timer();
- private final TimerTask pruner = new Pruner();
-
- /**
- * Binds the shared process flow monitor.
- *
- * @param m process monitor reference
- */
- public static void setMonitor(Monitor m) {
- monitor = m;
- }
-
- /**
- * Closes all currently open monitor web-sockets.
- */
- public static void closeAll() {
- if (instance != null) {
- instance.sockets.forEach(MonitorWebSocket::close);
- instance.sockets.clear();
- }
- }
-
- @Override
- public void init() throws ServletException {
- super.init();
- instance = this;
- monitor.setDelegate(this);
- timer.schedule(pruner, PING_DELAY_MS, PING_DELAY_MS);
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- String uri = req.getRequestURI();
- uri = uri.length() <= 1 ? "/index.html" : uri;
- InputStream resource = getClass().getResourceAsStream(uri);
- if (resource == null) {
- resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
- } else {
- byte[] entity = ByteStreams.toByteArray(resource);
- resp.setStatus(HttpServletResponse.SC_OK);
- resp.setContentType(contentType(uri).toString());
- resp.setContentLength(entity.length);
- resp.getOutputStream().write(entity);
- }
- }
-
- private MediaType contentType(String uri) {
- int sep = uri.lastIndexOf(DOT);
- String ext = sep > 0 ? uri.substring(sep + 1) : null;
- return ext == null ? MediaType.APPLICATION_BINARY :
- ext.equals("html") ? MediaType.HTML_UTF_8 :
- ext.equals("js") ? MediaType.JAVASCRIPT_UTF_8 :
- ext.equals("css") ? MediaType.CSS_UTF_8 :
- MediaType.APPLICATION_BINARY;
- }
-
- @Override
- public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
- MonitorWebSocket socket = new MonitorWebSocket(monitor);
- synchronized (sockets) {
- sockets.add(socket);
- }
- return socket;
- }
-
- @Override
- public void notify(ObjectNode event) {
- if (instance != null) {
- instance.sockets.forEach(ws -> ws.sendMessage(event));
- }
- }
-
- // Task for pruning web-sockets that are idle.
- private class Pruner extends TimerTask {
- @Override
- public void run() {
- synchronized (sockets) {
- Iterator<MonitorWebSocket> it = sockets.iterator();
- while (it.hasNext()) {
- MonitorWebSocket socket = it.next();
- if (socket.isIdle()) {
- it.remove();
- socket.close();
- }
- }
- }
- }
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java
deleted file mode 100644
index 4d99b339..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.onlab.graph.MutableAdjacencyListsGraph;
-
-import java.util.Set;
-
-/**
- * Graph representation of a test process flow.
- */
-public class ProcessFlow extends MutableAdjacencyListsGraph<Step, Dependency> {
-
- /**
- * Creates a graph comprising of the specified vertexes and edges.
- *
- * @param vertexes set of graph vertexes
- * @param edges set of graph edges
- */
- public ProcessFlow(Set<Step> vertexes, Set<Dependency> edges) {
- super(vertexes, edges);
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Scenario.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Scenario.java
deleted file mode 100644
index fd2cd62d..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Scenario.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import java.io.InputStream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * Representation of a re-usable test scenario.
- */
-public final class Scenario {
-
- private static final String SCENARIO = "scenario";
- private static final String NAME = "[@name]";
- private static final String DESCRIPTION = "[@description]";
-
- private final String name;
- private final String description;
- private final HierarchicalConfiguration definition;
-
- // Creates a new scenario from the specified definition.
- private Scenario(String name, String description, HierarchicalConfiguration definition) {
- this.name = checkNotNull(name, "Name cannot be null");
- this.description = checkNotNull(description, "Description cannot be null");
- this.definition = checkNotNull(definition, "Definition cannot be null");
- }
-
- /**
- * Loads a new scenario from the specified hierarchical configuration.
- *
- * @param definition scenario definition
- * @return loaded scenario
- */
- public static Scenario loadScenario(HierarchicalConfiguration definition) {
- String name = definition.getString(NAME);
- String description = definition.getString(DESCRIPTION, "");
- checkState(name != null, "Scenario name must be specified");
- return new Scenario(name, description, definition);
- }
-
- /**
- * Loads a new scenario from the specified input stream.
- *
- * @param stream scenario definition stream
- * @return loaded scenario
- */
- public static Scenario loadScenario(InputStream stream) {
- XMLConfiguration cfg = new XMLConfiguration();
- cfg.setAttributeSplittingDisabled(true);
- cfg.setDelimiterParsingDisabled(true);
- cfg.setRootElementName(SCENARIO);
- try {
- cfg.load(stream);
- return loadScenario(cfg);
- } catch (ConfigurationException e) {
- throw new IllegalArgumentException("Unable to load scenario from the stream", e);
- }
- }
-
- /**
- * Returns the scenario name.
- *
- * @return scenario name
- */
- public String name() {
- return name;
- }
-
- /**
- * Returns the scenario description.
- *
- * @return scenario description
- */
- public String description() {
- return description;
- }
-
- /**
- * Returns the scenario definition.
- *
- * @return scenario definition
- */
- public HierarchicalConfiguration definition() {
- return definition;
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java
deleted file mode 100644
index 7313462e..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.stc.Coordinator.Status.*;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Maintains state of scenario execution.
- */
-class ScenarioStore {
-
- private final ProcessFlow processFlow;
- private final File storeFile;
- private final File logDir;
-
- private final List<StepEvent> events = Lists.newArrayList();
- private final Map<String, Status> statusMap = Maps.newConcurrentMap();
-
- private long startTime = Long.MAX_VALUE;
- private long endTime = Long.MIN_VALUE;
-
- /**
- * Creates a new scenario store for the specified process flow.
- *
- * @param processFlow scenario process flow
- * @param logDir scenario log directory
- * @param name scenario name
- */
- ScenarioStore(ProcessFlow processFlow, File logDir, String name) {
- this.processFlow = processFlow;
- this.logDir = logDir;
- this.storeFile = new File(logDir, name + ".stc");
- load();
- }
-
- /**
- * Resets status of all steps to waiting and clears all events.
- */
- void reset() {
- events.clear();
- statusMap.clear();
- processFlow.getVertexes().forEach(step -> statusMap.put(step.name(), WAITING));
- try {
- removeLogs();
- PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
- cfg.clear();
- cfg.save();
- startTime = Long.MAX_VALUE;
- endTime = Long.MIN_VALUE;
- } catch (ConfigurationException e) {
- print("Unable to store file %s", storeFile);
- }
-
- }
-
- /**
- * Returns set of all test steps.
- *
- * @return set of steps
- */
- Set<Step> getSteps() {
- return processFlow.getVertexes();
- }
-
- /**
- * Returns a chronological list of step or group records.
- *
- * @return list of events
- */
- synchronized List<StepEvent> getEvents() {
- return ImmutableList.copyOf(events);
- }
-
- /**
- * Returns the status record of the specified test step.
- *
- * @param step test step or group
- * @return step status record
- */
- Status getStatus(Step step) {
- return checkNotNull(statusMap.get(step.name()), "Step %s not found", step.name());
- }
-
- /**
- * Marks the specified test step as being in progress.
- *
- * @param step test step or group
- */
- synchronized void markStarted(Step step) {
- add(new StepEvent(step.name(), IN_PROGRESS, step.command()));
- save();
- }
-
- /**
- * Marks the specified test step as being complete.
- *
- * @param step test step or group
- * @param status new step status
- */
- synchronized void markComplete(Step step, Status status) {
- add(new StepEvent(step.name(), status, null));
- save();
- }
-
- /**
- * Returns true if all steps in the store have been marked as completed
- * regardless of the completion status.
- *
- * @return true if all steps completed one way or another
- */
- synchronized boolean isComplete() {
- return !statusMap.values().stream().anyMatch(s -> s == WAITING || s == IN_PROGRESS);
- }
-
- /**
- * Indicates whether there are any failures.
- *
- * @return true if there are failed steps
- */
- boolean hasFailures() {
- for (Status status : statusMap.values()) {
- if (status == FAILED) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Registers a new step record.
- *
- * @param event step event
- */
- private synchronized void add(StepEvent event) {
- events.add(event);
- statusMap.put(event.name(), event.status());
- startTime = Math.min(startTime, event.time());
- endTime = Math.max(endTime, event.time());
- }
-
- /**
- * Loads the states from disk.
- */
- private void load() {
- try {
- PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
- cfg.getKeys().forEachRemaining(prop -> add(StepEvent.fromString(cfg.getString(prop))));
- cfg.save();
- } catch (ConfigurationException e) {
- print("Unable to load file %s", storeFile);
- }
- }
-
- /**
- * Saves the states to disk.
- */
- private void save() {
- try {
- PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
- events.forEach(event -> cfg.setProperty("T" + event.time(), event.toString()));
- cfg.save();
- } catch (ConfigurationException e) {
- print("Unable to store file %s", storeFile);
- }
- }
-
- /**
- * Removes all scenario log files.
- */
- private void removeLogs() {
- File[] logFiles = logDir.listFiles();
- if (logFiles != null && logFiles.length > 0) {
- for (File file : logFiles) {
- if (!file.delete()) {
- print("Unable to delete log file %s", file);
- }
- }
- }
- }
-
- /**
- * Returns the scenario run start time.
- *
- * @return start time in mills since start of epoch
- */
- public long startTime() {
- return startTime;
- }
-
- /**
- * Returns the scenario run end time or current time if the scenario
- * is still running.
- *
- * @return end time (or current time) in mills since start of epoch
- */
- public long endTime() {
- return endTime > 0 ? endTime : System.currentTimeMillis();
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Step.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Step.java
deleted file mode 100644
index e14addb5..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/Step.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.base.MoreObjects;
-import org.onlab.graph.Vertex;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of a test step.
- */
-public class Step implements Vertex {
-
- protected final String name;
- protected final String command;
- protected final String env;
- protected final String cwd;
- protected final Group group;
-
- /**
- * Creates a new test step.
- *
- * @param name step name
- * @param command step command to execute
- * @param env path to file to be sourced into the environment
- * @param cwd path to current working directory for the step
- * @param group optional group to which this step belongs
- */
- public Step(String name, String command, String env, String cwd, Group group) {
- this.name = checkNotNull(name, "Name cannot be null");
- this.group = group;
-
- // Set the command, environment and cwd
- // If one is not given use the value from the enclosing group
- this.command = command != null ? command : group != null && group.command != null ? group.command : null;
- this.env = env != null ? env : group != null && group.env != null ? group.env : null;
- this.cwd = cwd != null ? cwd : group != null && group.cwd != null ? group.cwd : null;
- }
-
- /**
- * Returns the step name.
- *
- * @return step name
- */
- public String name() {
- return name;
- }
-
- /**
- * Returns the step command string.
- *
- * @return command string
- */
- public String command() {
- return command;
- }
-
- /**
- * Returns the step environment script path.
- *
- * @return env script path
- */
- public String env() {
- return env;
- }
-
- /**
- * Returns the step current working directory path.
- *
- * @return current working dir path
- */
- public String cwd() {
- return cwd;
- }
-
- /**
- * Returns the enclosing group; null if none.
- *
- * @return enclosing group or null
- */
- public Group group() {
- return group;
- }
-
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Step) {
- final Step other = (Step) obj;
- return Objects.equals(this.name, other.name);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("name", name)
- .add("command", command)
- .add("env", env)
- .add("cwd", cwd)
- .add("group", group)
- .toString();
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepEvent.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepEvent.java
deleted file mode 100644
index c9b81a24..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepEvent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.onlab.stc.Coordinator.Status;
-
-import static java.lang.Long.parseLong;
-import static org.onlab.stc.Coordinator.Status.valueOf;
-
-/**
- * Represents an event of execution of a scenario step or group.
- */
-public class StepEvent {
-
- private static final String SEP = "~";
-
- private final String name;
- private final long time;
- private final Status status;
- private final String command;
-
- /**
- * Creates a new step record.
- *
- * @param name test step or group name
- * @param time time in millis since start of epoch
- * @param status step completion status
- * @param command step command
- */
- public StepEvent(String name, long time, Status status, String command) {
- this.name = name;
- this.time = time;
- this.status = status;
- this.command = command;
- }
-
- /**
- * Creates a new step record for non-running status.
- *
- * @param name test step or group name
- * @param status status
- * @param command step command
- */
- public StepEvent(String name, Status status, String command) {
- this(name, System.currentTimeMillis(), status, command);
- }
-
- /**
- * Returns the test step or test group name.
- *
- * @return step or group name
- */
- public String name() {
- return name;
- }
-
- /**
- * Returns the step event time.
- *
- * @return time in millis since start of epoch
- */
- public long time() {
- return time;
- }
-
- /**
- * Returns the step completion status.
- *
- * @return completion status
- */
- public Status status() {
- return status;
- }
-
- /**
- * Returns the step command.
- *
- * @return step command
- */
- public String command() {
- return command;
- }
-
-
- @Override
- public String toString() {
- return name + SEP + time + SEP + status + SEP + command;
- }
-
- /**
- * Returns a record parsed from the specified string.
- *
- * @param string string encoding
- * @return step record
- */
- public static StepEvent fromString(String string) {
- String[] fields = string.split("~");
- return fields.length == 4 ?
- new StepEvent(fields[0], parseLong(fields[1]), valueOf(fields[2]),
- fields[3].equals("null") ? null : fields[3]) :
- new StepEvent(fields[0], 0, Status.WAITING, null);
- }
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java
deleted file mode 100644
index a8222d0b..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-/**
- * Entity capable of receiving notifications of process step execution events.
- */
-public interface StepProcessListener {
-
- /**
- * Indicates that process step has started.
- *
- * @param step subject step
- * @param command actual command executed; includes run-time substitutions
- */
- default void onStart(Step step, String command) {
- }
-
- /**
- * Indicates that process step has completed.
- *
- * @param step subject step
- * @param status step completion status
- */
- default void onCompletion(Step step, Coordinator.Status status) {
- }
-
- /**
- * Notifies when a new line of output becomes available.
- *
- * @param step subject step
- * @param line line of output
- */
- default void onOutput(Step step, String line) {
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
deleted file mode 100644
index 49943691..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-
-import static java.lang.String.format;
-import static org.onlab.stc.Coordinator.Status.FAILED;
-import static org.onlab.stc.Coordinator.Status.SUCCEEDED;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Manages execution of the specified step or a group.
- */
-class StepProcessor implements Runnable {
-
- private static final String IGNORE_CODE = "~";
- private static final String NEGATE_CODE = "!";
-
- private static final int FAIL = -1;
-
- static String launcher = "stc-launcher ";
-
- private final Step step;
- private final File logDir;
- private String command;
-
- private Process process;
- private StepProcessListener delegate;
-
- /**
- * Creates a process monitor.
- *
- * @param step step or group to be executed
- * @param logDir directory where step process log should be stored
- * @param delegate process lifecycle listener
- * @param command actual command to execute
- */
- StepProcessor(Step step, File logDir, StepProcessListener delegate,
- String command) {
- this.step = step;
- this.logDir = logDir;
- this.delegate = delegate;
- this.command = command;
- }
-
- @Override
- public void run() {
- delegate.onStart(step, command);
- int code = execute();
- boolean ignoreCode = step.env() != null && step.env.equals(IGNORE_CODE);
- boolean negateCode = step.env() != null && step.env.equals(NEGATE_CODE);
- Status status = ignoreCode || code == 0 && !negateCode || code != 0 && negateCode ?
- SUCCEEDED : FAILED;
- delegate.onCompletion(step, status);
- }
-
- /**
- * Executes the step process.
- *
- * @return exit code
- */
- private int execute() {
- try (PrintWriter pw = new PrintWriter(logFile())) {
- process = Runtime.getRuntime().exec(command());
- processOutput(pw);
-
- // Wait for the process to complete and get its exit code.
- if (process.isAlive()) {
- process.waitFor();
- }
- return process.exitValue();
-
- } catch (IOException e) {
- print("Unable to run step %s using command %s", step.name(), step.command());
- } catch (InterruptedException e) {
- print("Step %s interrupted", step.name());
- }
- return FAIL;
- }
-
- /**
- * Returns ready-to-run command for the step.
- *
- * @return command to execute
- */
- private String command() {
- return format("%s %s %s %s", launcher,
- step.env() != null ? step.env() : "-",
- step.cwd() != null ? step.cwd() : "-",
- command);
- }
-
- /**
- * Captures output of the step process.
- *
- * @param pw print writer to send output to
- * @throws IOException if unable to read output or write logs
- */
- private void processOutput(PrintWriter pw) throws IOException {
- InputStream out = process.getInputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(out));
-
- // Slurp its combined stderr/stdout
- String line;
- while ((line = br.readLine()) != null) {
- pw.println(line);
- delegate.onOutput(step, line);
- }
- }
-
- /**
- * Returns the log file for the step output.
- *
- * @return log file
- */
- private File logFile() {
- return new File(logDir, step.name() + ".log");
- }
-
-}
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/package-info.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/package-info.java
deleted file mode 100644
index 56145899..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * System Test Coordinator tool for modular scenario-based testing.
- */
-package org.onlab.stc; \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/main/resources/data.json b/framework/src/onos/utils/stc/src/main/resources/data.json
deleted file mode 100644
index f5823744..00000000
--- a/framework/src/onos/utils/stc/src/main/resources/data.json
+++ /dev/null
@@ -1,1087 +0,0 @@
-{
- "requirements": [
- {
- "dst": "Reactive-Forwarding.Ping-2",
- "isSoft": false,
- "src": "Reactive-Forwarding.Link-2-Down"
- },
- {
- "dst": "Final-Check-Logs-2",
- "isSoft": true,
- "src": "Fetch-Logs-2"
- },
- {
- "dst": "Host-Intent.Ping-4",
- "isSoft": false,
- "src": "Host-Intent.Link-2-Up"
- },
- {
- "dst": "Install-1",
- "isSoft": false,
- "src": "Wait-for-Start-1"
- },
- {
- "dst": "Host-Intent.Link-1-Down",
- "isSoft": false,
- "src": "Host-Intent.Ping-2"
- },
- {
- "dst": "Host-Intent.Link-2-Up",
- "isSoft": false,
- "src": "Host-Intent.Ping-5"
- },
- {
- "dst": "Host-Intent.Ping-2",
- "isSoft": false,
- "src": "Host-Intent.Link-2-Down"
- },
- {
- "dst": "Reinstall-App-With-CLI",
- "isSoft": false,
- "src": "Verify-CLI"
- },
- {
- "dst": "Create-App-UI-Overlay",
- "isSoft": false,
- "src": "Build-App-With-UI"
- },
- {
- "dst": "Secure-SSH",
- "isSoft": true,
- "src": "Wait-for-Start-1"
- },
- {
- "dst": "Pause-For-Masters",
- "isSoft": true,
- "src": "Check-Flows"
- },
- {
- "dst": "Secure-SSH",
- "isSoft": true,
- "src": "Wait-for-Start-3"
- },
- {
- "dst": "Uninstall-3",
- "isSoft": false,
- "src": "Kill-3"
- },
- {
- "dst": "Balance-Masters",
- "isSoft": false,
- "src": "Pause-For-Masters"
- },
- {
- "dst": "Reactive-Forwarding.Net-Pingall",
- "isSoft": true,
- "src": "Reactive-Forwarding.Net-Link-Down-Up"
- },
- {
- "dst": "Wait-for-Start-3",
- "isSoft": true,
- "src": "Check-Logs-3"
- },
- {
- "dst": "Wait-for-Start-2",
- "isSoft": true,
- "src": "Check-Components-2"
- },
- {
- "dst": "Uninstall-Reactive-Forwarding",
- "isSoft": false,
- "src": "Find-Host-1"
- },
- {
- "dst": "Wipe-Out-Data-Before",
- "isSoft": true,
- "src": "Initial-Summary-Check"
- },
- {
- "dst": "Reactive-Forwarding.Ping-3",
- "isSoft": false,
- "src": "Reactive-Forwarding.Link-1-Up"
- },
- {
- "dst": "Archetypes",
- "isSoft": true,
- "src": "Wrapup"
- },
- {
- "dst": "Reactive-Forwarding.Ping-4",
- "isSoft": false,
- "src": "Reactive-Forwarding.Link-2-Up"
- },
- {
- "dst": "Host-Intent-Connectivity",
- "isSoft": true,
- "src": "Net-Teardown"
- },
- {
- "dst": "Host-Intent.Ping-3",
- "isSoft": false,
- "src": "Host-Intent.Link-1-Up"
- },
- {
- "dst": "Host-Intent.Ping-1",
- "isSoft": false,
- "src": "Host-Intent.Link-1-Down"
- },
- {
- "dst": "Install-App",
- "isSoft": false,
- "src": "Create-App-CLI-Overlay"
- },
- {
- "dst": "Final-Check-Logs-3",
- "isSoft": true,
- "src": "Fetch-Logs-3"
- },
- {
- "dst": "Install-App",
- "isSoft": false,
- "src": "Verify-App"
- },
- {
- "dst": "Host-Intent.Link-2-Down",
- "isSoft": false,
- "src": "Host-Intent.Ping-3"
- },
- {
- "dst": "Prerequisites",
- "isSoft": false,
- "src": "Setup"
- },
- {
- "dst": "Verify-App",
- "isSoft": true,
- "src": "Reinstall-App-With-CLI"
- },
- {
- "dst": "Net-Smoke",
- "isSoft": true,
- "src": "Archetypes"
- },
- {
- "dst": "Setup",
- "isSoft": true,
- "src": "Wrapup"
- },
- {
- "dst": "Start-Mininet",
- "isSoft": false,
- "src": "Wait-For-Mininet"
- },
- {
- "dst": "Verify-UI",
- "isSoft": false,
- "src": "Uninstall-App"
- },
- {
- "dst": "Kill-3",
- "isSoft": false,
- "src": "Install-3"
- },
- {
- "dst": "Wait-for-Start-1",
- "isSoft": true,
- "src": "Check-Components-1"
- },
- {
- "dst": "Wait-for-Start-1",
- "isSoft": true,
- "src": "Check-Nodes-1"
- },
- {
- "dst": "Push-Topos",
- "isSoft": false,
- "src": "Start-Mininet"
- },
- {
- "dst": "Reactive-Forwarding.Check-Summary-For-Hosts",
- "isSoft": true,
- "src": "Reactive-Forwarding.Config-Topo"
- },
- {
- "dst": "Reactive-Forwarding.Install-Apps",
- "isSoft": false,
- "src": "Reactive-Forwarding.Check-Apps"
- },
- {
- "dst": "Push-Bits",
- "isSoft": false,
- "src": "Install-2"
- },
- {
- "dst": "Install-1",
- "isSoft": false,
- "src": "Secure-SSH"
- },
- {
- "dst": "Create-Intent",
- "isSoft": false,
- "src": "Host-Intent.Net-Link-Down-Up"
- },
- {
- "dst": "Verify-CLI",
- "isSoft": true,
- "src": "Reinstall-App-With-UI"
- },
- {
- "dst": "Wait-for-Start-3",
- "isSoft": true,
- "src": "Check-Apps-3"
- },
- {
- "dst": "Net-Smoke",
- "isSoft": true,
- "src": "Wrapup"
- },
- {
- "dst": "Initial-Summary-Check",
- "isSoft": false,
- "src": "Start-Mininet"
- },
- {
- "dst": "Install-3",
- "isSoft": false,
- "src": "Wait-for-Start-3"
- },
- {
- "dst": "Reactive-Forwarding.Link-1-Up",
- "isSoft": false,
- "src": "Reactive-Forwarding.Ping-4"
- },
- {
- "dst": "Check-Summary",
- "isSoft": true,
- "src": "Balance-Masters"
- },
- {
- "dst": "Reactive-Forwarding.Net-Link-Down-Up",
- "isSoft": true,
- "src": "Host-Intent-Connectivity"
- },
- {
- "dst": "Secure-SSH",
- "isSoft": true,
- "src": "Wait-for-Start-2"
- },
- {
- "dst": "Build-App-With-CLI",
- "isSoft": false,
- "src": "Reinstall-App-With-CLI"
- },
- {
- "dst": "Uninstall-1",
- "isSoft": false,
- "src": "Kill-1"
- },
- {
- "dst": "Find-Host-1",
- "isSoft": false,
- "src": "Find-Host-2"
- },
- {
- "dst": "Create-App-CLI-Overlay",
- "isSoft": false,
- "src": "Build-App-With-CLI"
- },
- {
- "dst": "Net-Setup",
- "isSoft": false,
- "src": "Reactive-Forwarding.Net-Link-Down-Up"
- },
- {
- "dst": "Kill-2",
- "isSoft": false,
- "src": "Install-2"
- },
- {
- "dst": "Wait-for-Start-1",
- "isSoft": true,
- "src": "Check-Logs-1"
- },
- {
- "dst": "Wait-for-Start-2",
- "isSoft": true,
- "src": "Check-Nodes-2"
- },
- {
- "dst": "Reactive-Forwarding.Ping-All-And-Verify",
- "isSoft": true,
- "src": "Reactive-Forwarding.Check-Summary-For-Hosts"
- },
- {
- "dst": "Clean-Up",
- "isSoft": false,
- "src": "Create-App"
- },
- {
- "dst": "Host-Intent.Link-1-Up",
- "isSoft": false,
- "src": "Host-Intent.Ping-4"
- },
- {
- "dst": "Build-App-With-UI",
- "isSoft": false,
- "src": "Reinstall-App-With-UI"
- },
- {
- "dst": "Install-2",
- "isSoft": false,
- "src": "Secure-SSH"
- },
- {
- "dst": "Wait-For-Mininet",
- "isSoft": false,
- "src": "Check-Summary"
- },
- {
- "dst": "Host-Intent.Net-Link-Down-Up",
- "isSoft": false,
- "src": "Remove-Intent"
- },
- {
- "dst": "Net-Setup",
- "isSoft": false,
- "src": "Host-Intent-Connectivity"
- },
- {
- "dst": "Net-Setup",
- "isSoft": false,
- "src": "Reactive-Forwarding.Net-Pingall"
- },
- {
- "dst": "Reactive-Forwarding.Link-2-Down",
- "isSoft": false,
- "src": "Reactive-Forwarding.Ping-3"
- },
- {
- "dst": "Find-Host-2",
- "isSoft": false,
- "src": "Create-Intent"
- },
- {
- "dst": "Wait-for-Start-2",
- "isSoft": true,
- "src": "Check-Apps-2"
- },
- {
- "dst": "Final-Check-Logs-1",
- "isSoft": true,
- "src": "Fetch-Logs-1"
- },
- {
- "dst": "Install-2",
- "isSoft": false,
- "src": "Wait-for-Start-2"
- },
- {
- "dst": "Reactive-Forwarding.Ping-1",
- "isSoft": false,
- "src": "Reactive-Forwarding.Link-1-Down"
- },
- {
- "dst": "Create-App",
- "isSoft": false,
- "src": "Build-App"
- },
- {
- "dst": "Check-Summary",
- "isSoft": true,
- "src": "Check-Flows"
- },
- {
- "dst": "Build-App",
- "isSoft": false,
- "src": "Install-App"
- },
- {
- "dst": "Reinstall-App-With-UI",
- "isSoft": false,
- "src": "Verify-UI"
- },
- {
- "dst": "Uninstall-2",
- "isSoft": false,
- "src": "Kill-2"
- },
- {
- "dst": "Setup",
- "isSoft": false,
- "src": "Archetypes"
- },
- {
- "dst": "Setup",
- "isSoft": false,
- "src": "Net-Smoke"
- },
- {
- "dst": "Kill-1",
- "isSoft": false,
- "src": "Install-1"
- },
- {
- "dst": "Reactive-Forwarding.Link-1-Down",
- "isSoft": false,
- "src": "Reactive-Forwarding.Ping-2"
- },
- {
- "dst": "Wait-for-Start-2",
- "isSoft": true,
- "src": "Check-Logs-2"
- },
- {
- "dst": "Wait-for-Start-3",
- "isSoft": true,
- "src": "Check-Components-3"
- },
- {
- "dst": "Wait-for-Start-3",
- "isSoft": true,
- "src": "Check-Nodes-3"
- },
- {
- "dst": "Stop-Mininet-If-Needed",
- "isSoft": false,
- "src": "Start-Mininet"
- },
- {
- "dst": "Reactive-Forwarding.Link-2-Up",
- "isSoft": false,
- "src": "Reactive-Forwarding.Ping-5"
- },
- {
- "dst": "Reactive-Forwarding.Check-Apps",
- "isSoft": false,
- "src": "Reactive-Forwarding.Ping-All-And-Verify"
- },
- {
- "dst": "Install-3",
- "isSoft": false,
- "src": "Secure-SSH"
- },
- {
- "dst": "Push-Bits",
- "isSoft": false,
- "src": "Install-3"
- },
- {
- "dst": "Reinstall-App-With-CLI",
- "isSoft": false,
- "src": "Create-App-UI-Overlay"
- },
- {
- "dst": "Push-Bits",
- "isSoft": false,
- "src": "Install-1"
- },
- {
- "dst": "Wait-for-Start-1",
- "isSoft": true,
- "src": "Check-Apps-1"
- }
- ],
- "steps": [
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Check-Summary",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Check-Flows",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Final-Check-Logs-1",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Final-Check-Logs-2",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Clean-Up",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Build-App-With-UI",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Uninstall-App",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Final-Check-Logs-3",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Link-2-Down",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Fetch-Logs-3",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Fetch-Logs-2",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Components-3",
- "status": "waiting"
- },
- {
- "group": "Wrapup",
- "isGroup": false,
- "name": "Fetch-Logs-1",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Push-Topos",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Pingall",
- "isGroup": false,
- "name": "Reactive-Forwarding.Check-Apps",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Wait-for-Start-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Wait-for-Start-2",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Wait-for-Start-1",
- "status": "waiting"
- },
- {
- "group": "Net-Smoke",
- "isGroup": true,
- "name": "Host-Intent-Connectivity",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": false,
- "name": "Create-Intent",
- "status": "waiting"
- },
- {
- "isGroup": true,
- "name": "Prerequisites",
- "status": "in_progress"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Push-Bits",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Logs-2",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Logs-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Kill-1",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Kill-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Kill-2",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": true,
- "name": "Host-Intent.Net-Link-Down-Up",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Ping-1",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Verify-UI",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Ping-2",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Ping-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Uninstall-1",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Logs-1",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Ping-4",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Uninstall-3",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Ping-5",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Uninstall-2",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Pingall",
- "isGroup": false,
- "name": "Reactive-Forwarding.Install-Apps",
- "status": "waiting"
- },
- {
- "group": "Net-Smoke",
- "isGroup": true,
- "name": "Reactive-Forwarding.Net-Link-Down-Up",
- "status": "waiting"
- },
- {
- "group": "Prerequisites",
- "isGroup": false,
- "name": "Check-ONOS-Bits",
- "status": "in_progress"
- },
- {
- "isGroup": true,
- "name": "Wrapup",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Install-2",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": false,
- "name": "Find-Host-1",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Install-1",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Wipe-Out-Data-Before",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Pause-For-Masters",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Link-2-Up",
- "status": "waiting"
- },
- {
- "group": "Net-Smoke",
- "isGroup": true,
- "name": "Reactive-Forwarding.Net-Pingall",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Components-2",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Components-1",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Reinstall-App-With-UI",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Reinstall-App-With-CLI",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Build-App-With-CLI",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": false,
- "name": "Uninstall-Reactive-Forwarding",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Link-2-Up",
- "status": "waiting"
- },
- {
- "group": "Net-Teardown",
- "isGroup": false,
- "name": "Stop-Mininet",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Pingall",
- "isGroup": false,
- "name": "Reactive-Forwarding.Config-Topo",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Create-App-CLI-Overlay",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Link-1-Down",
- "status": "waiting"
- },
- {
- "isGroup": true,
- "name": "Net-Smoke",
- "status": "waiting"
- },
- {
- "group": "Prerequisites",
- "isGroup": false,
- "name": "Check-Passwordless-Login-2",
- "status": "in_progress"
- },
- {
- "group": "Prerequisites",
- "isGroup": false,
- "name": "Check-Passwordless-Login-1",
- "status": "in_progress"
- },
- {
- "group": "Prerequisites",
- "isGroup": false,
- "name": "Check-Passwordless-Login-3",
- "status": "in_progress"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Secure-SSH",
- "status": "waiting"
- },
- {
- "group": "Net-Smoke",
- "isGroup": true,
- "name": "Net-Setup",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Nodes-1",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Install-3",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": false,
- "name": "Find-Host-2",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Initial-Summary-Check",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Create-App",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Nodes-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Nodes-2",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Link-2-Down",
- "status": "waiting"
- },
- {
- "isGroup": true,
- "name": "Setup",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Verify-App",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-1",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-2",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Start-Mininet",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-3",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-4",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-5",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Verify-CLI",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Pingall",
- "isGroup": false,
- "name": "Reactive-Forwarding.Check-Summary-For-Hosts",
- "status": "waiting"
- },
- {
- "group": "Net-Smoke",
- "isGroup": true,
- "name": "Net-Teardown",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Link-1-Up",
- "status": "waiting"
- },
- {
- "group": "Host-Intent-Connectivity",
- "isGroup": false,
- "name": "Remove-Intent",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Install-App",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Create-App-UI-Overlay",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Reactive-Forwarding.Link-1-Up",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Wait-For-Mininet",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Apps-3",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Apps-2",
- "status": "waiting"
- },
- {
- "group": "Setup",
- "isGroup": false,
- "name": "Check-Apps-1",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Stop-Mininet-If-Needed",
- "status": "waiting"
- },
- {
- "group": "Prerequisites",
- "isGroup": false,
- "name": "Check-Environment",
- "status": "in_progress"
- },
- {
- "isGroup": true,
- "name": "Archetypes",
- "status": "waiting"
- },
- {
- "group": "Host-Intent.Net-Link-Down-Up",
- "isGroup": false,
- "name": "Host-Intent.Link-1-Down",
- "status": "waiting"
- },
- {
- "group": "Net-Setup",
- "isGroup": false,
- "name": "Balance-Masters",
- "status": "waiting"
- },
- {
- "group": "Reactive-Forwarding.Net-Pingall",
- "isGroup": false,
- "name": "Reactive-Forwarding.Ping-All-And-Verify",
- "status": "waiting"
- },
- {
- "group": "Archetypes",
- "isGroup": false,
- "name": "Build-App",
- "status": "waiting"
- }
- ]
-}
diff --git a/framework/src/onos/utils/stc/src/main/resources/index.html b/framework/src/onos/utils/stc/src/main/resources/index.html
deleted file mode 100644
index c75bb8f2..00000000
--- a/framework/src/onos/utils/stc/src/main/resources/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<html>
-<head lang="en">
- <meta charset="utf-8">
- <title>Scenario Test Coordinator</title>
-
- <link rel="stylesheet" href="stc.css">
-
- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
- <script src="stc.js"></script>
-</head>
-<body>
-</body>
-</html> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/main/resources/stc.css b/framework/src/onos/utils/stc/src/main/resources/stc.css
deleted file mode 100644
index 8d94253e..00000000
--- a/framework/src/onos/utils/stc/src/main/resources/stc.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-.body {
- font-family: Helvetica, Arial, sans-serif;
-}
-
-.node {
- stroke: #fff;
- stroke-width: 1.5px;
-}
-
-.link {
- stroke: #999;
- stroke-opacity: .6;
-}
-
-text {
- font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
- stroke: #000;
- stroke-width: 0.2;
- font-weight: normal;
- font-size: 0.6em;
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/main/resources/stc.js b/framework/src/onos/utils/stc/src/main/resources/stc.js
deleted file mode 100644
index 215fd6e2..00000000
--- a/framework/src/onos/utils/stc/src/main/resources/stc.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-(function () {
-
- var ws, flow,
- nodes = [],
- links = [],
- nodeIndexes = {};
-
- var width = 2400,
- height = 2400;
-
- var color = d3.scale.category20();
-
- var force = d3.layout.force()
- .charge(-820)
- .linkDistance(50)
- .size([width, height]);
-
- // Process flow graph layout
- function createNode(n) {
- nodeIndexes[n.name] = nodes.push(n) - 1;
- }
-
- function createLink(e) {
- e.source = nodeIndexes[e.src];
- e.target = nodeIndexes[e.dst];
- links.push(e);
- }
-
- // Returns the newly computed bounding box of the rectangle
- function adjustRectToFitText(n) {
- var text = n.select('text'),
- box = text.node().getBBox();
-
- text.attr('text-anchor', 'left')
- .attr('y', 2)
- .attr('x', 4);
-
- // add padding
- box.x -= 4;
- box.width += 8;
- box.y -= 2;
- box.height += 4;
-
- n.select("rect").attr(box);
- }
-
- function processFlow() {
- var svg = d3.select("body").append("svg")
- .attr("width", width)
- .attr("height", height);
-
- flow.steps.forEach(createNode);
- flow.requirements.forEach(createLink);
-
- force
- .nodes(nodes)
- .links(links)
- .start();
-
- var link = svg.selectAll(".link")
- .data(links)
- .enter().append("line")
- .attr("class", "link")
- .style("stroke-width", function(d) { return d.isSoft ? 1 : 2; });
-
- var node = svg.selectAll(".node")
- .data(nodes)
- .enter().append("g")
- .attr("class", "node")
- .call(force.drag);
-
- node.append("rect")
- .attr({ rx: 5, ry:5, width:180, height:18 })
- .style("fill", function(d) { return color(d.group); });
-
- node.append("text").text( function(d) { return d.name; })
- .attr({ dy:"1.1em", width:100, height:16, x:4, y:2 });
-
- node.append("title")
- .text(function(d) { return d.name; });
-
- force.on("tick", function() {
- link.attr("x1", function(d) { return d.source.x; })
- .attr("y1", function(d) { return d.source.y; })
- .attr("x2", function(d) { return d.target.x; })
- .attr("y2", function(d) { return d.target.y; });
-
- node.attr("transform", function(d) { return "translate(" + (d.x - 180/2) + "," + (d.y - 18/2) + ")"; });
- });
- }
-
-
- // Web socket callbacks
-
- function handleOpen() {
- console.log('WebSocket open');
- }
-
- // Handles the specified (incoming) message using handler bindings.
- function handleMessage(msg) {
- console.log('rx: ', msg);
- evt = JSON.parse(msg.data);
- if (evt.event === 'progress') {
-
- } else if (evt.event === 'log') {
-
- } else if (evt.event === 'flow') {
- flow = evt.payload;
- processFlow();
- }
- }
-
- function handleClose() {
- console.log('WebSocket closed');
- }
-
- if (false) {
- d3.json("data.json", function (error, data) {
- flow = data;
- processFlow();
- });
- return;
- }
-
- // Open the web-socket
- ws = new WebSocket(document.location.href.replace('http:', 'ws:'));
- if (ws) {
- ws.onopen = handleOpen;
- ws.onmessage = handleMessage;
- ws.onclose = handleClose;
- }
-
-})(); \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java
deleted file mode 100644
index 59b55307..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.io.Files;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import static com.google.common.io.ByteStreams.toByteArray;
-import static com.google.common.io.Files.write;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test scenario compiler.
- */
-public class CompilerTest {
-
- static final File TEST_DIR = Files.createTempDir();
-
- @BeforeClass
- public static void setUpClass() throws IOException {
- stageTestResource("scenario.xml");
- stageTestResource("simple-scenario.xml");
- stageTestResource("one-scenario.xml");
- stageTestResource("two-scenario.xml");
-
- System.setProperty("prop.foo", "Foobar");
- System.setProperty("prop.bar", "Barfoo");
- System.setProperty("TOC1", "1.2.3.1");
- System.setProperty("TOC2", "1.2.3.2");
- System.setProperty("TOC3", "1.2.3.3");
- System.setProperty("test.dir", TEST_DIR.getAbsolutePath());
- }
-
- static FileInputStream getStream(String name) throws FileNotFoundException {
- return new FileInputStream(new File(TEST_DIR, name));
- }
-
- static void stageTestResource(String name) throws IOException {
- byte[] bytes = toByteArray(CompilerTest.class.getResourceAsStream(name));
- write(bytes, new File(TEST_DIR, name));
- }
-
- @Test
- public void basics() throws Exception {
- Scenario scenario = loadScenario(getStream("scenario.xml"));
- Compiler compiler = new Compiler(scenario);
- compiler.compile();
- ProcessFlow flow = compiler.processFlow();
-
- assertSame("incorrect scenario", scenario, compiler.scenario());
- assertEquals("incorrect step count", 33, flow.getVertexes().size());
- assertEquals("incorrect dependency count", 26, flow.getEdges().size());
- assertEquals("incorrect logDir",
- new File(TEST_DIR.getAbsolutePath(), "foo"), compiler.logDir());
-
- Step step = compiler.getStep("there");
- assertEquals("incorrect edge count", 2, flow.getEdgesFrom(step).size());
- assertEquals("incorrect edge count", 0, flow.getEdgesTo(step).size());
-
- Step group = compiler.getStep("three");
- assertEquals("incorrect edge count", 2, flow.getEdgesFrom(group).size());
- assertEquals("incorrect edge count", 0, flow.getEdgesTo(group).size());
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java
deleted file mode 100644
index c6f057ec..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.util.Tools;
-
-import java.io.IOException;
-
-import static org.onlab.stc.CompilerTest.getStream;
-import static org.onlab.stc.Coordinator.print;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test coordinator.
- */
-public class CoordinatorTest {
-
- private Coordinator coordinator;
- private StepProcessListener listener = new Listener();
-
- @BeforeClass
- public static void setUpClass() throws IOException {
- CompilerTest.setUpClass();
- Tools.removeDirectory(StepProcessorTest.DIR);
-
- StepProcessor.launcher = "true ";
- }
-
- @Test
- public void simple() throws IOException, InterruptedException {
- executeTest("simple-scenario.xml");
- }
-
- @Test
- public void complex() throws IOException, InterruptedException {
- executeTest("scenario.xml");
- }
-
- private void executeTest(String name) throws IOException, InterruptedException {
- Scenario scenario = loadScenario(getStream(name));
- Compiler compiler = new Compiler(scenario);
- compiler.compile();
- Tools.removeDirectory(compiler.logDir());
- coordinator = new Coordinator(scenario, compiler.processFlow(), compiler.logDir());
- coordinator.addListener(listener);
- coordinator.reset();
- coordinator.start();
- coordinator.waitFor();
- coordinator.removeListener(listener);
- }
-
- private class Listener implements StepProcessListener {
- @Override
- public void onStart(Step step, String command) {
- print("> %s: started; %s", step.name(), command);
- }
-
- @Override
- public void onCompletion(Step step, Coordinator.Status status) {
- print("< %s: %s", step.name(), status == Coordinator.Status.SUCCEEDED ? "completed" : "failed");
- }
-
- @Override
- public void onOutput(Step step, String line) {
- print(" %s: %s", step.name(), line);
- }
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java
deleted file mode 100644
index 4438303c..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Test of the test step dependency.
- */
-public class DependencyTest extends StepTest {
-
- protected Step step1, step2;
-
- @Before
- public void setUp() throws ConfigurationException {
- super.setUp();
- step1 = new Step("step1", CMD, null, null, null);
- step2 = new Step("step2", CMD, null, null, null);
- }
-
- @Test
- public void hard() {
- Dependency hard = new Dependency(step1, step2, false);
- assertSame("incorrect src", step1, hard.src());
- assertSame("incorrect dst", step2, hard.dst());
- assertFalse("incorrect isSoft", hard.isSoft());
- }
-
- @Test
- public void soft() {
- Dependency soft = new Dependency(step2, step1, true);
- assertSame("incorrect src", step2, soft.src());
- assertSame("incorrect dst", step1, soft.dst());
- assertTrue("incorrect isSoft", soft.isSoft());
- }
-
- @Test
- public void equality() {
- Dependency d1 = new Dependency(step1, step2, false);
- Dependency d2 = new Dependency(step1, step2, false);
- Dependency d3 = new Dependency(step1, step2, true);
- Dependency d4 = new Dependency(step2, step1, true);
- new EqualsTester()
- .addEqualityGroup(d1, d2)
- .addEqualityGroup(d3)
- .addEqualityGroup(d4)
- .testEquals();
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/GroupTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/GroupTest.java
deleted file mode 100644
index 9b612c85..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/GroupTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-/**
- * Test of the test scenario entity.
- */
-public class GroupTest extends StepTest {
-
- @Test
- public void basics() {
- Group group = new Group(NAME, CMD, ENV, CWD, parent);
- assertEquals("incorrect name", NAME, group.name());
- assertEquals("incorrect command", CMD, group.command());
- assertEquals("incorrect env", ENV, group.env());
- assertEquals("incorrect cwd", CWD, group.cwd());
- assertSame("incorrect group", parent, group.group());
-
- Step step = new Step("step", null, null, null, group);
- group.addChild(step);
- assertSame("incorrect child", step, group.children().iterator().next());
- }
-
- @Test
- public void equality() {
- Group g1 = new Group(NAME, CMD, null, null, parent);
- Group g2 = new Group(NAME, CMD, ENV, CWD, null);
- Group g3 = new Group("foo", null, null, null, parent);
- new EqualsTester()
- .addEqualityGroup(g1, g2)
- .addEqualityGroup(g3)
- .testEquals();
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java
deleted file mode 100644
index 4b7f5614..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.junit.Test;
-import org.onlab.stc.MonitorLayout.Box;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.stc.CompilerTest.getStream;
-import static org.onlab.stc.CompilerTest.stageTestResource;
-import static org.onlab.stc.MonitorLayout.SLOT_WIDTH;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Tests of the monitor layout functionality.
- */
-public class MonitorLayoutTest {
-
- private MonitorLayout layout;
-
- private Compiler getCompiler(String name) throws IOException {
- stageTestResource(name);
- Scenario scenario = loadScenario(getStream(name));
- Compiler compiler = new Compiler(scenario);
- compiler.compile();
- return compiler;
- }
-
- @Test
- public void basic() throws IOException {
- layout = new MonitorLayout(getCompiler("layout-basic.xml"));
- validate(layout, null, 0, 1, 5, 2);
- validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
- validate(layout, "b", 2, 2, 1, 1, 0, 0);
- validate(layout, "f", 3, 3, 1);
-
- validate(layout, "g", 1, 1, 4, 1, 1, SLOT_WIDTH / 2);
- validate(layout, "c", 2, 1, 1);
- validate(layout, "d", 3, 2, 1);
- validate(layout, "e", 4, 3, 1);
- }
-
- @Test
- public void basicNest() throws IOException {
- layout = new MonitorLayout(getCompiler("layout-basic-nest.xml"));
- validate(layout, null, 0, 1, 6, 2);
- validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
- validate(layout, "b", 2, 2, 1);
- validate(layout, "f", 3, 3, 1);
-
- validate(layout, "g", 1, 1, 5, 1);
- validate(layout, "c", 2, 1, 1);
-
- validate(layout, "gg", 3, 2, 3, 1);
- validate(layout, "d", 4, 1, 1);
- validate(layout, "e", 5, 2, 1);
- }
-
- @Test
- public void staggeredDependencies() throws IOException {
- layout = new MonitorLayout(getCompiler("layout-staggered-dependencies.xml"));
- validate(layout, null, 0, 1, 7, 4);
- validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH - SLOT_WIDTH / 2);
- validate(layout, "aa", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
- validate(layout, "b", 2, 2, 1);
- validate(layout, "f", 3, 3, 1);
-
- validate(layout, "g", 1, 1, 5, 2, 1, +SLOT_WIDTH / 2);
- validate(layout, "c", 2, 1, 1);
-
- validate(layout, "gg", 3, 2, 3, 2);
- validate(layout, "d", 4, 1, 1);
- validate(layout, "dd", 4, 1, 1);
- validate(layout, "e", 5, 2, 1);
-
- validate(layout, "i", 6, 6, 1);
- }
-
- @Test
- public void deepNext() throws IOException {
- layout = new MonitorLayout(getCompiler("layout-deep-nest.xml"));
- validate(layout, null, 0, 1, 7, 6);
- validate(layout, "a", 1, 1, 1);
- validate(layout, "aa", 1, 1, 1);
- validate(layout, "b", 2, 2, 1);
- validate(layout, "f", 3, 3, 1);
-
- validate(layout, "g", 1, 1, 5, 2);
- validate(layout, "c", 2, 1, 1);
-
- validate(layout, "gg", 3, 2, 3, 2);
- validate(layout, "d", 4, 1, 1);
- validate(layout, "dd", 4, 1, 1);
- validate(layout, "e", 5, 2, 1);
-
- validate(layout, "i", 6, 6, 1);
-
- validate(layout, "g1", 1, 1, 6, 2);
- validate(layout, "g2", 2, 1, 5, 2);
- validate(layout, "g3", 3, 1, 4, 2);
- validate(layout, "u", 4, 1, 1);
- validate(layout, "v", 4, 1, 1);
- validate(layout, "w", 5, 2, 1);
- validate(layout, "z", 6, 3, 1);
- }
-
-
- private void validate(MonitorLayout layout, String name,
- int absoluteTier, int tier, int depth, int breadth) {
- Box b = layout.get(name);
- assertEquals("incorrect absolute tier", absoluteTier, b.absoluteTier());
- assertEquals("incorrect tier", tier, b.tier());
- assertEquals("incorrect depth", depth, b.depth());
- assertEquals("incorrect breadth", breadth, b.breadth());
- }
-
- private void validate(MonitorLayout layout, String name,
- int absoluteTier, int tier, int depth, int breadth,
- int top, int center) {
- validate(layout, name, absoluteTier, tier, depth, breadth);
- Box b = layout.get(name);
- assertEquals("incorrect top", top, b.top());
- assertEquals("incorrect center", center, b.center());
- }
-
- private void validate(MonitorLayout layout, String name,
- int absoluteTier, int tier, int depth) {
- validate(layout, name, absoluteTier, tier, depth, 1);
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java
deleted file mode 100644
index 2aa51747..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test scenario entity.
- */
-public class ScenarioTest {
-
- @Test
- public void basics() throws ConfigurationException {
- Scenario scenario = loadScenario(getClass().getResourceAsStream("scenario.xml"));
- assertEquals("incorrect name", "foo", scenario.name());
- assertEquals("incorrect description", "Test Scenario", scenario.description());
- assertEquals("incorrect logDir", "Test Scenario", scenario.description());
- assertEquals("incorrect definition", "Test Scenario",
- scenario.definition().getString("[@description]"));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void badStream() throws ConfigurationException {
- loadScenario(getClass().getResourceAsStream("no.xml"));
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java
deleted file mode 100644
index 74d50241..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.io.Files;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.util.Tools;
-
-import java.io.File;
-import java.io.IOException;
-
-import static com.google.common.base.Preconditions.checkState;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.stc.Coordinator.Status.SUCCEEDED;
-
-/**
- * Test of the step processor.
- */
-public class StepProcessorTest {
-
- static final File DIR = Files.createTempDir();
- private final Listener delegate = new Listener();
-
- @BeforeClass
- public static void setUpClass() {
- StepProcessor.launcher = "echo";
- checkState(DIR.exists() || DIR.mkdirs(), "Unable to create directory");
- }
-
- @AfterClass
- public static void tearDownClass() throws IOException {
- Tools.removeDirectory(DIR.getPath());
- }
-
- @Test
- public void basics() {
- Step step = new Step("foo", "ls " + DIR.getAbsolutePath(), null, null, null);
- StepProcessor processor = new StepProcessor(step, DIR, delegate, step.command());
- processor.run();
- assertTrue("should be started", delegate.started);
- assertTrue("should be stopped", delegate.stopped);
- assertEquals("incorrect status", SUCCEEDED, delegate.status);
- assertTrue("should have output", delegate.output);
- }
-
- private class Listener implements StepProcessListener {
-
- private Coordinator.Status status;
- private boolean started, stopped, output;
-
- @Override
- public void onStart(Step step, String command) {
- started = true;
- }
-
- @Override
- public void onCompletion(Step step, Coordinator.Status status) {
- stopped = true;
- this.status = status;
- }
-
- @Override
- public void onOutput(Step step, String line) {
- output = true;
- }
- }
-
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepTest.java b/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepTest.java
deleted file mode 100644
index 71083624..00000000
--- a/framework/src/onos/utils/stc/src/test/java/org/onlab/stc/StepTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-/**
- * Test of the test step entity.
- */
-public class StepTest {
-
- protected static final String NAME = "step";
- protected static final String CMD = "command";
- protected static final String ENV = "environment";
- protected static final String CWD = "directory";
- protected Group parent;
-
- @Before
- public void setUp() throws ConfigurationException {
- parent = new Group("parent", null, null, null, null);
- }
-
- @Test
- public void basics() {
- Step step = new Step(NAME, CMD, ENV, CWD, parent);
- assertEquals("incorrect name", NAME, step.name());
- assertEquals("incorrect command", CMD, step.command());
- assertEquals("incorrect env", ENV, step.env());
- assertEquals("incorrect cwd", CWD, step.cwd());
- assertSame("incorrect group", parent, step.group());
- }
-
- @Test
- public void equality() {
- Step s1 = new Step(NAME, CMD, null, null, parent);
- Step s2 = new Step(NAME, CMD, ENV, CWD, null);
- Step s3 = new Step("foo", null, null, null, parent);
- new EqualsTester()
- .addEqualityGroup(s1, s2)
- .addEqualityGroup(s3)
- .testEquals();
- }
-} \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml
deleted file mode 100644
index 19c48db1..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="basic-nest">
- <step name="a"/>
- <step name="b" requires="a"/>
- <step name="f" requires="b"/>
- <group name="g">
- <step name="c"/>
- <group name="gg" requires="c">
- <step name="d"/>
- <step name="e" requires="d"/>
- </group>
- </group>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml
deleted file mode 100644
index d7dc1383..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="basic">
- <step name="a"/>
- <step name="b" requires="a"/>
- <step name="f" requires="b"/>
- <group name="g">
- <step name="c"/>
- <step name="d" requires="c"/>
- <step name="e" requires="d"/>
- </group>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml
deleted file mode 100644
index bbe1ac19..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="basic-nest">
- <step name="a"/>
- <step name="aa"/>
- <step name="b" requires="a"/>
- <step name="f" requires="b,aa"/>
- <group name="g">
- <step name="c"/>
- <group name="gg" requires="c">
- <step name="d"/>
- <step name="dd" requires="c"/>
- <step name="e" requires="d"/>
- </group>
- </group>
- <step name="i" requires="f,g"/>
-
- <group name="g1">
- <group name="g2">
- <group name="g3">
- <step name="u"/>
- <step name="v"/>
- <step name="w" requires="u,v"/>
- <step name="z" requires="u,w"/>
- </group>
- </group>
- </group>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml
deleted file mode 100644
index 318b4ba1..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="basic-nest">
- <step name="a"/>
- <step name="aa"/>
- <step name="b" requires="a"/>
- <step name="f" requires="b,aa"/>
- <group name="g">
- <step name="c"/>
- <group name="gg" requires="c">
- <step name="d"/>
- <step name="dd" requires="c"/>
- <step name="e" requires="d"/>
- </group>
- </group>
- <step name="i" requires="f,g"/>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml
deleted file mode 100644
index e5cb6f29..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<scenario name="one" description="" logDir="/tmp/junit-stc/one">
- <step name="yolo" exec="some-command args"/>
- <step name="hello" exec="some-command other args" requires="yolo"/>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/scenario.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/scenario.xml
deleted file mode 100644
index 533b11ea..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/scenario.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="foo" description="Test Scenario" logDir="${test.dir}/foo">
- <import file="${test.dir}/one-scenario.xml" namespace="foo"/>
-
- <import file="${test.dir}/two-scenario.xml"/>
-
- <dependency name="dude" requires="~yolo"/>
-
- <step name="yo" exec="some-command ${HOME} and ${prop.foo} args" if="${prop.foo}"/>
- <step name="hi" exec="some-command ${prop.bar} or ${HOME} other args"/>
- <step name="there" exec="another-command" requires="yo,hi"/>
-
- <step name="maybe" exec="another-command" requires="~hi" unless="${prop.foo}"/>
-
- <group name="alpha" exec="same-command args" requires="yo">
- <step name="one" exec="asdads"/>
- <step name="two" exec="asdads"/>
- <group name="three" exec="asdads" requires="one,two">
- <step name="three.a"/>
- <step name="three.b" requires="three.a"/>
- <step name="three.c" requires="three.b"/>
- </group>
- </group>
-
- <dependency name="maybe" requires="yo"/>
-
- <parallel var="${TOC#}" requires="alpha">
- <step name="ping-${#}" exec="asdads ${TOC#}"/>
- <step name="pong-${#}" exec="asdads"/>
- <step name="ding-${#}" exec="asdads" requires="ping-${#},pong-${#}"/>
- <dependency name="maybe" requires="ding-${#}"/>
- </parallel>
-
- <sequential var="${TOC#}" requires="alpha" starts="fifi-${#},gigi-${#}" ends="gaga-${#-1}">
- <step name="fifi-${#}" exec="asdads ${TOC#}"/>
- <step name="gigi-${#}" exec="asdads"/>
- <step name="gaga-${#}" exec="asdads" requires="fifi-${#},gigi-${#}"/>
- <dependency name="maybe" requires="gaga-${#}"/>
- </sequential>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml
deleted file mode 100644
index c70fe872..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<scenario name="foo" description="Simple Test Scenario" logDir="/tmp/junit-stc/foo">
- <group name="alpha" exec="same-command args">
- <step name="one" exec="asdads"/>
- <step name="two" exec="asdads"/>
- <group name="three" exec="asdads" requires="one,two">
- <step name="three.a"/>
- <step name="three.b" requires="three.a"/>
- <step name="three.c" requires="three.b"/>
- </group>
- </group>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml b/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml
deleted file mode 100644
index 0d6135d5..00000000
--- a/framework/src/onos/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
- ~ Copyright 2015 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<scenario name="two" description="" logDir="/tmp/junit-stc/two">
- <step name="dude" exec="some-command args"/>
- <step name="waz" exec="some-command other args"/>
- <step name="up" exec="another-command" requires="dude,waz"/>
-</scenario> \ No newline at end of file
diff --git a/framework/src/onos/utils/thirdparty/pom.xml b/framework/src/onos/utils/thirdparty/pom.xml
deleted file mode 100644
index d383bd60..00000000
--- a/framework/src/onos/utils/thirdparty/pom.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 Open Networking Laboratory
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-utils</artifactId>
- <version>1.4.0-rc1</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onlab-thirdparty</artifactId>
- <packaging>bundle</packaging>
-
- <description>ONLab third-party dependencies</description>
-
- <dependencies>
- <dependency>
- <groupId>com.googlecode.concurrent-trees</groupId>
- <artifactId>concurrent-trees</artifactId>
- </dependency>
-
- <dependency>
- <!-- FIXME once fixes get merged to upstream -->
- <groupId>org.onosproject</groupId>
- <artifactId>copycat-api</artifactId>
- <version>${copycat.version}</version>
- </dependency>
-
- <dependency>
- <!-- FIXME once fixes get merged to upstream -->
- <groupId>org.onosproject</groupId>
- <artifactId>copycat-core</artifactId>
- <version>${copycat.version}</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <configuration>
- <createSourcesJar>true</createSourcesJar>
-
- <artifactSet>
- <excludes>
- <!-- exclude OSGi-ready transitive dependencies -->
- <exclude>com.google.guava:guava</exclude>
- <exclude>com.esotericsoftware:*</exclude>
- <exclude>org.ow2.asm:asm</exclude>
- <exclude>org.objenesis:objenesis</exclude>
- <exclude>io.netty:*</exclude>
- </excludes>
- </artifactSet>
-
- <filters>
-
- <filter>
- <artifact>com.googlecode.concurrent-trees:concurrent-trees</artifact>
- <includes>
- <include>com/googlecode/**</include>
- </includes>
- </filter>
-
- <filter>
- <artifact>org.onosproject:copycat*</artifact>
- <includes>
- <include>**</include>
- </includes>
- </filter>
-
- </filters>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- com.googlecode.concurrenttrees.*;net.kuujo.copycat.*
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/utils/thirdparty/src/main/java/org/onlab/thirdparty/OnlabThirdparty.java b/framework/src/onos/utils/thirdparty/src/main/java/org/onlab/thirdparty/OnlabThirdparty.java
deleted file mode 100644
index 217ee026..00000000
--- a/framework/src/onos/utils/thirdparty/src/main/java/org/onlab/thirdparty/OnlabThirdparty.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.thirdparty;
-
-
-/**
- * Empty class required to get the onlab-thirdparty module to build properly.
- *
- * NOTE Required for shade plugin to operate.
- */
-public class OnlabThirdparty {
-
-}