Tests for FlowRuleStore plus bugfixes
Change-Id: Ib5b0bd9d41fbbcac1cf09684e70446326887caf7
Showing
6 changed files
with
362 additions
and
13 deletions
| 1 | package org.onlab.onos.net.flow; | 1 | package org.onlab.onos.net.flow; |
| 2 | 2 | ||
| 3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
| 4 | + | ||
| 3 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
| 4 | 6 | ||
| 5 | public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | 7 | public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { |
| ... | @@ -63,7 +65,9 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | ... | @@ -63,7 +65,9 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { |
| 63 | public int hashCode() { | 65 | public int hashCode() { |
| 64 | final int prime = 31; | 66 | final int prime = 31; |
| 65 | int result = prime * this.deviceId().hashCode(); | 67 | int result = prime * this.deviceId().hashCode(); |
| 66 | - result = prime * result + Long.valueOf(this.created).hashCode(); | 68 | + result = prime * result + this.priority; |
| 69 | + result = prime * result + this.selector().hashCode(); | ||
| 70 | + result = prime * result + this.treatment().hashCode(); | ||
| 67 | return result; | 71 | return result; |
| 68 | } | 72 | } |
| 69 | 73 | ||
| ... | @@ -77,7 +81,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | ... | @@ -77,7 +81,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { |
| 77 | public boolean equals(Object obj) { | 81 | public boolean equals(Object obj) { |
| 78 | if (obj instanceof DefaultFlowEntry) { | 82 | if (obj instanceof DefaultFlowEntry) { |
| 79 | DefaultFlowEntry that = (DefaultFlowEntry) obj; | 83 | DefaultFlowEntry that = (DefaultFlowEntry) obj; |
| 80 | - if (!this.id.equals(that.id())) { | 84 | + if (!this.deviceId().equals(that.deviceId())) { |
| 85 | + return false; | ||
| 86 | + } | ||
| 87 | + if (!(this.priority == that.priority)) { | ||
| 81 | return false; | 88 | return false; |
| 82 | } | 89 | } |
| 83 | return super.equals(obj); | 90 | return super.equals(obj); |
| ... | @@ -85,4 +92,15 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | ... | @@ -85,4 +92,15 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { |
| 85 | return false; | 92 | return false; |
| 86 | } | 93 | } |
| 87 | 94 | ||
| 95 | + @Override | ||
| 96 | + public String toString() { | ||
| 97 | + return toStringHelper(this) | ||
| 98 | + .add("id", id) | ||
| 99 | + .add("deviceId", deviceId()) | ||
| 100 | + .add("priority", priority) | ||
| 101 | + .add("selector", selector()) | ||
| 102 | + .add("treatment", treatment()) | ||
| 103 | + .toString(); | ||
| 104 | + } | ||
| 105 | + | ||
| 88 | } | 106 | } | ... | ... |
| ... | @@ -17,6 +17,7 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -17,6 +17,7 @@ public class DefaultFlowRule implements FlowRule { |
| 17 | 17 | ||
| 18 | @Override | 18 | @Override |
| 19 | public int priority() { | 19 | public int priority() { |
| 20 | + // is this supposed to be 0? | ||
| 20 | return 0; | 21 | return 0; |
| 21 | } | 22 | } |
| 22 | 23 | ||
| ... | @@ -63,8 +64,9 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -63,8 +64,9 @@ public class DefaultFlowRule implements FlowRule { |
| 63 | if (!this.selector().equals(that.selector())) { | 64 | if (!this.selector().equals(that.selector())) { |
| 64 | return false; | 65 | return false; |
| 65 | } | 66 | } |
| 67 | + return true; | ||
| 66 | } | 68 | } |
| 67 | - return true; | 69 | + return false; |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | 72 | ... | ... |
| ... | @@ -45,10 +45,10 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -45,10 +45,10 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
| 45 | private final SimpleFlowRuleStore store = new SimpleFlowRuleStore(); | 45 | private final SimpleFlowRuleStore store = new SimpleFlowRuleStore(); |
| 46 | 46 | ||
| 47 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 47 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 48 | - private EventDeliveryService eventDispatcher; | 48 | + protected EventDeliveryService eventDispatcher; |
| 49 | 49 | ||
| 50 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 50 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 51 | - private DeviceService deviceService; | 51 | + protected DeviceService deviceService; |
| 52 | 52 | ||
| 53 | @Activate | 53 | @Activate |
| 54 | public void activate() { | 54 | public void activate() { | ... | ... |
| ... | @@ -53,17 +53,20 @@ public class SimpleFlowRuleStore { | ... | @@ -53,17 +53,20 @@ public class SimpleFlowRuleStore { |
| 53 | FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) { | 53 | FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) { |
| 54 | DeviceId did = rule.deviceId(); | 54 | DeviceId did = rule.deviceId(); |
| 55 | 55 | ||
| 56 | + FlowEntry entry = new DefaultFlowEntry( | ||
| 57 | + did, | ||
| 58 | + rule.selector(), | ||
| 59 | + rule.treatment(), | ||
| 60 | + rule.priority()); | ||
| 61 | + | ||
| 56 | // check if this new rule is an update to an existing entry | 62 | // check if this new rule is an update to an existing entry |
| 57 | for (FlowEntry fe : flowEntries.get(did)) { | 63 | for (FlowEntry fe : flowEntries.get(did)) { |
| 58 | - if (rule.equals(fe)) { | 64 | + if (entry.equals(fe)) { |
| 59 | // TODO update the stats on this flowEntry? | 65 | // TODO update the stats on this flowEntry? |
| 60 | return null; | 66 | return null; |
| 61 | } | 67 | } |
| 62 | } | 68 | } |
| 63 | - | 69 | + flowEntries.put(did, entry); |
| 64 | - FlowEntry newfe = new DefaultFlowEntry(did, | ||
| 65 | - rule.selector(), rule.treatment(), rule.priority()); | ||
| 66 | - flowEntries.put(did, newfe); | ||
| 67 | return new FlowRuleEvent(RULE_ADDED, rule); | 70 | return new FlowRuleEvent(RULE_ADDED, rule); |
| 68 | } | 71 | } |
| 69 | 72 | ||
| ... | @@ -73,8 +76,11 @@ public class SimpleFlowRuleStore { | ... | @@ -73,8 +76,11 @@ public class SimpleFlowRuleStore { |
| 73 | * @return flow_removed event, or null if nothing removed | 76 | * @return flow_removed event, or null if nothing removed |
| 74 | */ | 77 | */ |
| 75 | FlowRuleEvent removeFlowRule(FlowRule rule) { | 78 | FlowRuleEvent removeFlowRule(FlowRule rule) { |
| 79 | + | ||
| 80 | + FlowEntry rem = new DefaultFlowEntry(rule.deviceId(), | ||
| 81 | + rule.selector(), rule.treatment(), rule.priority()); | ||
| 76 | synchronized (this) { | 82 | synchronized (this) { |
| 77 | - if (flowEntries.remove(rule.deviceId(), rule)) { | 83 | + if (flowEntries.remove(rem.deviceId(), rem)) { |
| 78 | return new FlowRuleEvent(RULE_REMOVED, rule); | 84 | return new FlowRuleEvent(RULE_REMOVED, rule); |
| 79 | } else { | 85 | } else { |
| 80 | return null; | 86 | return null; | ... | ... |
core/trivial/src/test/java/org/onlab/onos/net/trivial/flow/impl/SimpleFlowRuleManagerTest.java
0 → 100644
| 1 | +package org.onlab.onos.net.trivial.flow.impl; | ||
| 2 | + | ||
| 3 | +import static org.junit.Assert.assertEquals; | ||
| 4 | +import static org.junit.Assert.assertFalse; | ||
| 5 | +import static org.junit.Assert.assertNotNull; | ||
| 6 | +import static org.junit.Assert.assertTrue; | ||
| 7 | + | ||
| 8 | +import java.util.ArrayList; | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +import org.junit.After; | ||
| 12 | +import org.junit.Before; | ||
| 13 | +import org.junit.Test; | ||
| 14 | +import org.onlab.onos.event.impl.TestEventDispatcher; | ||
| 15 | +import org.onlab.onos.net.DefaultDevice; | ||
| 16 | +import org.onlab.onos.net.Device; | ||
| 17 | +import org.onlab.onos.net.Device.Type; | ||
| 18 | +import org.onlab.onos.net.DeviceId; | ||
| 19 | +import org.onlab.onos.net.MastershipRole; | ||
| 20 | +import org.onlab.onos.net.Port; | ||
| 21 | +import org.onlab.onos.net.PortNumber; | ||
| 22 | +import org.onlab.onos.net.device.DeviceListener; | ||
| 23 | +import org.onlab.onos.net.device.DeviceService; | ||
| 24 | +import org.onlab.onos.net.flow.DefaultFlowEntry; | ||
| 25 | +import org.onlab.onos.net.flow.DefaultFlowRule; | ||
| 26 | +import org.onlab.onos.net.flow.FlowEntry; | ||
| 27 | +import org.onlab.onos.net.flow.FlowRule; | ||
| 28 | +import org.onlab.onos.net.flow.FlowRuleEvent; | ||
| 29 | +import org.onlab.onos.net.flow.FlowRuleListener; | ||
| 30 | +import org.onlab.onos.net.flow.FlowRuleProvider; | ||
| 31 | +import org.onlab.onos.net.flow.FlowRuleProviderRegistry; | ||
| 32 | +import org.onlab.onos.net.flow.FlowRuleProviderService; | ||
| 33 | +import org.onlab.onos.net.flow.FlowRuleService; | ||
| 34 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
| 35 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
| 36 | +import org.onlab.onos.net.flow.criteria.Criterion; | ||
| 37 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
| 38 | +import org.onlab.onos.net.provider.AbstractProvider; | ||
| 39 | +import org.onlab.onos.net.provider.ProviderId; | ||
| 40 | + | ||
| 41 | +import com.google.common.collect.Lists; | ||
| 42 | +import com.google.common.collect.Sets; | ||
| 43 | + | ||
| 44 | +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*; | ||
| 45 | + | ||
| 46 | +/** | ||
| 47 | + * Test codifying the flow rule service & flow rule provider service contracts. | ||
| 48 | + */ | ||
| 49 | +public class SimpleFlowRuleManagerTest { | ||
| 50 | + | ||
| 51 | + private static final ProviderId PID = new ProviderId("foo"); | ||
| 52 | + private static final DeviceId DID = DeviceId.deviceId("of:001"); | ||
| 53 | + private static final Device DEV = new DefaultDevice( | ||
| 54 | + PID, DID, Type.SWITCH, "", "", "", ""); | ||
| 55 | + | ||
| 56 | + private SimpleFlowRuleManager mgr; | ||
| 57 | + | ||
| 58 | + protected FlowRuleService service; | ||
| 59 | + protected FlowRuleProviderRegistry registry; | ||
| 60 | + protected FlowRuleProviderService providerSerivce; | ||
| 61 | + protected TestProvider provider; | ||
| 62 | + protected TestListener listener = new TestListener(); | ||
| 63 | + | ||
| 64 | + @Before | ||
| 65 | + public void setUp() { | ||
| 66 | + mgr = new SimpleFlowRuleManager(); | ||
| 67 | + mgr.eventDispatcher = new TestEventDispatcher(); | ||
| 68 | + mgr.deviceService = new TestDeviceService(); | ||
| 69 | + service = mgr; | ||
| 70 | + registry = mgr; | ||
| 71 | + | ||
| 72 | + mgr.activate(); | ||
| 73 | + mgr.addListener(listener); | ||
| 74 | + provider = new TestProvider(PID); | ||
| 75 | + providerSerivce = registry.register(provider); | ||
| 76 | + assertTrue("provider should be registered", | ||
| 77 | + registry.getProviders().contains(provider.id())); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @After | ||
| 81 | + public void tearDown() { | ||
| 82 | + registry.unregister(provider); | ||
| 83 | + assertFalse("provider should not be registered", | ||
| 84 | + registry.getProviders().contains(provider.id())); | ||
| 85 | + service.removeListener(listener); | ||
| 86 | + mgr.deactivate(); | ||
| 87 | + mgr.eventDispatcher = null; | ||
| 88 | + mgr.deviceService = null; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + private FlowRule flowRule(int tsval, int trval) { | ||
| 92 | + TestSelector ts = new TestSelector(tsval); | ||
| 93 | + TestTreatment tr = new TestTreatment(trval); | ||
| 94 | + return new DefaultFlowRule(DID, ts, tr); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + private void addFlowRule(int hval) { | ||
| 98 | + FlowRule rule = flowRule(hval, hval); | ||
| 99 | + providerSerivce.flowAdded(rule); | ||
| 100 | + assertNotNull("rule should be found", service.getFlowEntries(DID)); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + private void validateEvents(FlowRuleEvent.Type ... events) { | ||
| 104 | + if (events == null) { | ||
| 105 | + assertTrue("events generated", listener.events.isEmpty()); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + int i = 0; | ||
| 109 | + for (FlowRuleEvent e : listener.events) { | ||
| 110 | + assertTrue("unexpected event", e.type().equals(events[i])); | ||
| 111 | + i++; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + assertEquals("mispredicted number of events", | ||
| 115 | + events.length, listener.events.size()); | ||
| 116 | + | ||
| 117 | + listener.events.clear(); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + private int flowCount() { | ||
| 121 | + return Sets.newHashSet(service.getFlowEntries(DID)).size(); | ||
| 122 | + } | ||
| 123 | + @Test | ||
| 124 | + public void getFlowEntries() { | ||
| 125 | + assertTrue("store should be empty", | ||
| 126 | + Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); | ||
| 127 | + addFlowRule(1); | ||
| 128 | + addFlowRule(2); | ||
| 129 | + assertEquals("2 rules should exist", 2, flowCount()); | ||
| 130 | + validateEvents(RULE_ADDED, RULE_ADDED); | ||
| 131 | + | ||
| 132 | + addFlowRule(1); | ||
| 133 | + assertEquals("should still be 2 rules", 2, flowCount()); | ||
| 134 | + validateEvents(); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + @Test | ||
| 138 | + public void applyFlowRules() { | ||
| 139 | + TestSelector ts = new TestSelector(1); | ||
| 140 | + FlowRule r1 = flowRule(1, 1); | ||
| 141 | + FlowRule r2 = flowRule(1, 2); | ||
| 142 | + FlowRule r3 = flowRule(1, 3); | ||
| 143 | + | ||
| 144 | + //current FlowRules always return 0. FlowEntries inherit the value | ||
| 145 | + FlowEntry e1 = new DefaultFlowEntry(DID, ts, r1.treatment(), 0); | ||
| 146 | + FlowEntry e2 = new DefaultFlowEntry(DID, ts, r2.treatment(), 0); | ||
| 147 | + FlowEntry e3 = new DefaultFlowEntry(DID, ts, r3.treatment(), 0); | ||
| 148 | + List<FlowEntry> fel = Lists.newArrayList(e1, e2, e3); | ||
| 149 | + | ||
| 150 | + assertTrue("store should be empty", | ||
| 151 | + Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); | ||
| 152 | + List<FlowEntry> ret = mgr.applyFlowRules(r1, r2, r3); | ||
| 153 | + assertEquals("3 rules should exist", 3, flowCount()); | ||
| 154 | + assertTrue("3 entries should result", fel.containsAll(ret)); | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + @Test | ||
| 158 | + public void removeFlowRules() { | ||
| 159 | + addFlowRule(1); | ||
| 160 | + addFlowRule(2); | ||
| 161 | + addFlowRule(3); | ||
| 162 | + assertEquals("3 rules should exist", 3, flowCount()); | ||
| 163 | + validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED); | ||
| 164 | + | ||
| 165 | + FlowRule rem1 = flowRule(1, 1); | ||
| 166 | + FlowRule rem2 = flowRule(2, 2); | ||
| 167 | + mgr.removeFlowRules(rem1, rem2); | ||
| 168 | + //removing from north, so no events generated | ||
| 169 | + validateEvents(); | ||
| 170 | + assertEquals("1 rule should exist", 1, flowCount()); | ||
| 171 | + | ||
| 172 | + mgr.removeFlowRules(rem1); | ||
| 173 | + assertEquals("1 rule should still exist", 1, flowCount()); | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + @Test | ||
| 177 | + public void flowRemoved() { | ||
| 178 | + addFlowRule(1); | ||
| 179 | + addFlowRule(2); | ||
| 180 | + FlowRule rem1 = flowRule(1, 1); | ||
| 181 | + providerSerivce.flowRemoved(rem1); | ||
| 182 | + validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED); | ||
| 183 | + | ||
| 184 | + providerSerivce.flowRemoved(rem1); | ||
| 185 | + validateEvents(); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + private static class TestListener implements FlowRuleListener { | ||
| 189 | + final List<FlowRuleEvent> events = new ArrayList<>(); | ||
| 190 | + | ||
| 191 | + @Override | ||
| 192 | + public void event(FlowRuleEvent event) { | ||
| 193 | + events.add(event); | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + private static class TestDeviceService implements DeviceService { | ||
| 198 | + | ||
| 199 | + @Override | ||
| 200 | + public int getDeviceCount() { | ||
| 201 | + return 0; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + @Override | ||
| 205 | + public Iterable<Device> getDevices() { | ||
| 206 | + return null; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + @Override | ||
| 210 | + public Device getDevice(DeviceId deviceId) { | ||
| 211 | + return DEV; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + @Override | ||
| 215 | + public MastershipRole getRole(DeviceId deviceId) { | ||
| 216 | + return null; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + @Override | ||
| 220 | + public List<Port> getPorts(DeviceId deviceId) { | ||
| 221 | + return null; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + @Override | ||
| 225 | + public Port getPort(DeviceId deviceId, PortNumber portNumber) { | ||
| 226 | + return null; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + @Override | ||
| 230 | + public boolean isAvailable(DeviceId deviceId) { | ||
| 231 | + return false; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + @Override | ||
| 235 | + public void addListener(DeviceListener listener) { | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + @Override | ||
| 239 | + public void removeListener(DeviceListener listener) { | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + private class TestProvider extends AbstractProvider implements FlowRuleProvider { | ||
| 245 | + | ||
| 246 | + protected TestProvider(ProviderId id) { | ||
| 247 | + super(PID); | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | + @Override | ||
| 251 | + public void applyFlowRule(FlowRule... flowRules) { | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + @Override | ||
| 255 | + public void removeFlowRule(FlowRule... flowRules) { | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + @Override | ||
| 259 | + public Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId) { | ||
| 260 | + return null; | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + private class TestSelector implements TrafficSelector { | ||
| 266 | + | ||
| 267 | + //for controlling hashcode uniqueness; | ||
| 268 | + private int testval; | ||
| 269 | + | ||
| 270 | + public TestSelector(int val) { | ||
| 271 | + testval = val; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + @Override | ||
| 275 | + public List<Criterion> criteria() { | ||
| 276 | + return null; | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + @Override | ||
| 280 | + public int hashCode() { | ||
| 281 | + return testval; | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + @Override | ||
| 285 | + public boolean equals(Object o) { | ||
| 286 | + if (o instanceof TestSelector) { | ||
| 287 | + return this.testval == ((TestSelector) o).testval; | ||
| 288 | + } | ||
| 289 | + return false; | ||
| 290 | + } | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + private class TestTreatment implements TrafficTreatment { | ||
| 294 | + | ||
| 295 | + //for controlling hashcode uniqueness; | ||
| 296 | + private int testval; | ||
| 297 | + | ||
| 298 | + public TestTreatment(int val) { | ||
| 299 | + testval = val; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + @Override | ||
| 303 | + public List<Instruction> instructions() { | ||
| 304 | + return null; | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + @Override | ||
| 308 | + public int hashCode() { | ||
| 309 | + return testval; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + @Override | ||
| 313 | + public boolean equals(Object o) { | ||
| 314 | + if (o instanceof TestTreatment) { | ||
| 315 | + return this.testval == ((TestTreatment) o).testval; | ||
| 316 | + } | ||
| 317 | + return false; | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | +} |
| ... | @@ -18,6 +18,7 @@ public final class IpAddress { | ... | @@ -18,6 +18,7 @@ public final class IpAddress { |
| 18 | 18 | ||
| 19 | //maximum CIDR value | 19 | //maximum CIDR value |
| 20 | public static final int MAX_INET_MASK = 32; | 20 | public static final int MAX_INET_MASK = 32; |
| 21 | + //no mask (no network), e.g. a simple address | ||
| 21 | public static final int DEFAULT_MASK = 0; | 22 | public static final int DEFAULT_MASK = 0; |
| 22 | 23 | ||
| 23 | /** | 24 | /** |
| ... | @@ -112,7 +113,7 @@ public final class IpAddress { | ... | @@ -112,7 +113,7 @@ public final class IpAddress { |
| 112 | final String [] parts = address.split("\\/"); | 113 | final String [] parts = address.split("\\/"); |
| 113 | if (parts.length > 2) { | 114 | if (parts.length > 2) { |
| 114 | throw new IllegalArgumentException("Malformed IP address string; " | 115 | throw new IllegalArgumentException("Malformed IP address string; " |
| 115 | - + "Addres must take form \"x.x.x.x\" or \"x.x.x.x/y\""); | 116 | + + "Address must take form \"x.x.x.x\" or \"x.x.x.x/y\""); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | int mask = DEFAULT_MASK; | 119 | int mask = DEFAULT_MASK; |
| ... | @@ -128,7 +129,7 @@ public final class IpAddress { | ... | @@ -128,7 +129,7 @@ public final class IpAddress { |
| 128 | final String [] net = parts[0].split("\\."); | 129 | final String [] net = parts[0].split("\\."); |
| 129 | if (net.length != INET_LEN) { | 130 | if (net.length != INET_LEN) { |
| 130 | throw new IllegalArgumentException("Malformed IP address string; " | 131 | throw new IllegalArgumentException("Malformed IP address string; " |
| 131 | - + "Addres must have four decimal values separated by dots (.)"); | 132 | + + "Address must have four decimal values separated by dots (.)"); |
| 132 | } | 133 | } |
| 133 | final byte [] bytes = new byte[INET_LEN]; | 134 | final byte [] bytes = new byte[INET_LEN]; |
| 134 | for (int i = 0; i < INET_LEN; i++) { | 135 | for (int i = 0; i < INET_LEN; i++) { | ... | ... |
-
Please register or login to post a comment