Port the Router functionality from SDN-IP.
As part of this we added an onlab-thirdparty artifact which allows us to bring in dependencies that aren't bundles.
Showing
12 changed files
with
473 additions
and
1 deletions
| ... | @@ -36,6 +36,12 @@ | ... | @@ -36,6 +36,12 @@ |
| 36 | <groupId>com.google.guava</groupId> | 36 | <groupId>com.google.guava</groupId> |
| 37 | <artifactId>guava</artifactId> | 37 | <artifactId>guava</artifactId> |
| 38 | </dependency> | 38 | </dependency> |
| 39 | + | ||
| 40 | + <dependency> | ||
| 41 | + <groupId>org.onlab.onos</groupId> | ||
| 42 | + <artifactId>onlab-thirdparty</artifactId> | ||
| 43 | + </dependency> | ||
| 44 | + | ||
| 39 | </dependencies> | 45 | </dependencies> |
| 40 | 46 | ||
| 41 | </project> | 47 | </project> | ... | ... |
| 1 | +package org.onlab.onos.sdnip; | ||
| 2 | + | ||
| 3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 4 | + | ||
| 5 | +import java.util.Objects; | ||
| 6 | + | ||
| 7 | +import org.onlab.packet.IpAddress; | ||
| 8 | +import org.onlab.packet.IpPrefix; | ||
| 9 | + | ||
| 10 | +import com.google.common.base.MoreObjects; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * Represents a route entry for an IP prefix. | ||
| 14 | + */ | ||
| 15 | +public class RouteEntry { | ||
| 16 | + private final IpPrefix prefix; // The IP prefix | ||
| 17 | + private final IpAddress nextHop; // Next-hop IP address | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Class constructor. | ||
| 21 | + * | ||
| 22 | + * @param prefix the IP prefix of the route | ||
| 23 | + * @param nextHop the next hop IP address for the route | ||
| 24 | + */ | ||
| 25 | + public RouteEntry(IpPrefix prefix, IpAddress nextHop) { | ||
| 26 | + this.prefix = checkNotNull(prefix); | ||
| 27 | + this.nextHop = checkNotNull(nextHop); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * Returns the IP prefix of the route. | ||
| 32 | + * | ||
| 33 | + * @return the IP prefix of the route | ||
| 34 | + */ | ||
| 35 | + public IpPrefix prefix() { | ||
| 36 | + return prefix; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Returns the next hop IP address for the route. | ||
| 41 | + * | ||
| 42 | + * @return the next hop IP address for the route | ||
| 43 | + */ | ||
| 44 | + public IpAddress nextHop() { | ||
| 45 | + return nextHop; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * Creates the binary string representation of an IPv4 prefix. | ||
| 50 | + * The string length is equal to the prefix length. | ||
| 51 | + * | ||
| 52 | + * @param ip4Prefix the IPv4 prefix to use | ||
| 53 | + * @return the binary string representation | ||
| 54 | + */ | ||
| 55 | + static String createBinaryString(IpPrefix ip4Prefix) { | ||
| 56 | + if (ip4Prefix.prefixLength() == 0) { | ||
| 57 | + return ""; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); | ||
| 61 | + long value = ip4Prefix.toRealInt(); | ||
| 62 | + for (int i = 0; i < ip4Prefix.prefixLength(); i++) { | ||
| 63 | + long mask = 1 << (IpAddress.MAX_INET_MASK - 1 - i); | ||
| 64 | + result.append(((value & mask) == 0) ? "0" : "1"); | ||
| 65 | + } | ||
| 66 | + return result.toString(); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @Override | ||
| 70 | + public boolean equals(Object other) { | ||
| 71 | + if (this == other) { | ||
| 72 | + return true; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + // | ||
| 76 | + // NOTE: Subclasses are considered as change of identity, hence | ||
| 77 | + // equals() will return false if the class type doesn't match. | ||
| 78 | + // | ||
| 79 | + if (other == null || getClass() != other.getClass()) { | ||
| 80 | + return false; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + RouteEntry otherRoute = (RouteEntry) other; | ||
| 84 | + return Objects.equals(this.prefix, otherRoute.prefix) && | ||
| 85 | + Objects.equals(this.nextHop, otherRoute.nextHop); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @Override | ||
| 89 | + public int hashCode() { | ||
| 90 | + return Objects.hash(prefix, nextHop); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + @Override | ||
| 94 | + public String toString() { | ||
| 95 | + return MoreObjects.toStringHelper(getClass()) | ||
| 96 | + .add("prefix", prefix) | ||
| 97 | + .add("nextHop", nextHop) | ||
| 98 | + .toString(); | ||
| 99 | + } | ||
| 100 | +} |
| 1 | +package org.onlab.onos.sdnip; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * An interface to receive route updates from route providers. | ||
| 5 | + */ | ||
| 6 | +public interface RouteListener { | ||
| 7 | + /** | ||
| 8 | + * Receives a route update from a route provider. | ||
| 9 | + * | ||
| 10 | + * @param routeUpdate the updated route information | ||
| 11 | + */ | ||
| 12 | + public void update(RouteUpdate routeUpdate); | ||
| 13 | +} |
| 1 | +package org.onlab.onos.sdnip; | ||
| 2 | + | ||
| 3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 4 | + | ||
| 5 | +import java.util.Objects; | ||
| 6 | + | ||
| 7 | +import com.google.common.base.MoreObjects; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Represents a change in routing information. | ||
| 11 | + */ | ||
| 12 | +public class RouteUpdate { | ||
| 13 | + private final Type type; // The route update type | ||
| 14 | + private final RouteEntry routeEntry; // The updated route entry | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * Specifies the type of a route update. | ||
| 18 | + * <p/> | ||
| 19 | + * Route updates can either provide updated information for a route, or | ||
| 20 | + * withdraw a previously updated route. | ||
| 21 | + */ | ||
| 22 | + public enum Type { | ||
| 23 | + /** | ||
| 24 | + * The update contains updated route information for a route. | ||
| 25 | + */ | ||
| 26 | + UPDATE, | ||
| 27 | + /** | ||
| 28 | + * The update withdraws the route, meaning any previous information is | ||
| 29 | + * no longer valid. | ||
| 30 | + */ | ||
| 31 | + DELETE | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * Class constructor. | ||
| 36 | + * | ||
| 37 | + * @param type the type of the route update | ||
| 38 | + * @param routeEntry the route entry with the update | ||
| 39 | + */ | ||
| 40 | + public RouteUpdate(Type type, RouteEntry routeEntry) { | ||
| 41 | + this.type = type; | ||
| 42 | + this.routeEntry = checkNotNull(routeEntry); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Returns the type of the route update. | ||
| 47 | + * | ||
| 48 | + * @return the type of the update | ||
| 49 | + */ | ||
| 50 | + public Type type() { | ||
| 51 | + return type; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * Returns the route entry the route update is for. | ||
| 56 | + * | ||
| 57 | + * @return the route entry the route update is for | ||
| 58 | + */ | ||
| 59 | + public RouteEntry routeEntry() { | ||
| 60 | + return routeEntry; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public boolean equals(Object other) { | ||
| 65 | + if (other == this) { | ||
| 66 | + return true; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + if (!(other instanceof RouteUpdate)) { | ||
| 70 | + return false; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + RouteUpdate otherUpdate = (RouteUpdate) other; | ||
| 74 | + | ||
| 75 | + return Objects.equals(this.type, otherUpdate.type) && | ||
| 76 | + Objects.equals(this.routeEntry, otherUpdate.routeEntry); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public int hashCode() { | ||
| 81 | + return Objects.hash(type, routeEntry); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + @Override | ||
| 85 | + public String toString() { | ||
| 86 | + return MoreObjects.toStringHelper(getClass()) | ||
| 87 | + .add("type", type) | ||
| 88 | + .add("routeEntry", routeEntry) | ||
| 89 | + .toString(); | ||
| 90 | + } | ||
| 91 | +} |
This diff is collapsed. Click to expand it.
| ... | @@ -9,7 +9,10 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -9,7 +9,10 @@ import org.apache.felix.scr.annotations.Reference; |
| 9 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 9 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 10 | import org.onlab.onos.net.host.HostService; | 10 | import org.onlab.onos.net.host.HostService; |
| 11 | import org.onlab.onos.net.intent.IntentService; | 11 | import org.onlab.onos.net.intent.IntentService; |
| 12 | +import org.onlab.onos.sdnip.RouteUpdate.Type; | ||
| 12 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; | 13 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; |
| 14 | +import org.onlab.packet.IpAddress; | ||
| 15 | +import org.onlab.packet.IpPrefix; | ||
| 13 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
| 14 | 17 | ||
| 15 | /** | 18 | /** |
| ... | @@ -28,6 +31,7 @@ public class SdnIp { | ... | @@ -28,6 +31,7 @@ public class SdnIp { |
| 28 | 31 | ||
| 29 | private SdnIpConfigReader config; | 32 | private SdnIpConfigReader config; |
| 30 | private PeerConnectivity peerConnectivity; | 33 | private PeerConnectivity peerConnectivity; |
| 34 | + private Router router; | ||
| 31 | 35 | ||
| 32 | @Activate | 36 | @Activate |
| 33 | protected void activate() { | 37 | protected void activate() { |
| ... | @@ -41,6 +45,14 @@ public class SdnIp { | ... | @@ -41,6 +45,14 @@ public class SdnIp { |
| 41 | peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); | 45 | peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); |
| 42 | peerConnectivity.start(); | 46 | peerConnectivity.start(); |
| 43 | 47 | ||
| 48 | + router = new Router(intentService, hostService, config, interfaceService); | ||
| 49 | + router.start(); | ||
| 50 | + | ||
| 51 | + // TODO need to disable link discovery on external ports | ||
| 52 | + | ||
| 53 | + router.update(new RouteUpdate(Type.UPDATE, new RouteEntry( | ||
| 54 | + IpPrefix.valueOf("172.16.20.0/24"), | ||
| 55 | + IpAddress.valueOf("192.168.10.1")))); | ||
| 44 | } | 56 | } |
| 45 | 57 | ||
| 46 | @Deactivate | 58 | @Deactivate | ... | ... |
| 1 | +package org.onlab.onos.sdnip; | ||
| 2 | + | ||
| 3 | +import static org.hamcrest.Matchers.is; | ||
| 4 | +import static org.hamcrest.Matchers.not; | ||
| 5 | +import static org.junit.Assert.assertThat; | ||
| 6 | + | ||
| 7 | +import org.junit.Test; | ||
| 8 | +import org.onlab.packet.IpAddress; | ||
| 9 | +import org.onlab.packet.IpPrefix; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * Unit tests for the RouteEntry class. | ||
| 13 | + */ | ||
| 14 | +public class RouteEntryTest { | ||
| 15 | + /** | ||
| 16 | + * Tests valid class constructor. | ||
| 17 | + */ | ||
| 18 | + @Test | ||
| 19 | + public void testConstructor() { | ||
| 20 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 21 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
| 22 | + | ||
| 23 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
| 24 | + assertThat(routeEntry.toString(), | ||
| 25 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Tests invalid class constructor for null IPv4 prefix. | ||
| 30 | + */ | ||
| 31 | + @Test(expected = NullPointerException.class) | ||
| 32 | + public void testInvalidConstructorNullPrefix() { | ||
| 33 | + IpPrefix prefix = null; | ||
| 34 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
| 35 | + | ||
| 36 | + new RouteEntry(prefix, nextHop); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Tests invalid class constructor for null IPv4 next-hop. | ||
| 41 | + */ | ||
| 42 | + @Test(expected = NullPointerException.class) | ||
| 43 | + public void testInvalidConstructorNullNextHop() { | ||
| 44 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 45 | + IpAddress nextHop = null; | ||
| 46 | + | ||
| 47 | + new RouteEntry(prefix, nextHop); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * Tests getting the fields of a route entry. | ||
| 52 | + */ | ||
| 53 | + @Test | ||
| 54 | + public void testGetFields() { | ||
| 55 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 56 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
| 57 | + | ||
| 58 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
| 59 | + assertThat(routeEntry.prefix(), is(prefix)); | ||
| 60 | + assertThat(routeEntry.nextHop(), is(nextHop)); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * Tests creating a binary string from IPv4 prefix. | ||
| 65 | + */ | ||
| 66 | + @Test | ||
| 67 | + public void testCreateBinaryString() { | ||
| 68 | + IpPrefix prefix; | ||
| 69 | + | ||
| 70 | + prefix = IpPrefix.valueOf("0.0.0.0/0"); | ||
| 71 | + assertThat(RouteEntry.createBinaryString(prefix), is("")); | ||
| 72 | + | ||
| 73 | + prefix = IpPrefix.valueOf("192.168.166.0/22"); | ||
| 74 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
| 75 | + is("1100000010101000101001")); | ||
| 76 | + | ||
| 77 | + prefix = IpPrefix.valueOf("192.168.166.0/23"); | ||
| 78 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
| 79 | + is("11000000101010001010011")); | ||
| 80 | + | ||
| 81 | + prefix = IpPrefix.valueOf("192.168.166.0/24"); | ||
| 82 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
| 83 | + is("110000001010100010100110")); | ||
| 84 | + | ||
| 85 | + prefix = IpPrefix.valueOf("130.162.10.1/25"); | ||
| 86 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
| 87 | + is("1000001010100010000010100")); | ||
| 88 | + | ||
| 89 | + prefix = IpPrefix.valueOf("255.255.255.255/32"); | ||
| 90 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
| 91 | + is("11111111111111111111111111111111")); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + /** | ||
| 95 | + * Tests equality of {@link RouteEntry}. | ||
| 96 | + */ | ||
| 97 | + @Test | ||
| 98 | + public void testEquality() { | ||
| 99 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 100 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
| 101 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
| 102 | + | ||
| 103 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 104 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
| 105 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
| 106 | + | ||
| 107 | + assertThat(routeEntry1, is(routeEntry2)); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + /** | ||
| 111 | + * Tests non-equality of {@link RouteEntry}. | ||
| 112 | + */ | ||
| 113 | + @Test | ||
| 114 | + public void testNonEquality() { | ||
| 115 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 116 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
| 117 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
| 118 | + | ||
| 119 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/25"); // Different | ||
| 120 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
| 121 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
| 122 | + | ||
| 123 | + IpPrefix prefix3 = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 124 | + IpAddress nextHop3 = IpAddress.valueOf("5.6.7.9"); // Different | ||
| 125 | + RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3); | ||
| 126 | + | ||
| 127 | + assertThat(routeEntry1, is(not(routeEntry2))); | ||
| 128 | + assertThat(routeEntry1, is(not(routeEntry3))); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + /** | ||
| 132 | + * Tests object string representation. | ||
| 133 | + */ | ||
| 134 | + @Test | ||
| 135 | + public void testToString() { | ||
| 136 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
| 137 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
| 138 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
| 139 | + | ||
| 140 | + assertThat(routeEntry.toString(), | ||
| 141 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
| 142 | + } | ||
| 143 | +} |
| ... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
| 30 | 30 | ||
| 31 | <bundle>mvn:org.codehaus.jackson/jackson-core-asl/1.9.13</bundle> | 31 | <bundle>mvn:org.codehaus.jackson/jackson-core-asl/1.9.13</bundle> |
| 32 | <bundle>mvn:org.codehaus.jackson/jackson-mapper-asl/1.9.13</bundle> | 32 | <bundle>mvn:org.codehaus.jackson/jackson-mapper-asl/1.9.13</bundle> |
| 33 | + <bundle>mvn:org.onlab.onos/onlab-thirdparty/1.0.0-SNAPSHOT</bundle> | ||
| 33 | </feature> | 34 | </feature> |
| 34 | 35 | ||
| 35 | <feature name="onos-thirdparty-web" version="1.0.0" | 36 | <feature name="onos-thirdparty-web" version="1.0.0" | ... | ... |
| ... | @@ -107,7 +107,13 @@ | ... | @@ -107,7 +107,13 @@ |
| 107 | </dependency> | 107 | </dependency> |
| 108 | 108 | ||
| 109 | <dependency> | 109 | <dependency> |
| 110 | - <groupId>commons-lang</groupId> | 110 | + <groupId>com.googlecode.concurrent-trees</groupId> |
| 111 | + <artifactId>concurrent-trees</artifactId> | ||
| 112 | + <version>2.4.0</version> | ||
| 113 | + </dependency> | ||
| 114 | + | ||
| 115 | + <dependency> | ||
| 116 | + <groupId>commons-lang</groupId> | ||
| 111 | <artifactId>commons-lang</artifactId> | 117 | <artifactId>commons-lang</artifactId> |
| 112 | <version>2.6</version> | 118 | <version>2.6</version> |
| 113 | </dependency> | 119 | </dependency> |
| ... | @@ -266,6 +272,13 @@ | ... | @@ -266,6 +272,13 @@ |
| 266 | <artifactId>onos-of-api</artifactId> | 272 | <artifactId>onos-of-api</artifactId> |
| 267 | <version>${project.version}</version> | 273 | <version>${project.version}</version> |
| 268 | </dependency> | 274 | </dependency> |
| 275 | + | ||
| 276 | + <dependency> | ||
| 277 | + <groupId>org.onlab.onos</groupId> | ||
| 278 | + <artifactId>onlab-thirdparty</artifactId> | ||
| 279 | + <version>${project.version}</version> | ||
| 280 | + </dependency> | ||
| 281 | + | ||
| 269 | <dependency> | 282 | <dependency> |
| 270 | <groupId>org.onlab.onos</groupId> | 283 | <groupId>org.onlab.onos</groupId> |
| 271 | <artifactId>onos-of-api</artifactId> | 284 | <artifactId>onos-of-api</artifactId> | ... | ... |
| ... | @@ -191,6 +191,15 @@ public final class IpAddress { | ... | @@ -191,6 +191,15 @@ public final class IpAddress { |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | /** | 193 | /** |
| 194 | + * Converts the IP address to a /32 IP prefix. | ||
| 195 | + * | ||
| 196 | + * @return the new IP prefix | ||
| 197 | + */ | ||
| 198 | + public IpPrefix toPrefix() { | ||
| 199 | + return IpPrefix.valueOf(octets, MAX_INET_MASK); | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + /** | ||
| 194 | * Helper for computing the mask value from CIDR. | 203 | * Helper for computing the mask value from CIDR. |
| 195 | * | 204 | * |
| 196 | * @return an integer bitmask | 205 | * @return an integer bitmask | ... | ... |
utils/thirdparty/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
| 5 | + <modelVersion>4.0.0</modelVersion> | ||
| 6 | + | ||
| 7 | + <parent> | ||
| 8 | + <groupId>org.onlab.onos</groupId> | ||
| 9 | + <artifactId>onlab-utils</artifactId> | ||
| 10 | + <version>1.0.0-SNAPSHOT</version> | ||
| 11 | + <relativePath>../pom.xml</relativePath> | ||
| 12 | + </parent> | ||
| 13 | + | ||
| 14 | + <artifactId>onlab-thirdparty</artifactId> | ||
| 15 | + <packaging>bundle</packaging> | ||
| 16 | + | ||
| 17 | + <description>ONLab third-party dependencies</description> | ||
| 18 | + | ||
| 19 | + <dependencies> | ||
| 20 | + <dependency> | ||
| 21 | + <groupId>com.googlecode.concurrent-trees</groupId> | ||
| 22 | + <artifactId>concurrent-trees</artifactId> | ||
| 23 | + <version>2.4.0</version> | ||
| 24 | + </dependency> | ||
| 25 | + </dependencies> | ||
| 26 | + | ||
| 27 | + <build> | ||
| 28 | + <plugins> | ||
| 29 | + <plugin> | ||
| 30 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 31 | + <artifactId>maven-shade-plugin</artifactId> | ||
| 32 | + <version>2.3</version> | ||
| 33 | + <configuration> | ||
| 34 | + <filters> | ||
| 35 | + <filter> | ||
| 36 | + <artifact>com.googlecode.concurrent-trees:concurrent-trees</artifact> | ||
| 37 | + <includes> | ||
| 38 | + <include>com/googlecode/**</include> | ||
| 39 | + </includes> | ||
| 40 | + | ||
| 41 | + </filter> | ||
| 42 | + <filter> | ||
| 43 | + <artifact>com.google.guava:guava</artifact> | ||
| 44 | + <excludes> | ||
| 45 | + <exclude>**</exclude> | ||
| 46 | + </excludes> | ||
| 47 | + </filter> | ||
| 48 | + </filters> | ||
| 49 | + </configuration> | ||
| 50 | + <executions> | ||
| 51 | + <execution> | ||
| 52 | + <phase>package</phase> | ||
| 53 | + <goals> | ||
| 54 | + <goal>shade</goal> | ||
| 55 | + </goals> | ||
| 56 | + </execution> | ||
| 57 | + </executions> | ||
| 58 | + </plugin> | ||
| 59 | + <plugin> | ||
| 60 | + <groupId>org.apache.felix</groupId> | ||
| 61 | + <artifactId>maven-bundle-plugin</artifactId> | ||
| 62 | + <configuration> | ||
| 63 | + <instructions> | ||
| 64 | + <Export-Package> | ||
| 65 | + com.googlecode.concurrenttrees.* | ||
| 66 | + </Export-Package> | ||
| 67 | + </instructions> | ||
| 68 | + </configuration> | ||
| 69 | + </plugin> | ||
| 70 | + </plugins> | ||
| 71 | + </build> | ||
| 72 | + | ||
| 73 | +</project> |
-
Please register or login to post a comment