Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
20 changed files
with
254 additions
and
130 deletions
| ... | @@ -62,6 +62,32 @@ | ... | @@ -62,6 +62,32 @@ |
| 62 | <groupId>org.osgi</groupId> | 62 | <groupId>org.osgi</groupId> |
| 63 | <artifactId>org.osgi.core</artifactId> | 63 | <artifactId>org.osgi.core</artifactId> |
| 64 | </dependency> | 64 | </dependency> |
| 65 | + | ||
| 66 | + <dependency> | ||
| 67 | + <groupId>org.onlab.onos</groupId> | ||
| 68 | + <artifactId>onlab-thirdparty</artifactId> | ||
| 69 | + </dependency> | ||
| 70 | + | ||
| 71 | + <dependency> | ||
| 72 | + <groupId>org.onlab.onos</groupId> | ||
| 73 | + <artifactId>onlab-misc</artifactId> | ||
| 74 | + </dependency> | ||
| 75 | + | ||
| 76 | + <dependency> | ||
| 77 | + <groupId>org.onlab.onos</groupId> | ||
| 78 | + <artifactId>onlab-junit</artifactId> | ||
| 79 | + <scope>test</scope> | ||
| 80 | + </dependency> | ||
| 81 | + | ||
| 82 | + <dependency> | ||
| 83 | + <groupId>org.onlab.onos</groupId> | ||
| 84 | + <artifactId>onos-cli</artifactId> | ||
| 85 | + <version>${project.version}</version> | ||
| 86 | + </dependency> | ||
| 87 | + <dependency> | ||
| 88 | + <groupId>org.apache.karaf.shell</groupId> | ||
| 89 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
| 90 | + </dependency> | ||
| 65 | </dependencies> | 91 | </dependencies> |
| 66 | 92 | ||
| 67 | <build> | 93 | <build> |
| ... | @@ -77,6 +103,7 @@ | ... | @@ -77,6 +103,7 @@ |
| 77 | ${project.groupId}.${project.artifactId} | 103 | ${project.groupId}.${project.artifactId} |
| 78 | </Bundle-SymbolicName> | 104 | </Bundle-SymbolicName> |
| 79 | <Import-Package> | 105 | <Import-Package> |
| 106 | + org.slf4j, | ||
| 80 | org.osgi.framework, | 107 | org.osgi.framework, |
| 81 | javax.ws.rs,javax.ws.rs.core, | 108 | javax.ws.rs,javax.ws.rs.core, |
| 82 | com.sun.jersey.api.core, | 109 | com.sun.jersey.api.core, | ... | ... |
| ... | @@ -16,43 +16,47 @@ | ... | @@ -16,43 +16,47 @@ |
| 16 | package org.onlab.onos.calendar; | 16 | package org.onlab.onos.calendar; |
| 17 | 17 | ||
| 18 | import java.net.URI; | 18 | import java.net.URI; |
| 19 | - | 19 | +import org.onlab.onos.net.ConnectPoint; |
| 20 | +import org.onlab.onos.net.DeviceId; | ||
| 21 | +import org.onlab.onos.net.intent.IntentService; | ||
| 22 | +import org.onlab.rest.BaseResource; | ||
| 20 | import javax.ws.rs.POST; | 23 | import javax.ws.rs.POST; |
| 21 | -import javax.ws.rs.Path; | 24 | +import javax.ws.rs.DELETE; |
| 22 | import javax.ws.rs.PathParam; | 25 | import javax.ws.rs.PathParam; |
| 23 | import javax.ws.rs.core.Response; | 26 | import javax.ws.rs.core.Response; |
| 24 | - | ||
| 25 | import org.onlab.onos.core.ApplicationId; | 27 | import org.onlab.onos.core.ApplicationId; |
| 26 | import org.onlab.onos.core.CoreService; | 28 | import org.onlab.onos.core.CoreService; |
| 27 | -import org.onlab.onos.net.ConnectPoint; | ||
| 28 | -import org.onlab.onos.net.DeviceId; | ||
| 29 | import org.onlab.onos.net.flow.DefaultTrafficSelector; | 29 | import org.onlab.onos.net.flow.DefaultTrafficSelector; |
| 30 | import org.onlab.onos.net.flow.TrafficSelector; | 30 | import org.onlab.onos.net.flow.TrafficSelector; |
| 31 | import org.onlab.onos.net.flow.TrafficTreatment; | 31 | import org.onlab.onos.net.flow.TrafficTreatment; |
| 32 | -import org.onlab.onos.net.intent.Intent; | 32 | +import org.onlab.onos.net.intent.PointToPointIntent; |
| 33 | -import org.onlab.onos.net.intent.IntentService; | ||
| 34 | -import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint; | ||
| 35 | -import org.onlab.onos.net.resource.BandwidthResourceRequest; | ||
| 36 | import org.onlab.packet.Ethernet; | 33 | import org.onlab.packet.Ethernet; |
| 37 | -import org.onlab.rest.BaseResource; | ||
| 38 | - | ||
| 39 | import static org.onlab.onos.net.PortNumber.portNumber; | 34 | import static org.onlab.onos.net.PortNumber.portNumber; |
| 40 | import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | 35 | import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; |
| 41 | 36 | ||
| 37 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 38 | +import org.slf4j.Logger; | ||
| 39 | + | ||
| 42 | /** | 40 | /** |
| 43 | * Web resource for triggering calendared intents. | 41 | * Web resource for triggering calendared intents. |
| 44 | */ | 42 | */ |
| 45 | -@Path("intent") | 43 | +@javax.ws.rs.Path("intent") |
| 46 | public class BandwidthCalendarResource extends BaseResource { | 44 | public class BandwidthCalendarResource extends BaseResource { |
| 47 | 45 | ||
| 46 | + private static final Logger log = getLogger(BandwidthCalendarResource.class); | ||
| 47 | + | ||
| 48 | + @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}") | ||
| 48 | @POST | 49 | @POST |
| 49 | - @Path("{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}") | ||
| 50 | public Response createIntent(@PathParam("src") String src, | 50 | public Response createIntent(@PathParam("src") String src, |
| 51 | @PathParam("dst") String dst, | 51 | @PathParam("dst") String dst, |
| 52 | @PathParam("srcPort") String srcPort, | 52 | @PathParam("srcPort") String srcPort, |
| 53 | @PathParam("dstPort") String dstPort, | 53 | @PathParam("dstPort") String dstPort, |
| 54 | @PathParam("bandwidth") String bandwidth) { | 54 | @PathParam("bandwidth") String bandwidth) { |
| 55 | - // TODO: implement calls to intent framework | 55 | + |
| 56 | + log.info("Receiving Create Intent request..."); | ||
| 57 | + log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} BW = {}", | ||
| 58 | + src, srcPort, dst, dstPort, bandwidth); | ||
| 59 | + | ||
| 56 | IntentService service = get(IntentService.class); | 60 | IntentService service = get(IntentService.class); |
| 57 | 61 | ||
| 58 | ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); | 62 | ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); |
| ... | @@ -61,13 +65,38 @@ public class BandwidthCalendarResource extends BaseResource { | ... | @@ -61,13 +65,38 @@ public class BandwidthCalendarResource extends BaseResource { |
| 61 | TrafficSelector selector = buildTrafficSelector(); | 65 | TrafficSelector selector = buildTrafficSelector(); |
| 62 | TrafficTreatment treatment = builder().build(); | 66 | TrafficTreatment treatment = builder().build(); |
| 63 | 67 | ||
| 64 | - Intent intent = new PointToPointIntentWithBandwidthConstraint( | 68 | + PointToPointIntent intentP2P = |
| 65 | - appId(), selector, treatment, | 69 | + new PointToPointIntent(appId(), selector, treatment, |
| 66 | - srcPoint, dstPoint, new BandwidthResourceRequest(Double.parseDouble(bandwidth))); | 70 | + srcPoint, dstPoint); |
| 67 | - service.submit(intent); | 71 | + service.submit(intentP2P); |
| 72 | + log.info("Submitted Calendar App intent: src = " + src + "dest = " + dst | ||
| 73 | + + "srcPort = " + srcPort + "destPort" + dstPort + "intentID = " + intentP2P.id().toString()); | ||
| 74 | + String reply = intentP2P.id().toString() + "\n"; | ||
| 68 | 75 | ||
| 69 | - return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint + | 76 | + return Response.ok(reply).build(); |
| 70 | - "; bw=" + bandwidth + "; intent service " + service).build(); | 77 | + } |
| 78 | + | ||
| 79 | + @javax.ws.rs.Path("/cancellation/{intentId}") | ||
| 80 | + @DELETE | ||
| 81 | + public Response withdrawIntent(@PathParam("intentId") String intentId) { | ||
| 82 | + | ||
| 83 | + log.info("Receiving Teardown request..."); | ||
| 84 | + log.info("Withdraw intentId = {} ", intentId); | ||
| 85 | + | ||
| 86 | + String reply = "ok\n"; | ||
| 87 | + return Response.ok(reply).build(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @javax.ws.rs.Path("/modification/{intentId}/{bandwidth}") | ||
| 91 | + @POST | ||
| 92 | + public Response modifyBandwidth(@PathParam("intentId") String intentId, | ||
| 93 | + @PathParam("bandwidth") String bandwidth) { | ||
| 94 | + | ||
| 95 | + log.info("Receiving Modify request..."); | ||
| 96 | + log.info("Modify bw for intentId = {} with new bandwidth = {}", intentId, bandwidth); | ||
| 97 | + | ||
| 98 | + String reply = "ok\n"; | ||
| 99 | + return Response.ok(reply).build(); | ||
| 71 | } | 100 | } |
| 72 | 101 | ||
| 73 | private TrafficSelector buildTrafficSelector() { | 102 | private TrafficSelector buildTrafficSelector() { |
| ... | @@ -86,5 +115,4 @@ public class BandwidthCalendarResource extends BaseResource { | ... | @@ -86,5 +115,4 @@ public class BandwidthCalendarResource extends BaseResource { |
| 86 | protected ApplicationId appId() { | 115 | protected ApplicationId appId() { |
| 87 | return get(CoreService.class).registerApplication("org.onlab.onos.calendar"); | 116 | return get(CoreService.class).registerApplication("org.onlab.onos.calendar"); |
| 88 | } | 117 | } |
| 89 | - | ||
| 90 | } | 118 | } | ... | ... |
| ... | @@ -188,7 +188,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { | ... | @@ -188,7 +188,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | @Override | 190 | @Override |
| 191 | - public Builder matchOpticalSignalType(Byte signalType) { | 191 | + public Builder matchOpticalSignalType(Short signalType) { |
| 192 | return add(Criteria.matchOpticalSignalType(signalType)); | 192 | return add(Criteria.matchOpticalSignalType(signalType)); |
| 193 | 193 | ||
| 194 | } | 194 | } | ... | ... |
| ... | @@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
| 27 | */ | 27 | */ |
| 28 | public enum Type { | 28 | public enum Type { |
| 29 | 29 | ||
| 30 | + // Request has been forwarded to MASTER Node | ||
| 30 | /** | 31 | /** |
| 31 | * Signifies that a batch operation has been initiated. | 32 | * Signifies that a batch operation has been initiated. |
| 32 | */ | 33 | */ |
| 33 | BATCH_OPERATION_REQUESTED, | 34 | BATCH_OPERATION_REQUESTED, |
| 34 | 35 | ||
| 36 | + // MASTER Node has pushed the batch down to the Device | ||
| 37 | + // (e.g., Received barrier reply) | ||
| 35 | /** | 38 | /** |
| 36 | * Signifies that a batch operation has completed. | 39 | * Signifies that a batch operation has completed. |
| 37 | */ | 40 | */ | ... | ... |
| ... | @@ -25,29 +25,29 @@ import com.google.common.collect.Lists; | ... | @@ -25,29 +25,29 @@ import com.google.common.collect.Lists; |
| 25 | public class FlowRuleBatchRequest { | 25 | public class FlowRuleBatchRequest { |
| 26 | 26 | ||
| 27 | private final int batchId; | 27 | private final int batchId; |
| 28 | - private final List<FlowEntry> toAdd; | 28 | + private final List<FlowRule> toAdd; |
| 29 | - private final List<FlowEntry> toRemove; | 29 | + private final List<FlowRule> toRemove; |
| 30 | 30 | ||
| 31 | - public FlowRuleBatchRequest(int batchId, List<? extends FlowEntry> toAdd, List<? extends FlowEntry> toRemove) { | 31 | + public FlowRuleBatchRequest(int batchId, List<? extends FlowRule> toAdd, List<? extends FlowRule> toRemove) { |
| 32 | this.batchId = batchId; | 32 | this.batchId = batchId; |
| 33 | this.toAdd = Collections.unmodifiableList(toAdd); | 33 | this.toAdd = Collections.unmodifiableList(toAdd); |
| 34 | this.toRemove = Collections.unmodifiableList(toRemove); | 34 | this.toRemove = Collections.unmodifiableList(toRemove); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | - public List<FlowEntry> toAdd() { | 37 | + public List<FlowRule> toAdd() { |
| 38 | return toAdd; | 38 | return toAdd; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | - public List<FlowEntry> toRemove() { | 41 | + public List<FlowRule> toRemove() { |
| 42 | return toRemove; | 42 | return toRemove; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | public FlowRuleBatchOperation asBatchOperation() { | 45 | public FlowRuleBatchOperation asBatchOperation() { |
| 46 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); | 46 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); |
| 47 | - for (FlowEntry e : toAdd) { | 47 | + for (FlowRule e : toAdd) { |
| 48 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e)); | 48 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e)); |
| 49 | } | 49 | } |
| 50 | - for (FlowEntry e : toRemove) { | 50 | + for (FlowRule e : toRemove) { |
| 51 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e)); | 51 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e)); |
| 52 | } | 52 | } |
| 53 | return new FlowRuleBatchOperation(entries); | 53 | return new FlowRuleBatchOperation(entries); | ... | ... |
| ... | @@ -147,7 +147,7 @@ public interface TrafficSelector { | ... | @@ -147,7 +147,7 @@ public interface TrafficSelector { |
| 147 | * @param signalType | 147 | * @param signalType |
| 148 | * @return a selection builder | 148 | * @return a selection builder |
| 149 | */ | 149 | */ |
| 150 | - public Builder matchOpticalSignalType(Byte signalType); | 150 | + public Builder matchOpticalSignalType(Short signalType); |
| 151 | 151 | ||
| 152 | /** | 152 | /** |
| 153 | * Builds an immutable traffic selector. | 153 | * Builds an immutable traffic selector. | ... | ... |
| ... | @@ -161,11 +161,11 @@ public final class Criteria { | ... | @@ -161,11 +161,11 @@ public final class Criteria { |
| 161 | /** | 161 | /** |
| 162 | * Creates a match on lambda field using the specified value. | 162 | * Creates a match on lambda field using the specified value. |
| 163 | * | 163 | * |
| 164 | - * @param lambda | 164 | + * @param sigType |
| 165 | * @return match criterion | 165 | * @return match criterion |
| 166 | */ | 166 | */ |
| 167 | - public static Criterion matchOpticalSignalType(Byte lambda) { | 167 | + public static Criterion matchOpticalSignalType(Short sigType) { |
| 168 | - return new OpticalSignalTypeCriterion(lambda, Type.OCH_SIGTYPE); | 168 | + return new OpticalSignalTypeCriterion(sigType, Type.OCH_SIGTYPE); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | 171 | ||
| ... | @@ -587,10 +587,10 @@ public final class Criteria { | ... | @@ -587,10 +587,10 @@ public final class Criteria { |
| 587 | 587 | ||
| 588 | public static final class OpticalSignalTypeCriterion implements Criterion { | 588 | public static final class OpticalSignalTypeCriterion implements Criterion { |
| 589 | 589 | ||
| 590 | - private final byte signalType; | 590 | + private final Short signalType; |
| 591 | private final Type type; | 591 | private final Type type; |
| 592 | 592 | ||
| 593 | - public OpticalSignalTypeCriterion(byte signalType, Type type) { | 593 | + public OpticalSignalTypeCriterion(Short signalType, Type type) { |
| 594 | this.signalType = signalType; | 594 | this.signalType = signalType; |
| 595 | this.type = type; | 595 | this.type = type; |
| 596 | } | 596 | } |
| ... | @@ -600,7 +600,7 @@ public final class Criteria { | ... | @@ -600,7 +600,7 @@ public final class Criteria { |
| 600 | return this.type; | 600 | return this.type; |
| 601 | } | 601 | } |
| 602 | 602 | ||
| 603 | - public Byte signalType() { | 603 | + public Short signalType() { |
| 604 | return this.signalType; | 604 | return this.signalType; |
| 605 | } | 605 | } |
| 606 | 606 | ... | ... |
| ... | @@ -15,7 +15,11 @@ | ... | @@ -15,7 +15,11 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onlab.onos.net.intent; | 16 | package org.onlab.onos.net.intent; |
| 17 | 17 | ||
| 18 | +import java.util.List; | ||
| 19 | + | ||
| 18 | import com.google.common.base.MoreObjects; | 20 | import com.google.common.base.MoreObjects; |
| 21 | +import com.google.common.collect.ImmutableList; | ||
| 22 | + | ||
| 19 | import org.onlab.onos.core.ApplicationId; | 23 | import org.onlab.onos.core.ApplicationId; |
| 20 | import org.onlab.onos.net.Path; | 24 | import org.onlab.onos.net.Path; |
| 21 | import org.onlab.onos.net.flow.TrafficSelector; | 25 | import org.onlab.onos.net.flow.TrafficSelector; |
| ... | @@ -28,7 +32,7 @@ import org.onlab.onos.net.resource.LinkResourceRequest; | ... | @@ -28,7 +32,7 @@ import org.onlab.onos.net.resource.LinkResourceRequest; |
| 28 | public class PathIntent extends ConnectivityIntent { | 32 | public class PathIntent extends ConnectivityIntent { |
| 29 | 33 | ||
| 30 | private final Path path; | 34 | private final Path path; |
| 31 | - private final LinkResourceRequest[] resourceRequests; | 35 | + private final List<LinkResourceRequest> resourceRequests; |
| 32 | 36 | ||
| 33 | /** | 37 | /** |
| 34 | * Creates a new point-to-point intent with the supplied ingress/egress | 38 | * Creates a new point-to-point intent with the supplied ingress/egress |
| ... | @@ -45,7 +49,7 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -45,7 +49,7 @@ public class PathIntent extends ConnectivityIntent { |
| 45 | super(id(PathIntent.class, selector, treatment, path), appId, | 49 | super(id(PathIntent.class, selector, treatment, path), appId, |
| 46 | resources(path.links()), selector, treatment); | 50 | resources(path.links()), selector, treatment); |
| 47 | this.path = path; | 51 | this.path = path; |
| 48 | - this.resourceRequests = resourceRequests; | 52 | + this.resourceRequests = ImmutableList.copyOf(resourceRequests); |
| 49 | } | 53 | } |
| 50 | 54 | ||
| 51 | /** | 55 | /** |
| ... | @@ -54,7 +58,7 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -54,7 +58,7 @@ public class PathIntent extends ConnectivityIntent { |
| 54 | protected PathIntent() { | 58 | protected PathIntent() { |
| 55 | super(); | 59 | super(); |
| 56 | this.path = null; | 60 | this.path = null; |
| 57 | - this.resourceRequests = new LinkResourceRequest[0]; | 61 | + this.resourceRequests = ImmutableList.of(); |
| 58 | } | 62 | } |
| 59 | 63 | ||
| 60 | /** | 64 | /** |
| ... | @@ -71,8 +75,9 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -71,8 +75,9 @@ public class PathIntent extends ConnectivityIntent { |
| 71 | return true; | 75 | return true; |
| 72 | } | 76 | } |
| 73 | 77 | ||
| 78 | + // TODO: consider changing return type | ||
| 74 | public LinkResourceRequest[] resourceRequests() { | 79 | public LinkResourceRequest[] resourceRequests() { |
| 75 | - return resourceRequests; | 80 | + return resourceRequests.toArray(new LinkResourceRequest[resourceRequests.size()]); |
| 76 | } | 81 | } |
| 77 | 82 | ||
| 78 | @Override | 83 | @Override | ... | ... |
| ... | @@ -371,10 +371,11 @@ public class FlowRuleManager | ... | @@ -371,10 +371,11 @@ public class FlowRuleManager |
| 371 | final FlowRuleBatchRequest request = event.subject(); | 371 | final FlowRuleBatchRequest request = event.subject(); |
| 372 | switch (event.type()) { | 372 | switch (event.type()) { |
| 373 | case BATCH_OPERATION_REQUESTED: | 373 | case BATCH_OPERATION_REQUESTED: |
| 374 | - for (FlowEntry entry : request.toAdd()) { | 374 | + // Request has been forwarded to MASTER Node, and was |
| 375 | + for (FlowRule entry : request.toAdd()) { | ||
| 375 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry)); | 376 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry)); |
| 376 | } | 377 | } |
| 377 | - for (FlowEntry entry : request.toRemove()) { | 378 | + for (FlowRule entry : request.toRemove()) { |
| 378 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry)); | 379 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry)); |
| 379 | } | 380 | } |
| 380 | // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ? | 381 | // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ? |
| ... | @@ -392,21 +393,15 @@ public class FlowRuleManager | ... | @@ -392,21 +393,15 @@ public class FlowRuleManager |
| 392 | Futures.getUnchecked(result))); | 393 | Futures.getUnchecked(result))); |
| 393 | } | 394 | } |
| 394 | }, futureListeners); | 395 | }, futureListeners); |
| 395 | - | ||
| 396 | break; | 396 | break; |
| 397 | + | ||
| 397 | case BATCH_OPERATION_COMPLETED: | 398 | case BATCH_OPERATION_COMPLETED: |
| 398 | - Set<FlowRule> failedItems = event.result().failedItems(); | 399 | + // MASTER Node has pushed the batch down to the Device |
| 399 | - for (FlowEntry entry : request.toAdd()) { | 400 | + |
| 400 | - if (!failedItems.contains(entry)) { | 401 | + // Note: RULE_ADDED will be posted |
| 401 | - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, entry)); | 402 | + // when Flow was actually confirmed by stats reply. |
| 402 | - } | ||
| 403 | - } | ||
| 404 | - for (FlowEntry entry : request.toRemove()) { | ||
| 405 | - if (!failedItems.contains(entry)) { | ||
| 406 | - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, entry)); | ||
| 407 | - } | ||
| 408 | - } | ||
| 409 | break; | 403 | break; |
| 404 | + | ||
| 410 | default: | 405 | default: |
| 411 | break; | 406 | break; |
| 412 | } | 407 | } | ... | ... |
| ... | @@ -79,6 +79,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn | ... | @@ -79,6 +79,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn |
| 79 | private ApplicationId appId; | 79 | private ApplicationId appId; |
| 80 | 80 | ||
| 81 | //final short WAVELENGTH = 80; | 81 | //final short WAVELENGTH = 80; |
| 82 | + static final short SIGNAL_TYPE = (short) 1; | ||
| 82 | 83 | ||
| 83 | @Activate | 84 | @Activate |
| 84 | public void activate() { | 85 | public void activate() { |
| ... | @@ -151,7 +152,9 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn | ... | @@ -151,7 +152,9 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn |
| 151 | 152 | ||
| 152 | prev = link.dst(); | 153 | prev = link.dst(); |
| 153 | selectorBuilder.matchInport(link.dst().port()); | 154 | selectorBuilder.matchInport(link.dst().port()); |
| 155 | + selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE); //todo | ||
| 154 | selectorBuilder.matchLambda((short) la.toInt()); | 156 | selectorBuilder.matchLambda((short) la.toInt()); |
| 157 | + | ||
| 155 | } | 158 | } |
| 156 | 159 | ||
| 157 | // build the last T port rule | 160 | // build the last T port rule | ... | ... |
| ... | @@ -148,7 +148,7 @@ public class FlowRuleManagerTest { | ... | @@ -148,7 +148,7 @@ public class FlowRuleManagerTest { |
| 148 | int i = 0; | 148 | int i = 0; |
| 149 | System.err.println("events :" + listener.events); | 149 | System.err.println("events :" + listener.events); |
| 150 | for (FlowRuleEvent e : listener.events) { | 150 | for (FlowRuleEvent e : listener.events) { |
| 151 | - assertTrue("unexpected event", e.type().equals(events[i])); | 151 | + assertEquals("unexpected event", events[i], e.type()); |
| 152 | i++; | 152 | i++; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| ... | @@ -178,15 +178,13 @@ public class FlowRuleManagerTest { | ... | @@ -178,15 +178,13 @@ public class FlowRuleManagerTest { |
| 178 | RULE_ADDED, RULE_ADDED); | 178 | RULE_ADDED, RULE_ADDED); |
| 179 | 179 | ||
| 180 | addFlowRule(1); | 180 | addFlowRule(1); |
| 181 | + System.err.println("events :" + listener.events); | ||
| 181 | assertEquals("should still be 2 rules", 2, flowCount()); | 182 | assertEquals("should still be 2 rules", 2, flowCount()); |
| 182 | 183 | ||
| 183 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1)); | 184 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1)); |
| 184 | validateEvents(RULE_UPDATED); | 185 | validateEvents(RULE_UPDATED); |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | - | ||
| 188 | - // TODO: If preserving iteration order is a requirement, redo FlowRuleStore. | ||
| 189 | - //backing store is sensitive to the order of additions/removals | ||
| 190 | private boolean validateState(Map<FlowRule, FlowEntryState> expected) { | 188 | private boolean validateState(Map<FlowRule, FlowEntryState> expected) { |
| 191 | Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); | 189 | Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); |
| 192 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); | 190 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); |
| ... | @@ -539,17 +537,17 @@ public class FlowRuleManagerTest { | ... | @@ -539,17 +537,17 @@ public class FlowRuleManagerTest { |
| 539 | 537 | ||
| 540 | @Override | 538 | @Override |
| 541 | public boolean cancel(boolean mayInterruptIfRunning) { | 539 | public boolean cancel(boolean mayInterruptIfRunning) { |
| 542 | - return true; | 540 | + return false; |
| 543 | } | 541 | } |
| 544 | 542 | ||
| 545 | @Override | 543 | @Override |
| 546 | public boolean isCancelled() { | 544 | public boolean isCancelled() { |
| 547 | - return true; | 545 | + return false; |
| 548 | } | 546 | } |
| 549 | 547 | ||
| 550 | @Override | 548 | @Override |
| 551 | public boolean isDone() { | 549 | public boolean isDone() { |
| 552 | - return false; | 550 | + return true; |
| 553 | } | 551 | } |
| 554 | 552 | ||
| 555 | @Override | 553 | @Override |
| ... | @@ -562,12 +560,14 @@ public class FlowRuleManagerTest { | ... | @@ -562,12 +560,14 @@ public class FlowRuleManagerTest { |
| 562 | public CompletedBatchOperation get(long timeout, TimeUnit unit) | 560 | public CompletedBatchOperation get(long timeout, TimeUnit unit) |
| 563 | throws InterruptedException, | 561 | throws InterruptedException, |
| 564 | ExecutionException, TimeoutException { | 562 | ExecutionException, TimeoutException { |
| 565 | - return null; | 563 | + return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()); |
| 566 | } | 564 | } |
| 567 | 565 | ||
| 568 | @Override | 566 | @Override |
| 569 | public void addListener(Runnable task, Executor executor) { | 567 | public void addListener(Runnable task, Executor executor) { |
| 570 | - // TODO: add stuff. | 568 | + if (isDone()) { |
| 569 | + executor.execute(task); | ||
| 570 | + } | ||
| 571 | } | 571 | } |
| 572 | } | 572 | } |
| 573 | 573 | ... | ... |
| ... | @@ -447,7 +447,13 @@ implements MastershipStore { | ... | @@ -447,7 +447,13 @@ implements MastershipStore { |
| 447 | RoleValue oldValue = event.getOldValue(); | 447 | RoleValue oldValue = event.getOldValue(); |
| 448 | RoleValue newValue = event.getValue(); | 448 | RoleValue newValue = event.getValue(); |
| 449 | 449 | ||
| 450 | - if (Objects.equal(oldValue.get(MASTER), newValue.get(MASTER))) { | 450 | + NodeId oldMaster = null; |
| 451 | + if (oldValue != null) { | ||
| 452 | + oldMaster = oldValue.get(MASTER); | ||
| 453 | + } | ||
| 454 | + NodeId newMaster = newValue.get(MASTER); | ||
| 455 | + | ||
| 456 | + if (Objects.equal(oldMaster, newMaster)) { | ||
| 451 | notifyDelegate(new MastershipEvent( | 457 | notifyDelegate(new MastershipEvent( |
| 452 | MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); | 458 | MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); |
| 453 | } else { | 459 | } else { | ... | ... |
| ... | @@ -16,8 +16,12 @@ | ... | @@ -16,8 +16,12 @@ |
| 16 | package org.onlab.onos.store.trivial.impl; | 16 | package org.onlab.onos.store.trivial.impl; |
| 17 | 17 | ||
| 18 | import com.google.common.base.Function; | 18 | import com.google.common.base.Function; |
| 19 | +import com.google.common.cache.Cache; | ||
| 20 | +import com.google.common.cache.CacheBuilder; | ||
| 19 | import com.google.common.collect.FluentIterable; | 21 | import com.google.common.collect.FluentIterable; |
| 20 | import com.google.common.util.concurrent.Futures; | 22 | import com.google.common.util.concurrent.Futures; |
| 23 | +import com.google.common.util.concurrent.SettableFuture; | ||
| 24 | + | ||
| 21 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
| 22 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
| 23 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore; | ... | @@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore; |
| 43 | import org.onlab.util.NewConcurrentHashMap; | 47 | import org.onlab.util.NewConcurrentHashMap; |
| 44 | import org.slf4j.Logger; | 48 | import org.slf4j.Logger; |
| 45 | 49 | ||
| 46 | -import java.util.Arrays; | 50 | +import java.util.ArrayList; |
| 47 | import java.util.Collections; | 51 | import java.util.Collections; |
| 48 | import java.util.List; | 52 | import java.util.List; |
| 49 | import java.util.concurrent.ConcurrentHashMap; | 53 | import java.util.concurrent.ConcurrentHashMap; |
| 50 | import java.util.concurrent.ConcurrentMap; | 54 | import java.util.concurrent.ConcurrentMap; |
| 51 | import java.util.concurrent.CopyOnWriteArrayList; | 55 | import java.util.concurrent.CopyOnWriteArrayList; |
| 52 | import java.util.concurrent.Future; | 56 | import java.util.concurrent.Future; |
| 57 | +import java.util.concurrent.TimeUnit; | ||
| 58 | +import java.util.concurrent.atomic.AtomicInteger; | ||
| 53 | 59 | ||
| 54 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | 60 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; |
| 55 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 61 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
| ... | @@ -72,6 +78,18 @@ public class SimpleFlowRuleStore | ... | @@ -72,6 +78,18 @@ public class SimpleFlowRuleStore |
| 72 | private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> | 78 | private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> |
| 73 | flowEntries = new ConcurrentHashMap<>(); | 79 | flowEntries = new ConcurrentHashMap<>(); |
| 74 | 80 | ||
| 81 | + private final AtomicInteger localBatchIdGen = new AtomicInteger(); | ||
| 82 | + | ||
| 83 | + // TODO: make this configurable | ||
| 84 | + private int pendingFutureTimeoutMinutes = 5; | ||
| 85 | + | ||
| 86 | + private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures = | ||
| 87 | + CacheBuilder.newBuilder() | ||
| 88 | + .expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES) | ||
| 89 | + // TODO Explicitly fail the future if expired? | ||
| 90 | + //.removalListener(listener) | ||
| 91 | + .build(); | ||
| 92 | + | ||
| 75 | @Activate | 93 | @Activate |
| 76 | public void activate() { | 94 | public void activate() { |
| 77 | log.info("Started"); | 95 | log.info("Started"); |
| ... | @@ -173,10 +191,6 @@ public class SimpleFlowRuleStore | ... | @@ -173,10 +191,6 @@ public class SimpleFlowRuleStore |
| 173 | } | 191 | } |
| 174 | // new flow rule added | 192 | // new flow rule added |
| 175 | existing.add(f); | 193 | existing.add(f); |
| 176 | - notifyDelegate(FlowRuleBatchEvent.requested( | ||
| 177 | - new FlowRuleBatchRequest(1, /* FIXME generate something */ | ||
| 178 | - Arrays.<FlowEntry>asList(f), | ||
| 179 | - Collections.<FlowEntry>emptyList()))); | ||
| 180 | } | 194 | } |
| 181 | } | 195 | } |
| 182 | 196 | ||
| ... | @@ -190,11 +204,6 @@ public class SimpleFlowRuleStore | ... | @@ -190,11 +204,6 @@ public class SimpleFlowRuleStore |
| 190 | if (entry.equals(rule)) { | 204 | if (entry.equals(rule)) { |
| 191 | synchronized (entry) { | 205 | synchronized (entry) { |
| 192 | entry.setState(FlowEntryState.PENDING_REMOVE); | 206 | entry.setState(FlowEntryState.PENDING_REMOVE); |
| 193 | - // TODO: Should we notify only if it's "remote" event? | ||
| 194 | - notifyDelegate(FlowRuleBatchEvent.requested( | ||
| 195 | - new FlowRuleBatchRequest(1, /* FIXME generate something */ | ||
| 196 | - Collections.<FlowEntry>emptyList(), | ||
| 197 | - Arrays.<FlowEntry>asList(entry)))); | ||
| 198 | } | 207 | } |
| 199 | } | 208 | } |
| 200 | } | 209 | } |
| ... | @@ -251,20 +260,47 @@ public class SimpleFlowRuleStore | ... | @@ -251,20 +260,47 @@ public class SimpleFlowRuleStore |
| 251 | @Override | 260 | @Override |
| 252 | public Future<CompletedBatchOperation> storeBatch( | 261 | public Future<CompletedBatchOperation> storeBatch( |
| 253 | FlowRuleBatchOperation batchOperation) { | 262 | FlowRuleBatchOperation batchOperation) { |
| 263 | + List<FlowRule> toAdd = new ArrayList<>(); | ||
| 264 | + List<FlowRule> toRemove = new ArrayList<>(); | ||
| 254 | for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { | 265 | for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { |
| 266 | + final FlowRule flowRule = entry.getTarget(); | ||
| 255 | if (entry.getOperator().equals(FlowRuleOperation.ADD)) { | 267 | if (entry.getOperator().equals(FlowRuleOperation.ADD)) { |
| 256 | - storeFlowRule(entry.getTarget()); | 268 | + if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { |
| 269 | + storeFlowRule(flowRule); | ||
| 270 | + toAdd.add(flowRule); | ||
| 271 | + } | ||
| 257 | } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) { | 272 | } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) { |
| 258 | - deleteFlowRule(entry.getTarget()); | 273 | + if (getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { |
| 274 | + deleteFlowRule(flowRule); | ||
| 275 | + toRemove.add(flowRule); | ||
| 276 | + } | ||
| 259 | } else { | 277 | } else { |
| 260 | throw new UnsupportedOperationException("Unsupported operation type"); | 278 | throw new UnsupportedOperationException("Unsupported operation type"); |
| 261 | } | 279 | } |
| 262 | } | 280 | } |
| 263 | - return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); | 281 | + |
| 282 | + if (toAdd.isEmpty() && toRemove.isEmpty()) { | ||
| 283 | + return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowRule>emptySet())); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + SettableFuture<CompletedBatchOperation> r = SettableFuture.create(); | ||
| 287 | + final int batchId = localBatchIdGen.incrementAndGet(); | ||
| 288 | + | ||
| 289 | + pendingFutures.put(batchId, r); | ||
| 290 | + notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove))); | ||
| 291 | + | ||
| 292 | + return r; | ||
| 264 | } | 293 | } |
| 265 | 294 | ||
| 266 | @Override | 295 | @Override |
| 267 | public void batchOperationComplete(FlowRuleBatchEvent event) { | 296 | public void batchOperationComplete(FlowRuleBatchEvent event) { |
| 297 | + final Integer batchId = event.subject().batchId(); | ||
| 298 | + SettableFuture<CompletedBatchOperation> future | ||
| 299 | + = pendingFutures.getIfPresent(batchId); | ||
| 300 | + if (future != null) { | ||
| 301 | + future.set(event.result()); | ||
| 302 | + pendingFutures.invalidate(batchId); | ||
| 303 | + } | ||
| 268 | notifyDelegate(event); | 304 | notifyDelegate(event); |
| 269 | } | 305 | } |
| 270 | } | 306 | } | ... | ... |
| ... | @@ -352,13 +352,6 @@ | ... | @@ -352,13 +352,6 @@ |
| 352 | </dependencies> | 352 | </dependencies> |
| 353 | 353 | ||
| 354 | <build> | 354 | <build> |
| 355 | - <extensions> | ||
| 356 | - <extension> | ||
| 357 | - <groupId>kr.motd.maven</groupId> | ||
| 358 | - <artifactId>os-maven-plugin</artifactId> | ||
| 359 | - <version>1.2.3.Final</version> | ||
| 360 | - </extension> | ||
| 361 | - </extensions> | ||
| 362 | <pluginManagement> | 355 | <pluginManagement> |
| 363 | <plugins> | 356 | <plugins> |
| 364 | <plugin> | 357 | <plugin> | ... | ... |
| ... | @@ -289,7 +289,10 @@ public class FlowEntryBuilder { | ... | @@ -289,7 +289,10 @@ public class FlowEntryBuilder { |
| 289 | case OCH_SIGID: | 289 | case OCH_SIGID: |
| 290 | builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber()); | 290 | builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber()); |
| 291 | break; | 291 | break; |
| 292 | - case OCH_SIGTYPE_BASIC: | 292 | + case OCH_SIGTYPE: |
| 293 | + builder.matchOpticalSignalType(match.get(MatchField | ||
| 294 | + .OCH_SIGTYPE).getValue()); | ||
| 295 | + break; | ||
| 293 | case ARP_OP: | 296 | case ARP_OP: |
| 294 | case ARP_SHA: | 297 | case ARP_SHA: |
| 295 | case ARP_SPA: | 298 | case ARP_SPA: | ... | ... |
| ... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 19 | 19 | ||
| 20 | import org.onlab.onos.net.flow.FlowRule; | 20 | import org.onlab.onos.net.flow.FlowRule; |
| 21 | import org.onlab.onos.net.flow.TrafficSelector; | 21 | import org.onlab.onos.net.flow.TrafficSelector; |
| 22 | +import org.onlab.onos.net.flow.criteria.Criteria; | ||
| 22 | import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; | 23 | import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; |
| 23 | import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; | 24 | import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; |
| 24 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; | 25 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; |
| ... | @@ -46,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked; | ... | @@ -46,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked; |
| 46 | import org.projectfloodlight.openflow.types.OFPort; | 47 | import org.projectfloodlight.openflow.types.OFPort; |
| 47 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; | 48 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; |
| 48 | import org.projectfloodlight.openflow.types.TransportPort; | 49 | import org.projectfloodlight.openflow.types.TransportPort; |
| 50 | +import org.projectfloodlight.openflow.types.U8; | ||
| 49 | import org.projectfloodlight.openflow.types.VlanPcp; | 51 | import org.projectfloodlight.openflow.types.VlanPcp; |
| 50 | import org.projectfloodlight.openflow.types.VlanVid; | 52 | import org.projectfloodlight.openflow.types.VlanVid; |
| 51 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
| ... | @@ -197,6 +199,12 @@ public abstract class FlowModBuilder { | ... | @@ -197,6 +199,12 @@ public abstract class FlowModBuilder { |
| 197 | mBuilder.setExact(MatchField.OCH_SIGID, | 199 | mBuilder.setExact(MatchField.OCH_SIGID, |
| 198 | new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1)); | 200 | new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1)); |
| 199 | break; | 201 | break; |
| 202 | + case OCH_SIGTYPE: | ||
| 203 | + Criteria.OpticalSignalTypeCriterion sc = | ||
| 204 | + (Criteria.OpticalSignalTypeCriterion) c; | ||
| 205 | + mBuilder.setExact(MatchField.OCH_SIGTYPE, | ||
| 206 | + U8.of(sc.signalType())); | ||
| 207 | + break; | ||
| 200 | case ARP_OP: | 208 | case ARP_OP: |
| 201 | case ARP_SHA: | 209 | case ARP_SHA: |
| 202 | case ARP_SPA: | 210 | case ARP_SPA: | ... | ... |
| ... | @@ -30,7 +30,6 @@ import static com.google.common.base.Preconditions.checkState; | ... | @@ -30,7 +30,6 @@ import static com.google.common.base.Preconditions.checkState; |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * A class representing an IP address. | 32 | * A class representing an IP address. |
| 33 | - * TODO: Add support for IPv6 as well. | ||
| 34 | */ | 33 | */ |
| 35 | public final class IpAddress implements Comparable<IpAddress> { | 34 | public final class IpAddress implements Comparable<IpAddress> { |
| 36 | // IP Versions | 35 | // IP Versions | ... | ... |
| ... | @@ -17,8 +17,6 @@ package org.onlab.packet; | ... | @@ -17,8 +17,6 @@ package org.onlab.packet; |
| 17 | 17 | ||
| 18 | import java.util.Objects; | 18 | import java.util.Objects; |
| 19 | 19 | ||
| 20 | -// TODO: Add support for IPv6 as well. | ||
| 21 | - | ||
| 22 | /** | 20 | /** |
| 23 | * A class representing an IP prefix. A prefix consists of an IP address and | 21 | * A class representing an IP prefix. A prefix consists of an IP address and |
| 24 | * a subnet mask. | 22 | * a subnet mask. |
| ... | @@ -40,26 +38,39 @@ public final class IpPrefix { | ... | @@ -40,26 +38,39 @@ public final class IpPrefix { |
| 40 | * | 38 | * |
| 41 | * @param address the IP address | 39 | * @param address the IP address |
| 42 | * @param prefixLength the prefix length | 40 | * @param prefixLength the prefix length |
| 41 | + * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 43 | */ | 42 | */ |
| 44 | private IpPrefix(IpAddress address, int prefixLength) { | 43 | private IpPrefix(IpAddress address, int prefixLength) { |
| 45 | - checkPrefixLength(prefixLength); | 44 | + checkPrefixLength(address.version(), prefixLength); |
| 46 | this.address = IpAddress.makeMaskedAddress(address, prefixLength); | 45 | this.address = IpAddress.makeMaskedAddress(address, prefixLength); |
| 47 | this.prefixLength = (short) prefixLength; | 46 | this.prefixLength = (short) prefixLength; |
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | /** | 49 | /** |
| 51 | - * Checks whether the prefix length is valid. | 50 | + * Returns the IP version of the prefix. |
| 52 | * | 51 | * |
| 53 | - * @param prefixLength the prefix length value to check | 52 | + * @return the IP version of the prefix |
| 54 | - * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 55 | */ | 53 | */ |
| 56 | - private static void checkPrefixLength(int prefixLength) { | 54 | + public IpAddress.Version version() { |
| 57 | - if ((prefixLength < 0) || (prefixLength > MAX_INET_MASK_LENGTH)) { | 55 | + return address.version(); |
| 58 | - String msg = "Invalid prefix length " + prefixLength + ". " + | 56 | + } |
| 59 | - "The value must be in the interval [0, " + | 57 | + |
| 60 | - MAX_INET_MASK_LENGTH + "]"; | 58 | + /** |
| 61 | - throw new IllegalArgumentException(msg); | 59 | + * Returns the IP address value of the prefix. |
| 60 | + * | ||
| 61 | + * @return the IP address value of the prefix | ||
| 62 | + */ | ||
| 63 | + public IpAddress address() { | ||
| 64 | + return address; | ||
| 62 | } | 65 | } |
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Returns the IP address prefix length. | ||
| 69 | + * | ||
| 70 | + * @return the IP address prefix length | ||
| 71 | + */ | ||
| 72 | + public int prefixLength() { | ||
| 73 | + return prefixLength; | ||
| 63 | } | 74 | } |
| 64 | 75 | ||
| 65 | /** | 76 | /** |
| ... | @@ -68,6 +79,7 @@ public final class IpPrefix { | ... | @@ -68,6 +79,7 @@ public final class IpPrefix { |
| 68 | * @param address an integer representing the IPv4 address | 79 | * @param address an integer representing the IPv4 address |
| 69 | * @param prefixLength the prefix length | 80 | * @param prefixLength the prefix length |
| 70 | * @return an IP prefix | 81 | * @return an IP prefix |
| 82 | + * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 71 | */ | 83 | */ |
| 72 | public static IpPrefix valueOf(int address, int prefixLength) { | 84 | public static IpPrefix valueOf(int address, int prefixLength) { |
| 73 | return new IpPrefix(IpAddress.valueOf(address), prefixLength); | 85 | return new IpPrefix(IpAddress.valueOf(address), prefixLength); |
| ... | @@ -80,11 +92,11 @@ public final class IpPrefix { | ... | @@ -80,11 +92,11 @@ public final class IpPrefix { |
| 80 | * @param address the IP address value stored in network byte order | 92 | * @param address the IP address value stored in network byte order |
| 81 | * @param prefixLength the prefix length | 93 | * @param prefixLength the prefix length |
| 82 | * @return an IP prefix | 94 | * @return an IP prefix |
| 95 | + * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 83 | */ | 96 | */ |
| 84 | public static IpPrefix valueOf(IpAddress.Version version, byte[] address, | 97 | public static IpPrefix valueOf(IpAddress.Version version, byte[] address, |
| 85 | int prefixLength) { | 98 | int prefixLength) { |
| 86 | - return new IpPrefix(IpAddress.valueOf(version, address), | 99 | + return new IpPrefix(IpAddress.valueOf(version, address), prefixLength); |
| 87 | - prefixLength); | ||
| 88 | } | 100 | } |
| 89 | 101 | ||
| 90 | /** | 102 | /** |
| ... | @@ -93,6 +105,7 @@ public final class IpPrefix { | ... | @@ -93,6 +105,7 @@ public final class IpPrefix { |
| 93 | * @param address the IP address | 105 | * @param address the IP address |
| 94 | * @param prefixLength the prefix length | 106 | * @param prefixLength the prefix length |
| 95 | * @return an IP prefix | 107 | * @return an IP prefix |
| 108 | + * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 96 | */ | 109 | */ |
| 97 | public static IpPrefix valueOf(IpAddress address, int prefixLength) { | 110 | public static IpPrefix valueOf(IpAddress address, int prefixLength) { |
| 98 | return new IpPrefix(address, prefixLength); | 111 | return new IpPrefix(address, prefixLength); |
| ... | @@ -104,6 +117,7 @@ public final class IpPrefix { | ... | @@ -104,6 +117,7 @@ public final class IpPrefix { |
| 104 | * | 117 | * |
| 105 | * @param address an IP prefix in string form, e.g. "10.1.0.0/16" | 118 | * @param address an IP prefix in string form, e.g. "10.1.0.0/16" |
| 106 | * @return an IP prefix | 119 | * @return an IP prefix |
| 120 | + * @throws IllegalArgumentException if the arguments are invalid | ||
| 107 | */ | 121 | */ |
| 108 | public static IpPrefix valueOf(String address) { | 122 | public static IpPrefix valueOf(String address) { |
| 109 | final String[] parts = address.split("/"); | 123 | final String[] parts = address.split("/"); |
| ... | @@ -119,33 +133,6 @@ public final class IpPrefix { | ... | @@ -119,33 +133,6 @@ public final class IpPrefix { |
| 119 | } | 133 | } |
| 120 | 134 | ||
| 121 | /** | 135 | /** |
| 122 | - * Returns the IP version of the prefix. | ||
| 123 | - * | ||
| 124 | - * @return the IP version of the prefix | ||
| 125 | - */ | ||
| 126 | - public IpAddress.Version version() { | ||
| 127 | - return address.version(); | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - /** | ||
| 131 | - * Returns the IP address value of the prefix. | ||
| 132 | - * | ||
| 133 | - * @return the IP address value of the prefix | ||
| 134 | - */ | ||
| 135 | - public IpAddress address() { | ||
| 136 | - return address; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - /** | ||
| 140 | - * Returns the IP address prefix length. | ||
| 141 | - * | ||
| 142 | - * @return the IP address prefix length | ||
| 143 | - */ | ||
| 144 | - public int prefixLength() { | ||
| 145 | - return prefixLength; | ||
| 146 | - } | ||
| 147 | - | ||
| 148 | - /** | ||
| 149 | * Determines whether a given IP prefix is contained within this prefix. | 136 | * Determines whether a given IP prefix is contained within this prefix. |
| 150 | * | 137 | * |
| 151 | * @param other the IP prefix to test | 138 | * @param other the IP prefix to test |
| ... | @@ -217,4 +204,35 @@ public final class IpPrefix { | ... | @@ -217,4 +204,35 @@ public final class IpPrefix { |
| 217 | builder.append(String.format("%d", prefixLength)); | 204 | builder.append(String.format("%d", prefixLength)); |
| 218 | return builder.toString(); | 205 | return builder.toString(); |
| 219 | } | 206 | } |
| 207 | + | ||
| 208 | + /** | ||
| 209 | + * Checks whether the prefix length is valid. | ||
| 210 | + * | ||
| 211 | + * @param version the IP address version | ||
| 212 | + * @param prefixLength the prefix length value to check | ||
| 213 | + * @throws IllegalArgumentException if the prefix length value is invalid | ||
| 214 | + */ | ||
| 215 | + private static void checkPrefixLength(IpAddress.Version version, | ||
| 216 | + int prefixLength) { | ||
| 217 | + int maxPrefixLen = 0; | ||
| 218 | + | ||
| 219 | + switch (version) { | ||
| 220 | + case INET: | ||
| 221 | + maxPrefixLen = MAX_INET_MASK_LENGTH; | ||
| 222 | + break; | ||
| 223 | + case INET6: | ||
| 224 | + maxPrefixLen = MAX_INET6_MASK_LENGTH; | ||
| 225 | + break; | ||
| 226 | + default: | ||
| 227 | + String msg = "Invalid IP version " + version; | ||
| 228 | + throw new IllegalArgumentException(msg); | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + if ((prefixLength < 0) || (prefixLength > maxPrefixLen)) { | ||
| 232 | + String msg = "Invalid prefix length " + prefixLength + ". " + | ||
| 233 | + "The value must be in the interval [0, " + | ||
| 234 | + maxPrefixLen + "]"; | ||
| 235 | + throw new IllegalArgumentException(msg); | ||
| 236 | + } | ||
| 237 | + } | ||
| 220 | } | 238 | } | ... | ... |
| ... | @@ -135,7 +135,7 @@ public class IpAddressTest { | ... | @@ -135,7 +135,7 @@ public class IpAddressTest { |
| 135 | * Tests returning an IPv4 address asn an integer. | 135 | * Tests returning an IPv4 address asn an integer. |
| 136 | */ | 136 | */ |
| 137 | @Test | 137 | @Test |
| 138 | - public void testToint() { | 138 | + public void testToInt() { |
| 139 | IpAddress ipAddress; | 139 | IpAddress ipAddress; |
| 140 | 140 | ||
| 141 | ipAddress = IpAddress.valueOf("1.2.3.4"); | 141 | ipAddress = IpAddress.valueOf("1.2.3.4"); |
| ... | @@ -149,10 +149,10 @@ public class IpAddressTest { | ... | @@ -149,10 +149,10 @@ public class IpAddressTest { |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | /** | 151 | /** |
| 152 | - * Tests valueOf() converter for an integer value. | 152 | + * Tests valueOf() converter for IPv4 integer value. |
| 153 | */ | 153 | */ |
| 154 | @Test | 154 | @Test |
| 155 | - public void testValueOfForInteger() { | 155 | + public void testValueOfForIntegerIPv4() { |
| 156 | IpAddress ipAddress; | 156 | IpAddress ipAddress; |
| 157 | 157 | ||
| 158 | ipAddress = IpAddress.valueOf(0x01020304); | 158 | ipAddress = IpAddress.valueOf(0x01020304); | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment