@Test public final void testMarkOffline() { putDevice(DID1, SW1); assertTrue(deviceStore.isAvailable(DID1)); Capture<InternalDeviceEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalDeviceEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event = deviceStore.markOffline(DID1); assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type()); assertDevice(DID1, SW1, event.subject()); assertFalse(deviceStore.isAvailable(DID1)); verify(clusterCommunicator); // TODO: verify broadcast message assertTrue(message.hasCaptured()); resetCommunicatorExpectingNoBroadcast(message, subject, encoder); DeviceEvent event2 = deviceStore.markOffline(DID1); assertNull("No change, no event", event2); verify(clusterCommunicator); assertFalse(message.hasCaptured()); }
@Override public void event(DeviceEvent event) { Device device = event.subject(); switch (event.type()) { case DEVICE_ADDED: break; case DEVICE_AVAILABILITY_CHANGED: if (hostRemovalEnabled && !deviceService.isAvailable(device.id())) { removeHosts(hostService.getConnectedHosts(device.id())); } break; case DEVICE_SUSPENDED: case DEVICE_UPDATED: // Nothing to do? break; case DEVICE_REMOVED: if (hostRemovalEnabled) { removeHosts(hostService.getConnectedHosts(device.id())); } break; case PORT_ADDED: break; case PORT_UPDATED: if (hostRemovalEnabled) { ConnectPoint point = new ConnectPoint(device.id(), event.port().number()); removeHosts(hostService.getConnectedHosts(point)); } break; case PORT_REMOVED: // Nothing to do? break; default: break; } }
@Override public void event(DeviceEvent event) { DeviceEvent.Type type = event.type(); switch (type) { case DEVICE_ADDED: case DEVICE_AVAILABILITY_CHANGED: case DEVICE_REMOVED: case DEVICE_SUSPENDED: case DEVICE_UPDATED: DeviceId id = event.subject().id(); // TODO we need to check whether AVAILABILITY_CHANGED means up or down boolean available = (type == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || type == DeviceEvent.Type.DEVICE_ADDED || type == DeviceEvent.Type.DEVICE_UPDATED); executorService.execute(new DeviceAvailabilityHandler(id, available)); break; case PORT_ADDED: case PORT_REMOVED: case PORT_UPDATED: case PORT_STATS_UPDATED: default: // Don't handle port events for now break; } }
@Override public void event(DeviceEvent event) { DeviceEvent.Type type = event.type(); if (type == DEVICE_ADDED || type == DEVICE_AVAILABILITY_CHANGED) { deviceLatch.countDown(); } }
@Test public final void testRemoveDevice() { putDevice(DID1, SW1, A1); List<PortDescription> pds = Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true, A2)); deviceStore.updatePorts(PID, DID1, pds); putDevice(DID2, SW1); assertEquals(2, deviceStore.getDeviceCount()); assertEquals(1, deviceStore.getPorts(DID1).size()); assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations(), A1); assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations(), A2); Capture<InternalDeviceEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalDeviceEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event = deviceStore.removeDevice(DID1); assertEquals(DEVICE_REMOVED, event.type()); assertDevice(DID1, SW1, event.subject()); assertEquals(1, deviceStore.getDeviceCount()); assertEquals(0, deviceStore.getPorts(DID1).size()); verify(clusterCommunicator); // TODO: verify broadcast message assertTrue(message.hasCaptured()); // putBack Device, Port w/o annotation putDevice(DID1, SW1); List<PortDescription> pds2 = Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true)); deviceStore.updatePorts(PID, DID1, pds2); // annotations should not survive assertEquals(2, deviceStore.getDeviceCount()); assertEquals(1, deviceStore.getPorts(DID1).size()); assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations()); assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations()); }
@Test public final void testCreateOrUpdateDevice() throws IOException { DeviceDescription description = new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, HW, SW1, SN, CID); Capture<InternalDeviceEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalDeviceEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description); assertEquals(DEVICE_ADDED, event.type()); assertDevice(DID1, SW1, event.subject()); verify(clusterCommunicator); assertInternalDeviceEvent(NID1, DID1, PID, description, message, subject, encoder); DeviceDescription description2 = new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, HW, SW2, SN, CID); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2); assertEquals(DEVICE_UPDATED, event2.type()); assertDevice(DID1, SW2, event2.subject()); verify(clusterCommunicator); assertInternalDeviceEvent(NID1, DID1, PID, description2, message, subject, encoder); reset(clusterCommunicator); assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2)); }
@Test public final void testUpdatePortStatus() { putDevice(DID1, SW1); List<PortDescription> pds = Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true)); deviceStore.updatePorts(PID, DID1, pds); Capture<InternalPortStatusEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalPortStatusEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); final DefaultPortDescription desc = new DefaultPortDescription(P1, false); DeviceEvent event = deviceStore.updatePortStatus(PID, DID1, desc); assertEquals(PORT_UPDATED, event.type()); assertDevice(DID1, SW1, event.subject()); assertEquals(P1, event.port().number()); assertFalse("Port is disabled", event.port().isEnabled()); verify(clusterCommunicator); assertInternalPortStatusEvent(NID1, DID1, PID, desc, NO_ANNOTATION, message, subject, encoder); assertTrue(message.hasCaptured()); }
@Override public void event(DeviceEvent event) { switch (event.type()) { case DEVICE_REMOVED: case DEVICE_AVAILABILITY_CHANGED: DeviceId deviceId = event.subject().id(); if (!deviceService.isAvailable(deviceId)) { log.debug( "Device {} became un available; clearing initial audit status", event.type(), event.subject().id()); store.deviceInitialAuditCompleted(event.subject().id(), false); if (purgeOnDisconnection) { store.purgeGroupEntry(deviceId); } } break; default: break; } }
@Override public void run() { if (doNotPushFlows) { return; } switch (deviceEvent.type()) { case DEVICE_ADDED: processDeviceAdded((Device) deviceEvent.subject()); break; case DEVICE_UPDATED: Port port = (Port) deviceEvent.subject(); if (port.isEnabled()) { processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); } break; case DEVICE_AVAILABILITY_CHANGED: Device device = (Device) deviceEvent.subject(); if (deviceService.isAvailable(device.id())) { processDeviceAdded(device); } break; case PORT_ADDED: processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); break; case PORT_UPDATED: processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); break; case PORT_REMOVED: processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); break; default: break; } }
private void printEvent(Event<?, ?> event) { if (event instanceof DeviceEvent) { DeviceEvent deviceEvent = (DeviceEvent) event; if (event.type().toString().startsWith("PORT")) { // Port event print( "%s %s\t%s/%s [%s]", new LocalDateTime(event.time()), event.type(), deviceEvent.subject().id(), deviceEvent.port().number(), deviceEvent.port()); } else { // Device event print( "%s %s\t%s [%s]", new LocalDateTime(event.time()), event.type(), deviceEvent.subject().id(), deviceEvent.subject()); } } else if (event instanceof MastershipEvent) { print( "%s %s\t%s [%s]", new LocalDateTime(event.time()), event.type(), event.subject(), ((MastershipEvent) event).roleInfo()); } else if (event instanceof LinkEvent) { LinkEvent linkEvent = (LinkEvent) event; Link link = linkEvent.subject(); print( "%s %s\t%s/%s-%s/%s [%s]", new LocalDateTime(event.time()), event.type(), link.src().deviceId(), link.src().port(), link.dst().deviceId(), link.dst().port(), link); } else if (event instanceof HostEvent) { HostEvent hostEvent = (HostEvent) event; print( "%s %s\t%s [%s->%s]", new LocalDateTime(event.time()), event.type(), hostEvent.subject().id(), hostEvent.prevSubject(), hostEvent.subject()); } else if (event instanceof TopologyEvent) { TopologyEvent topoEvent = (TopologyEvent) event; List<Event> reasons = MoreObjects.firstNonNull(topoEvent.reasons(), ImmutableList.<Event>of()); Topology topo = topoEvent.subject(); String summary = String.format( "(d=%d,l=%d,c=%d)", topo.deviceCount(), topo.linkCount(), topo.clusterCount()); print( "%s %s%s [%s]", new LocalDateTime(event.time()), event.type(), summary, reasons.stream().map(e -> e.type()).collect(toList())); } else if (event instanceof ClusterEvent) { print( "%s %s\t%s [%s]", new LocalDateTime(event.time()), event.type(), ((ClusterEvent) event).subject().id(), event.subject()); } else { // Unknown Event? print( "%s %s\t%s [%s]", new LocalDateTime(event.time()), event.type(), event.subject(), event); } }
@Test public final void testUpdatePortStatusAncillary() throws IOException { putDeviceAncillary(DID1, SW1); putDevice(DID1, SW1); List<PortDescription> pds = Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true, A1)); deviceStore.updatePorts(PID, DID1, pds); Capture<InternalPortStatusEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalPortStatusEvent, byte[]>> encoder = new Capture<>(); // update port from primary resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); final DefaultPortDescription desc1 = new DefaultPortDescription(P1, false, A1_2); DeviceEvent event = deviceStore.updatePortStatus(PID, DID1, desc1); assertEquals(PORT_UPDATED, event.type()); assertDevice(DID1, SW1, event.subject()); assertEquals(P1, event.port().number()); assertAnnotationsEquals(event.port().annotations(), A1, A1_2); assertFalse("Port is disabled", event.port().isEnabled()); verify(clusterCommunicator); assertInternalPortStatusEvent( NID1, DID1, PID, desc1, asList(A1, A1_2), message, subject, encoder); assertTrue(message.hasCaptured()); // update port from ancillary with no attributes resetCommunicatorExpectingNoBroadcast(message, subject, encoder); final DefaultPortDescription desc2 = new DefaultPortDescription(P1, true); DeviceEvent event2 = deviceStore.updatePortStatus(PIDA, DID1, desc2); assertNull("Ancillary is ignored if primary exists", event2); verify(clusterCommunicator); assertFalse(message.hasCaptured()); // but, Ancillary annotation update will be notified resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); final DefaultPortDescription desc3 = new DefaultPortDescription(P1, true, A2); DeviceEvent event3 = deviceStore.updatePortStatus(PIDA, DID1, desc3); assertEquals(PORT_UPDATED, event3.type()); assertDevice(DID1, SW1, event3.subject()); assertEquals(P1, event3.port().number()); assertAnnotationsEquals(event3.port().annotations(), A1, A1_2, A2); assertFalse("Port is disabled", event3.port().isEnabled()); verify(clusterCommunicator); assertInternalPortStatusEvent(NID1, DID1, PIDA, desc3, asList(A2), message, subject, encoder); assertTrue(message.hasCaptured()); // port only reported from Ancillary will be notified as down resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); final DefaultPortDescription desc4 = new DefaultPortDescription(P2, true); DeviceEvent event4 = deviceStore.updatePortStatus(PIDA, DID1, desc4); assertEquals(PORT_ADDED, event4.type()); assertDevice(DID1, SW1, event4.subject()); assertEquals(P2, event4.port().number()); assertAnnotationsEquals(event4.port().annotations()); assertFalse("Port is disabled if not given from primary provider", event4.port().isEnabled()); verify(clusterCommunicator); // TODO: verify broadcast message content assertInternalPortStatusEvent( NID1, DID1, PIDA, desc4, NO_ANNOTATION, message, subject, encoder); assertTrue(message.hasCaptured()); }
@Test public final void testUpdatePorts() { putDevice(DID1, SW1); List<PortDescription> pds = Arrays.<PortDescription>asList( new DefaultPortDescription(P1, true), new DefaultPortDescription(P2, true)); Capture<InternalDeviceEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalDeviceEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds); verify(clusterCommunicator); // TODO: verify broadcast message assertTrue(message.hasCaptured()); Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2); for (DeviceEvent event : events) { assertEquals(PORT_ADDED, event.type()); assertDevice(DID1, SW1, event.subject()); assertTrue("PortNumber is one of expected", expectedPorts.remove(event.port().number())); assertTrue("Port is enabled", event.port().isEnabled()); } assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty()); List<PortDescription> pds2 = Arrays.<PortDescription>asList( new DefaultPortDescription(P1, false), new DefaultPortDescription(P2, true), new DefaultPortDescription(P3, true)); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); events = deviceStore.updatePorts(PID, DID1, pds2); verify(clusterCommunicator); // TODO: verify broadcast message assertTrue(message.hasCaptured()); assertFalse("event should be triggered", events.isEmpty()); for (DeviceEvent event : events) { PortNumber num = event.port().number(); if (P1.equals(num)) { assertEquals(PORT_UPDATED, event.type()); assertDevice(DID1, SW1, event.subject()); assertFalse("Port is disabled", event.port().isEnabled()); } else if (P2.equals(num)) { fail("P2 event not expected."); } else if (P3.equals(num)) { assertEquals(PORT_ADDED, event.type()); assertDevice(DID1, SW1, event.subject()); assertTrue("Port is enabled", event.port().isEnabled()); } else { fail("Unknown port number encountered: " + num); } } List<PortDescription> pds3 = Arrays.<PortDescription>asList( new DefaultPortDescription(P1, false), new DefaultPortDescription(P2, true)); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); events = deviceStore.updatePorts(PID, DID1, pds3); verify(clusterCommunicator); // TODO: verify broadcast message assertTrue(message.hasCaptured()); assertFalse("event should be triggered", events.isEmpty()); for (DeviceEvent event : events) { PortNumber num = event.port().number(); if (P1.equals(num)) { fail("P1 event not expected."); } else if (P2.equals(num)) { fail("P2 event not expected."); } else if (P3.equals(num)) { assertEquals(PORT_REMOVED, event.type()); assertDevice(DID1, SW1, event.subject()); assertTrue("Port was enabled", event.port().isEnabled()); } else { fail("Unknown port number encountered: " + num); } } }
@Test public final void testCreateOrUpdateDeviceAncillary() throws IOException { // add DeviceDescription description = new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, HW, SW1, SN, CID, A2); Capture<ClusterMessage> bcast = new Capture<>(); Capture<InternalDeviceEvent> message = new Capture<>(); Capture<MessageSubject> subject = new Capture<>(); Capture<Function<InternalDeviceEvent, byte[]>> encoder = new Capture<>(); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event = deviceStore.createOrUpdateDevice(PIDA, DID1, description); assertEquals(DEVICE_ADDED, event.type()); assertDevice(DID1, SW1, event.subject()); assertEquals(PIDA, event.subject().providerId()); assertAnnotationsEquals(event.subject().annotations(), A2); assertFalse("Ancillary will not bring device up", deviceStore.isAvailable(DID1)); verify(clusterCommunicator); assertInternalDeviceEvent(NID1, DID1, PIDA, description, message, subject, encoder); // update from primary DeviceDescription description2 = new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, HW, SW2, SN, CID, A1); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2); assertEquals(DEVICE_UPDATED, event2.type()); assertDevice(DID1, SW2, event2.subject()); assertEquals(PID, event2.subject().providerId()); assertAnnotationsEquals(event2.subject().annotations(), A1, A2); assertTrue(deviceStore.isAvailable(DID1)); verify(clusterCommunicator); assertInternalDeviceEvent(NID1, DID1, PID, description2, message, subject, encoder); // no-op update from primary resetCommunicatorExpectingNoBroadcast(message, subject, encoder); assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2)); verify(clusterCommunicator); assertFalse("no broadcast expected", bcast.hasCaptured()); // For now, Ancillary is ignored once primary appears resetCommunicatorExpectingNoBroadcast(message, subject, encoder); assertNull("No change expected", deviceStore.createOrUpdateDevice(PIDA, DID1, description)); verify(clusterCommunicator); assertFalse("no broadcast expected", bcast.hasCaptured()); // But, Ancillary annotations will be in effect DeviceDescription description3 = new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, HW, SW1, SN, CID, A2_2); resetCommunicatorExpectingSingleBroadcast(message, subject, encoder); DeviceEvent event3 = deviceStore.createOrUpdateDevice(PIDA, DID1, description3); assertEquals(DEVICE_UPDATED, event3.type()); // basic information will be the one from Primary assertDevice(DID1, SW2, event3.subject()); assertEquals(PID, event3.subject().providerId()); // but annotation from Ancillary will be merged assertAnnotationsEquals(event3.subject().annotations(), A1, A2, A2_2); assertTrue(deviceStore.isAvailable(DID1)); verify(clusterCommunicator); // note: only annotation from PIDA is sent over the wire assertInternalDeviceEvent( NID1, DID1, PIDA, description3, asList(union(A2, A2_2)), message, subject, encoder); }