blob: 361b071f0baca10004a77435a7237cf7ad8470d7 [file] [log] [blame]
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -07001package org.onlab.onos.store.device.impl;
2
3import static org.junit.Assert.*;
4import static org.onlab.onos.net.Device.Type.SWITCH;
5import static org.onlab.onos.net.DeviceId.deviceId;
6import static org.onlab.onos.net.device.DeviceEvent.Type.*;
7
Madan Jampani47c93732014-10-06 20:46:08 -07008import java.io.IOException;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -07009import java.util.Arrays;
10import java.util.HashMap;
11import java.util.List;
12import java.util.Map;
13import java.util.Set;
14import java.util.concurrent.CountDownLatch;
15import java.util.concurrent.TimeUnit;
16
17import org.junit.After;
18import org.junit.AfterClass;
19import org.junit.Before;
20import org.junit.BeforeClass;
21import org.junit.Ignore;
22import org.junit.Test;
23import org.onlab.onos.cluster.MastershipTerm;
24import org.onlab.onos.cluster.NodeId;
25import org.onlab.onos.net.Annotations;
26import org.onlab.onos.net.DefaultAnnotations;
27import org.onlab.onos.net.Device;
28import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.Port;
30import org.onlab.onos.net.PortNumber;
31import org.onlab.onos.net.SparseAnnotations;
32import org.onlab.onos.net.device.DefaultDeviceDescription;
33import org.onlab.onos.net.device.DefaultPortDescription;
34import org.onlab.onos.net.device.DeviceDescription;
35import org.onlab.onos.net.device.DeviceEvent;
36import org.onlab.onos.net.device.DeviceStore;
37import org.onlab.onos.net.device.DeviceStoreDelegate;
38import org.onlab.onos.net.device.PortDescription;
39import org.onlab.onos.net.provider.ProviderId;
40import org.onlab.onos.store.ClockService;
Madan Jampani47c93732014-10-06 20:46:08 -070041import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
42import org.onlab.onos.store.cluster.messaging.ClusterMessage;
43import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
44import org.onlab.onos.store.cluster.messaging.MessageSubject;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -070045
46import com.google.common.collect.Iterables;
47import com.google.common.collect.Sets;
48
49
50// TODO add tests for remote replication
51/**
52 * Test of the gossip based distributed DeviceStore implementation.
53 */
54public class GossipDeviceStoreTest {
55
56 private static final ProviderId PID = new ProviderId("of", "foo");
57 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
58 private static final DeviceId DID1 = deviceId("of:foo");
59 private static final DeviceId DID2 = deviceId("of:bar");
60 private static final String MFR = "whitebox";
61 private static final String HW = "1.1.x";
62 private static final String SW1 = "3.8.1";
63 private static final String SW2 = "3.9.5";
64 private static final String SN = "43311-12345";
65
66 private static final PortNumber P1 = PortNumber.portNumber(1);
67 private static final PortNumber P2 = PortNumber.portNumber(2);
68 private static final PortNumber P3 = PortNumber.portNumber(3);
69
70 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
71 .set("A1", "a1")
72 .set("B1", "b1")
73 .build();
74 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
75 .remove("A1")
76 .set("B3", "b3")
77 .build();
78 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
79 .set("A2", "a2")
80 .set("B2", "b2")
81 .build();
82 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
83 .remove("A2")
84 .set("B4", "b4")
85 .build();
86
87 private static final NodeId MYSELF = new NodeId("myself");
88
89 private GossipDeviceStore gossipDeviceStore;
90 private DeviceStore deviceStore;
91
92 private DeviceClockManager deviceClockManager;
93 private ClockService clockService;
94
95 @BeforeClass
96 public static void setUpBeforeClass() throws Exception {
97 }
98
99 @AfterClass
100 public static void tearDownAfterClass() throws Exception {
101 }
102
103
104 @Before
105 public void setUp() throws Exception {
106 deviceClockManager = new DeviceClockManager();
107 deviceClockManager.activate();
108 clockService = deviceClockManager;
109
110 deviceClockManager.setMastershipTerm(DID1, MastershipTerm.of(MYSELF, 1));
111 deviceClockManager.setMastershipTerm(DID2, MastershipTerm.of(MYSELF, 2));
112
Madan Jampani47c93732014-10-06 20:46:08 -0700113 ClusterCommunicationService clusterCommunicator = new TestClusterCommunicationService();
114
115 gossipDeviceStore = new TestGossipDeviceStore(clockService, clusterCommunicator);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700116 gossipDeviceStore.activate();
117 deviceStore = gossipDeviceStore;
118 }
119
120 @After
121 public void tearDown() throws Exception {
122 gossipDeviceStore.deactivate();
123 deviceClockManager.deactivate();
124 }
125
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700126 private void putDevice(DeviceId deviceId, String swVersion,
127 SparseAnnotations... annotations) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700128 DeviceDescription description =
129 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700130 HW, swVersion, SN, annotations);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700131 deviceStore.createOrUpdateDevice(PID, deviceId, description);
132 }
133
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700134 private void putDeviceAncillary(DeviceId deviceId, String swVersion,
135 SparseAnnotations... annotations) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700136 DeviceDescription description =
137 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700138 HW, swVersion, SN, annotations);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700139 deviceStore.createOrUpdateDevice(PIDA, deviceId, description);
140 }
141
142 private static void assertDevice(DeviceId id, String swVersion, Device device) {
143 assertNotNull(device);
144 assertEquals(id, device.id());
145 assertEquals(MFR, device.manufacturer());
146 assertEquals(HW, device.hwVersion());
147 assertEquals(swVersion, device.swVersion());
148 assertEquals(SN, device.serialNumber());
149 }
150
151 /**
152 * Verifies that Annotations created by merging {@code annotations} is
153 * equal to actual Annotations.
154 *
155 * @param actual Annotations to check
156 * @param annotations
157 */
158 private static void assertAnnotationsEquals(Annotations actual, SparseAnnotations... annotations) {
159 DefaultAnnotations expected = DefaultAnnotations.builder().build();
160 for (SparseAnnotations a : annotations) {
161 expected = DefaultAnnotations.merge(expected, a);
162 }
163 assertEquals(expected.keys(), actual.keys());
164 for (String key : expected.keys()) {
165 assertEquals(expected.value(key), actual.value(key));
166 }
167 }
168
169 @Test
170 public final void testGetDeviceCount() {
171 assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
172
173 putDevice(DID1, SW1);
174 putDevice(DID2, SW2);
175 putDevice(DID1, SW1);
176
177 assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
178 }
179
180 @Test
181 public final void testGetDevices() {
182 assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
183
184 putDevice(DID1, SW1);
185 putDevice(DID2, SW2);
186 putDevice(DID1, SW1);
187
188 assertEquals("expect 2 uniq devices",
189 2, Iterables.size(deviceStore.getDevices()));
190
191 Map<DeviceId, Device> devices = new HashMap<>();
192 for (Device device : deviceStore.getDevices()) {
193 devices.put(device.id(), device);
194 }
195
196 assertDevice(DID1, SW1, devices.get(DID1));
197 assertDevice(DID2, SW2, devices.get(DID2));
198
199 // add case for new node?
200 }
201
202 @Test
203 public final void testGetDevice() {
204
205 putDevice(DID1, SW1);
206
207 assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
208 assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
209 }
210
211 @Test
212 public final void testCreateOrUpdateDevice() {
213 DeviceDescription description =
214 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
215 HW, SW1, SN);
216 DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
217 assertEquals(DEVICE_ADDED, event.type());
218 assertDevice(DID1, SW1, event.subject());
219
220 DeviceDescription description2 =
221 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
222 HW, SW2, SN);
223 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
224 assertEquals(DEVICE_UPDATED, event2.type());
225 assertDevice(DID1, SW2, event2.subject());
226
227 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
228 }
229
230 @Test
231 public final void testCreateOrUpdateDeviceAncillary() {
232 DeviceDescription description =
233 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
234 HW, SW1, SN, A2);
235 DeviceEvent event = deviceStore.createOrUpdateDevice(PIDA, DID1, description);
236 assertEquals(DEVICE_ADDED, event.type());
237 assertDevice(DID1, SW1, event.subject());
238 assertEquals(PIDA, event.subject().providerId());
239 assertAnnotationsEquals(event.subject().annotations(), A2);
240 assertFalse("Ancillary will not bring device up", deviceStore.isAvailable(DID1));
241
242 DeviceDescription description2 =
243 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
244 HW, SW2, SN, A1);
245 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
246 assertEquals(DEVICE_UPDATED, event2.type());
247 assertDevice(DID1, SW2, event2.subject());
248 assertEquals(PID, event2.subject().providerId());
249 assertAnnotationsEquals(event2.subject().annotations(), A1, A2);
250 assertTrue(deviceStore.isAvailable(DID1));
251
252 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
253
254 // For now, Ancillary is ignored once primary appears
255 assertNull("No change expected", deviceStore.createOrUpdateDevice(PIDA, DID1, description));
256
257 // But, Ancillary annotations will be in effect
258 DeviceDescription description3 =
259 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
260 HW, SW1, SN, A2_2);
261 DeviceEvent event3 = deviceStore.createOrUpdateDevice(PIDA, DID1, description3);
262 assertEquals(DEVICE_UPDATED, event3.type());
263 // basic information will be the one from Primary
264 assertDevice(DID1, SW2, event3.subject());
265 assertEquals(PID, event3.subject().providerId());
266 // but annotation from Ancillary will be merged
267 assertAnnotationsEquals(event3.subject().annotations(), A1, A2, A2_2);
268 assertTrue(deviceStore.isAvailable(DID1));
269 }
270
271
272 @Test
273 public final void testMarkOffline() {
274
275 putDevice(DID1, SW1);
276 assertTrue(deviceStore.isAvailable(DID1));
277
278 DeviceEvent event = deviceStore.markOffline(DID1);
279 assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
280 assertDevice(DID1, SW1, event.subject());
281 assertFalse(deviceStore.isAvailable(DID1));
282
283 DeviceEvent event2 = deviceStore.markOffline(DID1);
284 assertNull("No change, no event", event2);
285}
286
287 @Test
288 public final void testUpdatePorts() {
289 putDevice(DID1, SW1);
290 List<PortDescription> pds = Arrays.<PortDescription>asList(
291 new DefaultPortDescription(P1, true),
292 new DefaultPortDescription(P2, true)
293 );
294
295 List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds);
296
297 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
298 for (DeviceEvent event : events) {
299 assertEquals(PORT_ADDED, event.type());
300 assertDevice(DID1, SW1, event.subject());
301 assertTrue("PortNumber is one of expected",
302 expectedPorts.remove(event.port().number()));
303 assertTrue("Port is enabled", event.port().isEnabled());
304 }
305 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
306
307
308 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
309 new DefaultPortDescription(P1, false),
310 new DefaultPortDescription(P2, true),
311 new DefaultPortDescription(P3, true)
312 );
313
314 events = deviceStore.updatePorts(PID, DID1, pds2);
315 assertFalse("event should be triggered", events.isEmpty());
316 for (DeviceEvent event : events) {
317 PortNumber num = event.port().number();
318 if (P1.equals(num)) {
319 assertEquals(PORT_UPDATED, event.type());
320 assertDevice(DID1, SW1, event.subject());
321 assertFalse("Port is disabled", event.port().isEnabled());
322 } else if (P2.equals(num)) {
323 fail("P2 event not expected.");
324 } else if (P3.equals(num)) {
325 assertEquals(PORT_ADDED, event.type());
326 assertDevice(DID1, SW1, event.subject());
327 assertTrue("Port is enabled", event.port().isEnabled());
328 } else {
329 fail("Unknown port number encountered: " + num);
330 }
331 }
332
333 List<PortDescription> pds3 = Arrays.<PortDescription>asList(
334 new DefaultPortDescription(P1, false),
335 new DefaultPortDescription(P2, true)
336 );
337 events = deviceStore.updatePorts(PID, DID1, pds3);
338 assertFalse("event should be triggered", events.isEmpty());
339 for (DeviceEvent event : events) {
340 PortNumber num = event.port().number();
341 if (P1.equals(num)) {
342 fail("P1 event not expected.");
343 } else if (P2.equals(num)) {
344 fail("P2 event not expected.");
345 } else if (P3.equals(num)) {
346 assertEquals(PORT_REMOVED, event.type());
347 assertDevice(DID1, SW1, event.subject());
348 assertTrue("Port was enabled", event.port().isEnabled());
349 } else {
350 fail("Unknown port number encountered: " + num);
351 }
352 }
353
354 }
355
356 @Test
357 public final void testUpdatePortStatus() {
358 putDevice(DID1, SW1);
359 List<PortDescription> pds = Arrays.<PortDescription>asList(
360 new DefaultPortDescription(P1, true)
361 );
362 deviceStore.updatePorts(PID, DID1, pds);
363
364 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
365 new DefaultPortDescription(P1, false));
366 assertEquals(PORT_UPDATED, event.type());
367 assertDevice(DID1, SW1, event.subject());
368 assertEquals(P1, event.port().number());
369 assertFalse("Port is disabled", event.port().isEnabled());
370
371 }
372 @Test
373 public final void testUpdatePortStatusAncillary() {
374 putDeviceAncillary(DID1, SW1);
375 putDevice(DID1, SW1);
376 List<PortDescription> pds = Arrays.<PortDescription>asList(
377 new DefaultPortDescription(P1, true, A1)
378 );
379 deviceStore.updatePorts(PID, DID1, pds);
380
381 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
382 new DefaultPortDescription(P1, false, A1_2));
383 assertEquals(PORT_UPDATED, event.type());
384 assertDevice(DID1, SW1, event.subject());
385 assertEquals(P1, event.port().number());
386 assertAnnotationsEquals(event.port().annotations(), A1, A1_2);
387 assertFalse("Port is disabled", event.port().isEnabled());
388
389 DeviceEvent event2 = deviceStore.updatePortStatus(PIDA, DID1,
390 new DefaultPortDescription(P1, true));
391 assertNull("Ancillary is ignored if primary exists", event2);
392
393 // but, Ancillary annotation update will be notified
394 DeviceEvent event3 = deviceStore.updatePortStatus(PIDA, DID1,
395 new DefaultPortDescription(P1, true, A2));
396 assertEquals(PORT_UPDATED, event3.type());
397 assertDevice(DID1, SW1, event3.subject());
398 assertEquals(P1, event3.port().number());
399 assertAnnotationsEquals(event3.port().annotations(), A1, A1_2, A2);
400 assertFalse("Port is disabled", event3.port().isEnabled());
401
402 // port only reported from Ancillary will be notified as down
403 DeviceEvent event4 = deviceStore.updatePortStatus(PIDA, DID1,
404 new DefaultPortDescription(P2, true));
405 assertEquals(PORT_ADDED, event4.type());
406 assertDevice(DID1, SW1, event4.subject());
407 assertEquals(P2, event4.port().number());
408 assertAnnotationsEquals(event4.port().annotations());
409 assertFalse("Port is disabled if not given from primary provider",
410 event4.port().isEnabled());
411 }
412
413 @Test
414 public final void testGetPorts() {
415 putDevice(DID1, SW1);
416 putDevice(DID2, SW1);
417 List<PortDescription> pds = Arrays.<PortDescription>asList(
418 new DefaultPortDescription(P1, true),
419 new DefaultPortDescription(P2, true)
420 );
421 deviceStore.updatePorts(PID, DID1, pds);
422
423 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
424 List<Port> ports = deviceStore.getPorts(DID1);
425 for (Port port : ports) {
426 assertTrue("Port is enabled", port.isEnabled());
427 assertTrue("PortNumber is one of expected",
428 expectedPorts.remove(port.number()));
429 }
430 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
431
432
433 assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
434 }
435
436 @Test
437 public final void testGetPort() {
438 putDevice(DID1, SW1);
439 putDevice(DID2, SW1);
440 List<PortDescription> pds = Arrays.<PortDescription>asList(
441 new DefaultPortDescription(P1, true),
442 new DefaultPortDescription(P2, false)
443 );
444 deviceStore.updatePorts(PID, DID1, pds);
445
446 Port port1 = deviceStore.getPort(DID1, P1);
447 assertEquals(P1, port1.number());
448 assertTrue("Port is enabled", port1.isEnabled());
449
450 Port port2 = deviceStore.getPort(DID1, P2);
451 assertEquals(P2, port2.number());
452 assertFalse("Port is disabled", port2.isEnabled());
453
454 Port port3 = deviceStore.getPort(DID1, P3);
455 assertNull("P3 not expected", port3);
456 }
457
458 @Test
459 public final void testRemoveDevice() {
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700460 putDevice(DID1, SW1, A1);
461 List<PortDescription> pds = Arrays.<PortDescription>asList(
462 new DefaultPortDescription(P1, true, A2)
463 );
464 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700465 putDevice(DID2, SW1);
466
467 assertEquals(2, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700468 assertEquals(1, deviceStore.getPorts(DID1).size());
469 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations(), A1);
470 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations(), A2);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700471
472 DeviceEvent event = deviceStore.removeDevice(DID1);
473 assertEquals(DEVICE_REMOVED, event.type());
474 assertDevice(DID1, SW1, event.subject());
475
476 assertEquals(1, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700477 assertEquals(0, deviceStore.getPorts(DID1).size());
478
479 // putBack Device, Port w/o annotation
480 putDevice(DID1, SW1);
481 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
482 new DefaultPortDescription(P1, true)
483 );
484 deviceStore.updatePorts(PID, DID1, pds2);
485
486 // annotations should not survive
487 assertEquals(2, deviceStore.getDeviceCount());
488 assertEquals(1, deviceStore.getPorts(DID1).size());
489 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations());
490 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations());
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700491 }
492
493 // If Delegates should be called only on remote events,
494 // then Simple* should never call them, thus not test required.
495 // TODO add test for Port events when we have them
496 @Ignore("Ignore until Delegate spec. is clear.")
497 @Test
498 public final void testEvents() throws InterruptedException {
499 final CountDownLatch addLatch = new CountDownLatch(1);
500 DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
501 @Override
502 public void notify(DeviceEvent event) {
503 assertEquals(DEVICE_ADDED, event.type());
504 assertDevice(DID1, SW1, event.subject());
505 addLatch.countDown();
506 }
507 };
508 final CountDownLatch updateLatch = new CountDownLatch(1);
509 DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
510 @Override
511 public void notify(DeviceEvent event) {
512 assertEquals(DEVICE_UPDATED, event.type());
513 assertDevice(DID1, SW2, event.subject());
514 updateLatch.countDown();
515 }
516 };
517 final CountDownLatch removeLatch = new CountDownLatch(1);
518 DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
519 @Override
520 public void notify(DeviceEvent event) {
521 assertEquals(DEVICE_REMOVED, event.type());
522 assertDevice(DID1, SW2, event.subject());
523 removeLatch.countDown();
524 }
525 };
526
527 DeviceDescription description =
528 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
529 HW, SW1, SN);
530 deviceStore.setDelegate(checkAdd);
531 deviceStore.createOrUpdateDevice(PID, DID1, description);
532 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
533
534
535 DeviceDescription description2 =
536 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
537 HW, SW2, SN);
538 deviceStore.unsetDelegate(checkAdd);
539 deviceStore.setDelegate(checkUpdate);
540 deviceStore.createOrUpdateDevice(PID, DID1, description2);
541 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
542
543 deviceStore.unsetDelegate(checkUpdate);
544 deviceStore.setDelegate(checkRemove);
545 deviceStore.removeDevice(DID1);
546 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
547 }
548
549 private static final class TestGossipDeviceStore extends GossipDeviceStore {
550
Madan Jampani47c93732014-10-06 20:46:08 -0700551 public TestGossipDeviceStore(ClockService clockService, ClusterCommunicationService clusterCommunicator) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700552 this.clockService = clockService;
Madan Jampani47c93732014-10-06 20:46:08 -0700553 this.clusterCommunicator = clusterCommunicator;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700554 }
555 }
Madan Jampani47c93732014-10-06 20:46:08 -0700556
557 private static final class TestClusterCommunicationService implements ClusterCommunicationService {
558 @Override
559 public boolean broadcast(ClusterMessage message) throws IOException { return true; }
560 @Override
561 public boolean unicast(ClusterMessage message, NodeId nodeId) throws IOException { return true; }
562 @Override
563 public boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException { return true; }
564 @Override
565 public void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber) {}
566 }
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700567}