alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

1 +package org.onlab.onos.cluster;
2 +
3 +import org.onlab.onos.event.AbstractEvent;
4 +
5 +/**
6 + * Describes cluster-related event.
7 + */
8 +public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerInstance> {
9 +
10 + /**
11 + * Type of device events.
12 + */
13 + public enum Type {
14 + /**
15 + * Signifies that a new cluster instance has been administratively added.
16 + */
17 + INSTANCE_ADDED,
18 +
19 + /**
20 + * Signifies that a cluster instance has been administratively removed.
21 + */
22 + INSTANCE_REMOVED,
23 +
24 + /**
25 + * Signifies that a cluster instance became active.
26 + */
27 + INSTANCE_ACTIVE,
28 +
29 + /**
30 + * Signifies that a cluster instance became inactive.
31 + */
32 + INSTANCE_INACTIVE
33 + }
34 + // TODO: do we need to fix the verv/adjective mix? discuss
35 +
36 + /**
37 + * Creates an event of a given type and for the specified instance and the
38 + * current time.
39 + *
40 + * @param type cluster event type
41 + * @param instance cluster device subject
42 + */
43 + public ClusterEvent(Type type, ControllerInstance instance) {
44 + super(type, instance);
45 + }
46 +
47 + /**
48 + * Creates an event of a given type and for the specified device and time.
49 + *
50 + * @param type device event type
51 + * @param instance event device subject
52 + * @param time occurrence time
53 + */
54 + public ClusterEvent(Type type, ControllerInstance instance, long time) {
55 + super(type, instance, time);
56 + }
57 +
58 +}
1 +package org.onlab.onos.cluster;
2 +
3 +import java.util.Set;
4 +
5 +/**
6 + * Service for obtaining information about the individual instances within
7 + * the controller cluster.
8 + */
9 +public interface ClusterService {
10 +
11 + /**
12 + * Returns the set of current cluster members.
13 + *
14 + * @return set of cluster members
15 + */
16 + Set<ControllerInstance> getInstances();
17 +
18 + /**
19 + * Returns the availability state of the specified controller instance.
20 + *
21 + * @return availability state
22 + */
23 + ControllerInstance.State getState(ControllerInstance instance);
24 + // TODO: determine if this would be better attached to ControllerInstance directly
25 +
26 +
27 + // addListener, removeListener
28 +
29 +}
1 +package org.onlab.onos.cluster;
2 +
3 +import org.onlab.packet.IpAddress;
4 +
5 +/**
6 + * Represents a controller instance as a member in a cluster.
7 + */
8 +public interface ControllerInstance {
9 +
10 + /** Represents the operational state of the instance. */
11 + public enum State {
12 + /**
13 + * Signifies that the instance is active and operating normally.
14 + */
15 + ACTIVE,
16 +
17 + /**
18 + * Signifies that the instance is inactive, which means either down or
19 + * up, but not operational.
20 + */
21 + INACTIVE
22 + }
23 +
24 + /**
25 + * Returns the instance identifier.
26 + *
27 + * @return instance identifier
28 + */
29 + InstanceId id();
30 +
31 + /**
32 + * Returns the IP address of the controller instance.
33 + *
34 + * @return IP address
35 + */
36 + IpAddress ip();
37 +
38 +}
1 +package org.onlab.onos.cluster;
2 +
3 +/**
4 + * Controller cluster identity.
5 + */
6 +public interface InstanceId {
7 +}
1 +/**
2 + * Set of abstractions for dealing with controller cluster related topics.
3 + */
4 +package org.onlab.onos.cluster;
...\ No newline at end of file ...\ No newline at end of file
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
......
...@@ -19,7 +19,7 @@ public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> { ...@@ -19,7 +19,7 @@ public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> {
19 /** 19 /**
20 * Signifies that a flow rule has been removed. 20 * Signifies that a flow rule has been removed.
21 */ 21 */
22 - RULE_REMOVED, 22 + RULE_REMOVED
23 } 23 }
24 24
25 /** 25 /**
......
...@@ -23,6 +23,8 @@ public interface FlowRuleService { ...@@ -23,6 +23,8 @@ public interface FlowRuleService {
23 */ 23 */
24 Iterable<FlowEntry> getFlowEntries(DeviceId deviceId); 24 Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
25 25
26 + // TODO: add createFlowRule factory method and execute operations method
27 +
26 /** 28 /**
27 * Applies the specified flow rules onto their respective devices. These 29 * Applies the specified flow rules onto their respective devices. These
28 * flow rules will be retained by the system and re-applied anytime the 30 * flow rules will be retained by the system and re-applied anytime the
...@@ -46,9 +48,6 @@ public interface FlowRuleService { ...@@ -46,9 +48,6 @@ public interface FlowRuleService {
46 void removeFlowRules(FlowRule... flowRules); 48 void removeFlowRules(FlowRule... flowRules);
47 49
48 50
49 - // void addInitialFlowContributor(InitialFlowContributor contributor);
50 - // void removeInitialFlowContributor(InitialFlowContributor contributor);
51 -
52 /** 51 /**
53 * Adds the specified flow rule listener. 52 * Adds the specified flow rule listener.
54 * 53 *
......
...@@ -44,10 +44,10 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -44,10 +44,10 @@ implements FlowRuleService, FlowRuleProviderRegistry {
44 private final SimpleFlowRuleStore store = new SimpleFlowRuleStore(); 44 private final SimpleFlowRuleStore store = new SimpleFlowRuleStore();
45 45
46 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 46 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
47 - private EventDeliveryService eventDispatcher; 47 + protected EventDeliveryService eventDispatcher;
48 48
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 - private DeviceService deviceService; 50 + protected DeviceService deviceService;
51 51
52 @Activate 52 @Activate
53 public void activate() { 53 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;
......
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 +}
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
7 description="ONOS 3rd party dependencies"> 7 description="ONOS 3rd party dependencies">
8 <bundle>mvn:commons-lang/commons-lang/2.6</bundle> 8 <bundle>mvn:commons-lang/commons-lang/2.6</bundle>
9 <bundle>mvn:com.google.guava/guava/18.0</bundle> 9 <bundle>mvn:com.google.guava/guava/18.0</bundle>
10 -
11 <bundle>mvn:io.netty/netty/3.9.2.Final</bundle> 10 <bundle>mvn:io.netty/netty/3.9.2.Final</bundle>
12 </feature> 11 </feature>
13 12
...@@ -63,7 +62,7 @@ ...@@ -63,7 +62,7 @@
63 <feature name="onos-openflow" version="1.0.0" 62 <feature name="onos-openflow" version="1.0.0"
64 description="ONOS OpenFlow API, Controller &amp; Providers"> 63 description="ONOS OpenFlow API, Controller &amp; Providers">
65 <feature>onos-api</feature> 64 <feature>onos-api</feature>
66 - 65 + <bundle>mvn:io.netty/netty/3.9.2.Final</bundle>
67 <bundle>mvn:org.onlab.onos/onos-of-api/1.0.0-SNAPSHOT</bundle> 66 <bundle>mvn:org.onlab.onos/onos-of-api/1.0.0-SNAPSHOT</bundle>
68 <bundle>mvn:org.onlab.onos/onos-of-ctl/1.0.0-SNAPSHOT</bundle> 67 <bundle>mvn:org.onlab.onos/onos-of-ctl/1.0.0-SNAPSHOT</bundle>
69 68
...@@ -77,8 +76,9 @@ ...@@ -77,8 +76,9 @@
77 76
78 <feature name="onos-app-tvue" version="1.0.0" 77 <feature name="onos-app-tvue" version="1.0.0"
79 description="ONOS sample topology viewer application"> 78 description="ONOS sample topology viewer application">
80 - <feature>onos-api</feature>
81 <feature>onos-thirdparty-web</feature> 79 <feature>onos-thirdparty-web</feature>
80 + <feature>onos-api</feature>
81 + <feature>onos-core</feature>
82 <bundle>mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT</bundle> 82 <bundle>mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT</bundle>
83 </feature> 83 </feature>
84 84
......
...@@ -15,107 +15,27 @@ ...@@ -15,107 +15,27 @@
15 15
16 <description>ONOS OpenFlow controller subsystem API</description> 16 <description>ONOS OpenFlow controller subsystem API</description>
17 17
18 - <properties>
19 - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20 - <powermock.version>1.5.5</powermock.version>
21 - <restlet.version>2.1.4</restlet.version>
22 - <cobertura-maven-plugin.version>2.6</cobertura-maven-plugin.version>
23 - <!-- Following 2 findbugs version needs to be updated in sync to match the
24 - findbugs version used in findbugs-plugin -->
25 - <findbugs.version>3.0.0</findbugs.version>
26 - <findbugs-plugin.version>3.0.0</findbugs-plugin.version>
27 - <findbugs.effort>Max</findbugs.effort>
28 - <findbugs.excludeFilterFile>${project.basedir}/conf/findbugs/exclude.xml
29 - </findbugs.excludeFilterFile>
30 - <checkstyle-plugin.version>2.12</checkstyle-plugin.version>
31 - <!-- To publish javadoc to github,
32 - uncomment com.github.github site-maven-plugin and
33 - see https://github.com/OPENNETWORKINGLAB/ONOS/pull/425
34 - <github.global.server>github</github.global.server>
35 - -->
36 - <metrics.version>3.0.2</metrics.version>
37 - <maven.surefire.plugin.version>2.16</maven.surefire.plugin.version>
38 - </properties>
39 -
40 <dependencies> 18 <dependencies>
41 <dependency> 19 <dependency>
42 <groupId>org.onlab.onos</groupId> 20 <groupId>org.onlab.onos</groupId>
43 <artifactId>onos-of-api</artifactId> 21 <artifactId>onos-of-api</artifactId>
44 </dependency> 22 </dependency>
45 - <!-- ONOS's direct dependencies -->
46 - <dependency>
47 - <groupId>org.apache.felix</groupId>
48 - <artifactId>org.apache.felix.scr.annotations</artifactId>
49 - <version>1.9.6</version>
50 - </dependency>
51 - <dependency>
52 - <groupId>ch.qos.logback</groupId>
53 - <artifactId>logback-classic</artifactId>
54 - <version>1.1.2</version>
55 - </dependency>
56 - <dependency>
57 - <groupId>ch.qos.logback</groupId>
58 - <artifactId>logback-core</artifactId>
59 - <version>1.1.2</version>
60 - </dependency>
61 - <dependency>
62 - <groupId>org.slf4j</groupId>
63 - <artifactId>slf4j-api</artifactId>
64 - <version>1.7.5</version>
65 - </dependency>
66 - <dependency>
67 - <!-- findbugs suppression annotation and @GuardedBy, etc. -->
68 - <groupId>com.google.code.findbugs</groupId>
69 - <artifactId>annotations</artifactId>
70 - <version>${findbugs.version}</version>
71 - </dependency>
72 <dependency> 23 <dependency>
73 - <groupId>org.projectfloodlight</groupId>
74 - <artifactId>openflowj</artifactId>
75 - <version>0.3.8-SNAPSHOT</version>
76 - </dependency>
77 - <!-- Floodlight's dependencies -->
78 - <dependency>
79 - <!-- dependency to old version of netty? -->
80 <groupId>io.netty</groupId> 24 <groupId>io.netty</groupId>
81 <artifactId>netty</artifactId> 25 <artifactId>netty</artifactId>
82 - <version>3.9.2.Final</version>
83 - </dependency>
84 - <!-- Dependency for libraries used for testing -->
85 - <dependency>
86 - <groupId>junit</groupId>
87 - <artifactId>junit</artifactId>
88 - <version>4.11</version>
89 - <scope>test</scope>
90 - </dependency>
91 - <dependency>
92 - <groupId>org.easymock</groupId>
93 - <artifactId>easymock</artifactId>
94 - <version>3.2</version>
95 - <scope>test</scope>
96 </dependency> 26 </dependency>
97 <dependency> 27 <dependency>
98 - <groupId>org.powermock</groupId> 28 + <groupId>org.apache.felix</groupId>
99 - <artifactId>powermock-module-junit4</artifactId> 29 + <artifactId>org.apache.felix.scr.annotations</artifactId>
100 - <version>${powermock.version}</version>
101 - <scope>test</scope>
102 - </dependency>
103 - <dependency>
104 - <groupId>org.powermock</groupId>
105 - <artifactId>powermock-api-easymock</artifactId>
106 - <version>${powermock.version}</version>
107 - <scope>test</scope>
108 </dependency> 30 </dependency>
109 </dependencies> 31 </dependencies>
110 32
111 -
112 <build> 33 <build>
113 <plugins> 34 <plugins>
114 <plugin> 35 <plugin>
115 <groupId>org.apache.felix</groupId> 36 <groupId>org.apache.felix</groupId>
116 <artifactId>maven-scr-plugin</artifactId> 37 <artifactId>maven-scr-plugin</artifactId>
117 </plugin> 38 </plugin>
118 -
119 </plugins> 39 </plugins>
120 </build> 40 </build>
121 41
......
1 +# Environmental defaults for ONOS build, package and test
2 +
3 +# Root of the ONOS source tree
4 +export ONOS_ROOT=${ONOS_ROOT:-~/onos-next}
5 +
6 +# M2 repository and Karaf gold bits
7 +export M2_REPO=${M2_REPO:-~/.m2/repository}
8 +export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip}
9 +export KARAF_DIST=$(basename $KARAF_ZIP .zip)
10 +
11 +# ONOS Version and onos.tar.gz staging environment
12 +export ONOS_VERSION=${ONOS_VERSION:-1.0.0-SNAPSHOT}
13 +export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp}
14 +export ONOS_BITS=onos-$ONOS_VERSION
15 +export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS
16 +export ONOS_TAR=$ONOS_STAGE.tar.gz
17 +
18 +# Defaults for ONOS testing using remote machines.
19 +export ONOS_INSTALL_DIR="/opt/onos" # Installation directory on remote
20 +export OCI="${OCI:-192.168.56.101}" # ONOS Controller Instance
21 +export ONOS_USER="sdn" # ONOS user on remote system
22 +export ONOS_PWD="rocks" # ONOS user password on remote system
...@@ -3,14 +3,8 @@ ...@@ -3,14 +3,8 @@
3 # Packages ONOS distributable into onos.tar.gz 3 # Packages ONOS distributable into onos.tar.gz
4 #------------------------------------------------------------------------------- 4 #-------------------------------------------------------------------------------
5 5
6 -export M2_REPO=${M2_REPO:-~/.m2/repository} 6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 -export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip} 7 +. $ONOS_ROOT/tools/build/envDefaults
8 -export KARAF_DIST=$(basename $KARAF_ZIP .zip)
9 -
10 -export ONOS_VERSION=${ONOS_VERSION:-1.0.0-SNAPSHOT}
11 -export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp}
12 -export ONOS_BITS=onos-$ONOS_VERSION
13 -export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS
14 8
15 # Bail on any errors 9 # Bail on any errors
16 set -e 10 set -e
...@@ -26,29 +20,31 @@ rm -fr $ONOS_STAGE # Remove this when package script is completed ...@@ -26,29 +20,31 @@ rm -fr $ONOS_STAGE # Remove this when package script is completed
26 mkdir -p $ONOS_STAGE 20 mkdir -p $ONOS_STAGE
27 cd $ONOS_STAGE 21 cd $ONOS_STAGE
28 22
29 -# Unroll the Apache Karaf bits and make the ONOS top-level directories. 23 +# Unroll the Apache Karaf bits, prune them and make ONOS top-level directories.
30 -unzip $KARAF_ZIP 24 +unzip -q $KARAF_ZIP && rm -rf $KARAF_DIST/demos
31 mkdir bin 25 mkdir bin
32 26
33 -# Stage the ONOS admin scripts 27 +# Stage the ONOS admin scripts and patch in Karaf service wrapper extras
34 cp -r $ONOS_ROOT/tools/package/bin . 28 cp -r $ONOS_ROOT/tools/package/bin .
29 +cp -r $ONOS_ROOT/tools/package/wrapper/* $KARAF_DIST
35 30
36 # Stage the ONOS bundles 31 # Stage the ONOS bundles
37 -mkdir -p system/org/onlab 32 +mkdir -p $KARAF_DIST/system/org/onlab
38 -cp -r $M2_REPO/org/onlab system/org/ 33 +cp -r $M2_REPO/org/onlab $KARAF_DIST/system/org/
39 34
40 # Patch the Apache Karaf distribution file to add ONOS features repository 35 # Patch the Apache Karaf distribution file to add ONOS features repository
41 perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \ 36 perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \
42 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg 37 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
43 38
44 # Patch the Apache Karaf distribution file to load ONOS features 39 # Patch the Apache Karaf distribution file to load ONOS features
45 -perl -pi.old -e 's|^(featuresBoot=.*)|\1,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-tvue|' \ 40 +perl -pi.old -e 's|^(featuresBoot=.*)|\1,wrapper,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-tvue|' \
46 - /tmp/onos-1.0.0-SNAPSHOT/apache-karaf-3.0.1/etc/org.apache.karaf.features.cfg 41 + $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
47 42
48 # Patch the Apache Karaf distribution with ONOS branding bundle 43 # Patch the Apache Karaf distribution with ONOS branding bundle
49 cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \ 44 cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \
50 - $ONOS_STAGE/apache-karaf-*/lib 45 + $ONOS_STAGE/$KARAF_DIST/lib
51 46
52 # Now package up the ONOS tar file 47 # Now package up the ONOS tar file
53 cd $ONOS_STAGE_ROOT 48 cd $ONOS_STAGE_ROOT
54 -tar zcf $ONOS_BITS.tar.gz $ONOS_BITS 49 +COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS
50 +ls -l $ONOS_TAR >&2
......
...@@ -12,7 +12,8 @@ export KARAF_LOG=$KARAF/data/log/karaf.log ...@@ -12,7 +12,8 @@ export KARAF_LOG=$KARAF/data/log/karaf.log
12 12
13 # Setup a path 13 # Setup a path
14 export PS=":" 14 export PS=":"
15 -export PATH="$PATH:$ONOS_ROOT/tools/dev:$ONOS_ROOT/tools/package" 15 +export PATH="$PATH:$ONOS_ROOT/tools/dev:$ONOS_ROOT/tools/build"
16 +export PATH="$PATH:$ONOS_ROOT/tools/test/bin"
16 export PATH="$PATH:$MAVEN/bin:$KARAF/bin" 17 export PATH="$PATH:$MAVEN/bin:$KARAF/bin"
17 export PATH="$PATH:." 18 export PATH="$PATH:."
18 19
...@@ -39,3 +40,13 @@ alias pp='python -m json.tool' ...@@ -39,3 +40,13 @@ alias pp='python -m json.tool'
39 # Short-hand to launch API docs and sample topology viewer GUI 40 # Short-hand to launch API docs and sample topology viewer GUI
40 alias docs='open $ONOS_ROOT/target/site/apidocs/index.html' 41 alias docs='open $ONOS_ROOT/target/site/apidocs/index.html'
41 alias gui='open http://localhost:8181/onos/tvue' 42 alias gui='open http://localhost:8181/onos/tvue'
43 +
44 +
45 +# Miscellaneous
46 +function spy {
47 + ps -ef | egrep "$@" | grep -v egrep
48 +}
49 +
50 +function nuke {
51 + spy | cut -c7-11 | xargs kill
52 +}
......
1 +Artifacts for packaging onos.tar.gz.
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# ONOS command-line client
4 +#-------------------------------------------------------------------------------
5 +
6 +export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/
7 +
8 +cd $(dirname $0)/../apache-karaf-*/bin
9 +./client -h localhost "$@"
10 +
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
3 # Starts ONOS Apache Karaf container 3 # Starts ONOS Apache Karaf container
4 #------------------------------------------------------------------------------- 4 #-------------------------------------------------------------------------------
5 5
6 +export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/
7 +
6 cd $(dirname $0)/../apache-karaf-*/bin 8 cd $(dirname $0)/../apache-karaf-*/bin
7 ./karaf "$@" 9 ./karaf "$@"
8 10
......
This diff is collapsed. Click to expand it.
No preview for this file type
1 +# ------------------------------------------------------------------------
2 +# Licensed to the Apache Software Foundation (ASF) under one or more
3 +# contributor license agreements. See the NOTICE file distributed with
4 +# this work for additional information regarding copyright ownership.
5 +# The ASF licenses this file to You under the Apache License, Version 2.0
6 +# (the "License"); you may not use this file except in compliance with
7 +# the License. You may obtain a copy of the License at
8 +#
9 +# http://www.apache.org/licenses/LICENSE-2.0
10 +#
11 +# Unless required by applicable law or agreed to in writing, software
12 +# distributed under the License is distributed on an "AS IS" BASIS,
13 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 +# See the License for the specific language governing permissions and
15 +# limitations under the License.
16 +# ------------------------------------------------------------------------
17 +
18 +#********************************************************************
19 +# Wrapper Properties
20 +#********************************************************************
21 +set.default.JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/
22 +set.default.KARAF_HOME=/opt/onos/apache-karaf-3.0.1
23 +set.default.KARAF_BASE=/opt/onos/apache-karaf-3.0.1
24 +set.default.KARAF_DATA=/opt/onos/apache-karaf-3.0.1/data
25 +set.default.KARAF_ETC=/opt/onos/apache-karaf-3.0.1/etc
26 +
27 +# Java Application
28 +wrapper.working.dir=%KARAF_BASE%
29 +wrapper.java.command=%JAVA_HOME%/bin/java
30 +wrapper.java.mainclass=org.apache.karaf.wrapper.internal.Main
31 +wrapper.java.classpath.1=%KARAF_HOME%/lib/karaf-wrapper.jar
32 +wrapper.java.classpath.2=%KARAF_HOME%/lib/karaf.jar
33 +wrapper.java.classpath.3=%KARAF_HOME%/lib/karaf-jmx-boot.jar
34 +wrapper.java.classpath.4=%KARAF_HOME%/lib/karaf-jaas-boot.jar
35 +wrapper.java.classpath.5=%KARAF_HOME%/lib/karaf-wrapper-main.jar
36 +wrapper.java.classpath.6=%KARAF_HOME%/lib/karaf-org.osgi.core.jar
37 +wrapper.java.library.path.1=%KARAF_HOME%/lib/
38 +
39 +# Application Parameters. Add parameters as needed starting from 1
40 +#wrapper.app.parameter.1=
41 +
42 +# JVM Parameters
43 +# note that n is the parameter number starting from 1.
44 +wrapper.java.additional.1=-Dkaraf.home=%KARAF_HOME%
45 +wrapper.java.additional.2=-Dkaraf.base=%KARAF_BASE%
46 +wrapper.java.additional.3=-Dkaraf.data=%KARAF_DATA%
47 +wrapper.java.additional.4=-Dkaraf.etc=%KARAF_ETC%
48 +wrapper.java.additional.5=-Dcom.sun.management.jmxremote
49 +wrapper.java.additional.6=-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
50 +wrapper.java.additional.7=-Dkaraf.startLocalConsole=false
51 +wrapper.java.additional.8=-Dkaraf.startRemoteShell=true
52 +wrapper.java.additional.9=-Djava.endorsed.dirs=%JAVA_HOME%/jre/lib/endorsed:%JAVA_HOME%/lib/endorsed:%KARAF_HOME%/lib/endorsed
53 +wrapper.java.additional.10=-Djava.ext.dirs=%JAVA_HOME%/jre/lib/ext:%JAVA_HOME%/lib/ext:%KARAF_HOME%/lib/ext
54 +
55 +# Uncomment to enable jmx
56 +#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.port=1616
57 +#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.authenticate=false
58 +#wrapper.java.additional.n=-Dcom.sun.management.jmxremote.ssl=false
59 +
60 +# Uncomment to enable YourKit profiling
61 +#wrapper.java.additional.n=-Xrunyjpagent
62 +
63 +# Uncomment to enable remote debugging
64 +#wrapper.java.additional.n=-Xdebug -Xnoagent -Djava.compiler=NONE
65 +#wrapper.java.additional.n=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
66 +
67 +# Initial Java Heap Size (in MB)
68 +#wrapper.java.initmemory=3
69 +
70 +# Maximum Java Heap Size (in MB)
71 +wrapper.java.maxmemory=512
72 +
73 +
74 +#********************************************************************
75 +# Wrapper Logging Properties
76 +#********************************************************************
77 +# Format of output for the console. (See docs for formats)
78 +wrapper.console.format=PM
79 +
80 +# Log Level for console output. (See docs for log levels)
81 +wrapper.console.loglevel=INFO
82 +
83 +# Log file to use for wrapper output logging.
84 +wrapper.logfile=%KARAF_DATA%/log/wrapper.log
85 +
86 +# Format of output for the log file. (See docs for formats)
87 +wrapper.logfile.format=LPTM
88 +
89 +# Log Level for log file output. (See docs for log levels)
90 +wrapper.logfile.loglevel=INFO
91 +
92 +# Maximum size that the log file will be allowed to grow to before
93 +# the log is rolled. Size is specified in bytes. The default value
94 +# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
95 +# 'm' (mb) suffix. For example: 10m = 10 megabytes.
96 +wrapper.logfile.maxsize=10m
97 +
98 +# Maximum number of rolled log files which will be allowed before old
99 +# files are deleted. The default value of 0 implies no limit.
100 +wrapper.logfile.maxfiles=5
101 +
102 +# Log Level for sys/event log output. (See docs for log levels)
103 +wrapper.syslog.loglevel=NONE
104 +
105 +#********************************************************************
106 +# Wrapper Windows Properties
107 +#********************************************************************
108 +# Title to use when running as a console
109 +wrapper.console.title=onos
110 +
111 +#********************************************************************
112 +# Wrapper Windows NT/2000/XP Service Properties
113 +#********************************************************************
114 +# WARNING - Do not modify any of these properties when an application
115 +# using this configuration file has been installed as a service.
116 +# Please uninstall the service before modifying this section. The
117 +# service can then be reinstalled.
118 +
119 +# Name of the service
120 +wrapper.ntservice.name=onos
121 +
122 +# Display name of the service
123 +wrapper.ntservice.displayname=onos
124 +
125 +# Description of the service
126 +wrapper.ntservice.description=ONOS
127 +
128 +# Service dependencies. Add dependencies as needed starting from 1
129 +wrapper.ntservice.dependency.1=
130 +
131 +# Mode in which the service is installed. AUTO_START or DEMAND_START
132 +wrapper.ntservice.starttype=AUTO_START
133 +
134 +# Allow the service to interact with the desktop.
135 +wrapper.ntservice.interactive=false
No preview for this file type
No preview for this file type
1 +Artifacts for system testing onos.
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Remotely pushes bits to a remote machine and install & starts ONOS.
4 +#-------------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +# If the first option is -f attempt uninstall first.
10 +[ "$1" = "-f" ] && shift && onos-uninstall ${1:-$OCI}
11 +
12 +remote=$ONOS_USER@${1:-$OCI}
13 +
14 +scp -q $ONOS_TAR $remote:/tmp
15 +
16 +ssh $remote "
17 + [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1
18 +
19 + sudo mkdir -p $ONOS_INSTALL_DIR && sudo chown sdn:sdn $ONOS_INSTALL_DIR
20 + tar zxmf /tmp/$ONOS_BITS.tar.gz -C $ONOS_INSTALL_DIR --strip-components=1
21 +
22 + ln -s /opt/onos/$KARAF_DIST/data/log /opt/onos/log
23 +
24 +"
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Remotely stops & uninstalls ONOS.
4 +#-------------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +remote=$ONOS_USER@${1:-$OCI}
10 +
11 +ssh $remote "
12 + [ -f $ONOS_INSTALL_DIR/bin/onos ] && \
13 + $ONOS_INSTALL_DIR/bin/onos halt 2>/dev/null
14 + sudo rm -fr $ONOS_INSTALL_DIR
15 +"
...@@ -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++) {
......