TopologyLinkDataChangeHandler implements DataTreeChangeListener<Link> { @Override public void onDataTreeChanged(Collection<DataTreeModification<Link>> changes) { boolean isGraphUpdated = false; for (DataTreeModification<Link> change: changes) { DataObjectModification<Link> rootNode = change.getRootNode(); switch (rootNode.getModificationType()) { case WRITE: Link createdLink = rootNode.getDataAfter(); if (rootNode.getDataBefore() == null && !createdLink.getLinkId().getValue().contains("host")) { isGraphUpdated = true; LOG.debug("Graph is updated! Added Link {}", createdLink.getLinkId().getValue()); } break; case DELETE: Link deletedLink = rootNode.getDataBefore(); if (!deletedLink.getLinkId().getValue().contains("host")) { isGraphUpdated = true; LOG.debug("Graph is updated! Removed Link {}", deletedLink.getLinkId().getValue()); break; } break; default: break; } } if (!isGraphUpdated) { return; } if (!networkGraphRefreshScheduled) { synchronized (this) { if (!networkGraphRefreshScheduled) { topologyDataChangeEventProcessor.schedule(new TopologyDataChangeEventProcessor(), graphRefreshDelay, TimeUnit.MILLISECONDS); networkGraphRefreshScheduled = true; LOG.debug("Scheduled Graph for refresh."); } } } else { LOG.debug("Already scheduled for network graph refresh."); threadReschedule = true; } } TopologyLinkDataChangeHandler(DataBroker dataBroker, NetworkGraphService networkGraphService); void setGraphRefreshDelay(long graphRefreshDelay); void setTopologyId(String topologyId); ListenerRegistration<TopologyLinkDataChangeHandler> registerAsDataChangeListener(); @Override void onDataTreeChanged(Collection<DataTreeModification<Link>> changes);  }
@SuppressWarnings("unchecked") @Test public void testOnDataChanged_CreatedDataNoRefresh() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link hostLink = new LinkBuilder().setLinkId(new LinkId("host:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataAfter()).thenReturn(hostLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(networkGraphService, times(0)).clear(); }
@SuppressWarnings("unchecked") @Test public void testOnDataChanged_CreatedDataRefresh() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link hostLink = new LinkBuilder().setLinkId(new LinkId("openflow:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataAfter()).thenReturn(hostLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(networkGraphService, times(1)).clear(); }
@SuppressWarnings("unchecked") @Test public void testOnDataChanged_RemovedDataNoRefresh() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link hostLink = new LinkBuilder().setLinkId(new LinkId("host:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataBefore()).thenReturn(hostLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(networkGraphService, times(0)).clear(); }
@SuppressWarnings("unchecked") @Test public void testOnDataChanged_RemovedDataRefresh() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link hostLink = new LinkBuilder().setLinkId(new LinkId("openflow:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataBefore()).thenReturn(hostLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(networkGraphService, times(1)).clear(); }
@SuppressWarnings("unchecked") @Test public void testUpdateNodeConnectorStatus_NoLinks() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link nodeLink = new LinkBuilder().setLinkId(new LinkId("openflow:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataAfter()).thenReturn(nodeLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); Topology topology = new TopologyBuilder().setLink(null).build(); Optional<Topology> topologyOptional = Optional.of(topology); CheckedFuture checkedFuture = Mockito.mock(CheckedFuture.class); when(checkedFuture.get()).thenReturn(topologyOptional); ReadOnlyTransaction readOnlyTransaction = Mockito.mock(ReadOnlyTransaction.class); when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))) .thenReturn(checkedFuture); when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(dataBroker, times(0)).newReadWriteTransaction(); verify(networkGraphService, times(0)).addLinks(any(List.class)); verify(networkGraphService, times(0)).getAllLinks(); verify(networkGraphService, times(0)).getLinksInMst(); }
@SuppressWarnings("unchecked") @Test public void testUpdateNodeConnectorStatus_WithLinks() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link nodeLink = new LinkBuilder().setLinkId(new LinkId("openflow:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataAfter()).thenReturn(nodeLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); List<Link> links = new ArrayList<>(); links.add(new LinkBuilder().setLinkId(new LinkId("openflow:1")).build()); Topology topology = new TopologyBuilder().setLink(links).build(); Optional<Topology> topologyOptional = Optional.of(topology); CheckedFuture checkedFuture = Mockito.mock(CheckedFuture.class); when(checkedFuture.get()).thenReturn(topologyOptional); ReadOnlyTransaction readOnlyTransaction = Mockito.mock(ReadOnlyTransaction.class); when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))) .thenReturn(checkedFuture); when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction); ReadWriteTransaction readWriteTransaction = Mockito.mock(ReadWriteTransaction.class); when(dataBroker.newReadWriteTransaction()).thenReturn(readWriteTransaction); Link link1 = new LinkBuilder().setLinkId(new LinkId("openflow:1")) .setSource(new SourceBuilder().setSourceNode(new NodeId("openflow:1")) .setSourceTp(new TpId("openflow:1")).build()) .setDestination(new DestinationBuilder().setDestNode(new NodeId("openflow:1")) .setDestTp(new TpId("openflow:1")).build()) .build(); Link link2 = new LinkBuilder().setLinkId(new LinkId("openflow:2")) .setSource(new SourceBuilder().setSourceNode(new NodeId("openflow:2")) .setSourceTp(new TpId("openflow:2")).build()) .setDestination(new DestinationBuilder().setDestNode(new NodeId("openflow:2")) .setDestTp(new TpId("openflow:2")).build()) .build(); List<Link> allLinks = new ArrayList<>(); allLinks.add(link1); allLinks.add(link2); when(networkGraphService.getAllLinks()).thenReturn(allLinks); List<Link> mstLinks = new ArrayList<>(); mstLinks.add(link1); when(networkGraphService.getLinksInMst()).thenReturn(mstLinks); NodeConnector nodeConnector = new NodeConnectorBuilder().build(); Optional<NodeConnector> optionalNodeConnector = Optional.of(nodeConnector); CheckedFuture checkedFutureNc = Mockito.mock(CheckedFuture.class); when(checkedFutureNc.get()).thenReturn(optionalNodeConnector); when(readWriteTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))) .thenReturn(checkedFutureNc); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(dataBroker, times(1)).newReadWriteTransaction(); verify(networkGraphService, times(1)).addLinks(any(ArrayList.class)); verify(networkGraphService, times(1)).getAllLinks(); verify(networkGraphService, times(1)).getLinksInMst(); verify(readWriteTransaction, times(4)).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(StpStatusAwareNodeConnector.class)); verify(readWriteTransaction, times(1)).submit(); }
@Test public void testUpdateNodeConnectorStatus_WithStpLinks() throws Exception { InstanceIdentifier<Link> instanceId = InstanceIdentifier.create(Link.class); Link nodeLink = new LinkBuilder().setLinkId(new LinkId("openflow:1")).build(); DataTreeModification<Link> mockChange = Mockito.mock(DataTreeModification.class); DataObjectModification<Link> mockModification = Mockito.mock(DataObjectModification.class); when(mockModification.getDataAfter()).thenReturn(nodeLink); when(mockModification.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); when(mockChange.getRootPath()).thenReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceId)); when(mockChange.getRootNode()).thenReturn(mockModification); List<Link> links = new ArrayList<>(); links.add(new LinkBuilder().setLinkId(new LinkId("openflow:1")).build()); Topology topology = new TopologyBuilder().setLink(links).build(); Optional<Topology> topologyOptional = Optional.of(topology); CheckedFuture checkedFuture = Mockito.mock(CheckedFuture.class); when(checkedFuture.get()).thenReturn(topologyOptional); ReadOnlyTransaction readOnlyTransaction = Mockito.mock(ReadOnlyTransaction.class); when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))) .thenReturn(checkedFuture); when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction); ReadWriteTransaction readWriteTransaction = Mockito.mock(ReadWriteTransaction.class); when(dataBroker.newReadWriteTransaction()).thenReturn(readWriteTransaction); Link link1 = new LinkBuilder().setLinkId(new LinkId("openflow:1")) .setSource(new SourceBuilder().setSourceNode(new NodeId("openflow:1")) .setSourceTp(new TpId("openflow:1")).build()) .setDestination(new DestinationBuilder().setDestNode(new NodeId("openflow:1")) .setDestTp(new TpId("openflow:1")).build()) .build(); Link link2 = new LinkBuilder().setLinkId(new LinkId("openflow:2")) .setSource(new SourceBuilder().setSourceNode(new NodeId("openflow:2")) .setSourceTp(new TpId("openflow:2")).build()) .setDestination(new DestinationBuilder().setDestNode(new NodeId("openflow:2")) .setDestTp(new TpId("openflow:2")).build()) .build(); List<Link> allLinks = new ArrayList<>(); allLinks.add(link1); allLinks.add(link2); when(networkGraphService.getAllLinks()).thenReturn(allLinks); List<Link> mstLinks = new ArrayList<>(); mstLinks.add(link1); when(networkGraphService.getLinksInMst()).thenReturn(mstLinks); StpStatusAwareNodeConnector stpStatusAwareNodeConnector = new StpStatusAwareNodeConnectorBuilder() .setStatus(StpStatus.Forwarding).build(); NodeConnector nodeConnector = new NodeConnectorBuilder() .addAugmentation(StpStatusAwareNodeConnector.class, stpStatusAwareNodeConnector).build(); Optional<NodeConnector> optionalNodeConnector = Optional.of(nodeConnector); CheckedFuture checkedFutureNc = Mockito.mock(CheckedFuture.class); when(checkedFutureNc.get()).thenReturn(optionalNodeConnector); when(readWriteTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))) .thenReturn(checkedFutureNc); topologyLinkDataChangeHandler.onDataTreeChanged(Collections.singletonList(mockChange)); Thread.sleep(500); verify(dataBroker, times(1)).newReadWriteTransaction(); verify(networkGraphService, times(1)).addLinks(any(ArrayList.class)); verify(networkGraphService, times(1)).getAllLinks(); verify(networkGraphService, times(1)).getLinksInMst(); verify(readWriteTransaction, times(2)).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(StpStatusAwareNodeConnector.class)); verify(readWriteTransaction, times(1)).submit(); }