TerrapinRoutingTableProvider extends RoutingTableProvider { @VisibleForTesting public void updateExternalView(List<ExternalView> externalViewList) { Set<String> resourceSet = Sets.newHashSetWithExpectedSize(externalViewList.size()); synchronized (viewInfoRecordMap) { for (ExternalView externalView : externalViewList) { if (externalView == null) { continue; } String resource = externalView.getResourceName(); resourceSet.add(resource); ViewInfoRecord record = viewInfoRecordMap.get(resource); ViewInfoRecord newRecord = new ViewInfoRecord(); newRecord.viewInfo = new ViewInfo(externalView); if (record != null) { if (newRecord.viewInfo.equals(record.viewInfo)) continue; } newRecord.drained = false; viewInfoRecordMap.put(resource, newRecord); } Set<String> resourcesToRemove = Sets.newHashSetWithExpectedSize(viewInfoRecordMap.size()); for (String resource : viewInfoRecordMap.keySet()) { if (!resourceSet.contains(resource)) { resourcesToRemove.add(resource); } } for (String resource : resourcesToRemove) { this.viewInfoRecordMap.remove(resource); } } } TerrapinRoutingTableProvider(ZooKeeperManager zkManager,
                                      List<String> resourceList); void start(); @VisibleForTesting void updateExternalView(List<ExternalView> externalViewList); @Override void onExternalViewChange(List<ExternalView> externalViewList,
                                   NotificationContext context); void shutdown();  }
@Test public void testUpdateExternalView() { ZooKeeperManager zkManager = mock(ZooKeeperManager.class); ExternalView ev1 = mock(ExternalView.class); ExternalView ev2 = mock(ExternalView.class); ExternalView ev3 = mock(ExternalView.class); when(ev1.getPartitionSet()).thenReturn(Sets.newHashSet("p$0", "p$1")); when(ev2.getPartitionSet()).thenReturn(Sets.newHashSet("p$1", "p$2")); when(ev3.getPartitionSet()).thenReturn(Sets.newHashSet("p$0", "p$2")); when(ev1.getStateMap(eq("p$0"))).thenReturn(ImmutableMap.of("p$0", "ONLINE")); when(ev1.getStateMap(eq("p$1"))).thenReturn(ImmutableMap.of("p$1", "ONLINE")); when(ev2.getStateMap(eq("p$1"))).thenReturn(ImmutableMap.of("p$1", "ONLINE")); when(ev2.getStateMap(eq("p$2"))).thenReturn(ImmutableMap.of("p$2", "ONLINE")); when(ev3.getStateMap(eq("p$0"))).thenReturn(ImmutableMap.of("p$0", "ONLINE")); when(ev3.getStateMap(eq("p$2"))).thenReturn(ImmutableMap.of("p$2", "ONLINE")); when(ev1.getResourceName()).thenReturn("r1"); when(ev2.getResourceName()).thenReturn("r2"); when(ev3.getResourceName()).thenReturn("r3"); ViewInfo v1 = new ViewInfo(ev1); ViewInfo v2 = new ViewInfo(ev2); when(zkManager.getViewInfo(eq("r1"))).thenReturn(v1); when(zkManager.getViewInfo(eq("r2"))).thenReturn(v2); TerrapinRoutingTableProvider provider = new TerrapinRoutingTableProvider(zkManager, ImmutableList.of("r1", "r2")); Map<String, TerrapinRoutingTableProvider.ViewInfoRecord> viewInfoRecordMap = Whitebox.getInternalState(provider, "viewInfoRecordMap"); viewInfoRecordMap.get("r1").drained = true; viewInfoRecordMap.get("r2").drained = true; provider.updateExternalView(ImmutableList.of(ev2, ev3)); viewInfoRecordMap = Whitebox.getInternalState(provider, "viewInfoRecordMap"); assertEquals(2, viewInfoRecordMap.size()); assertTrue(viewInfoRecordMap.containsKey("r2")); assertTrue(viewInfoRecordMap.containsKey("r3")); assertTrue(viewInfoRecordMap.get("r2").drained); assertFalse(viewInfoRecordMap.get("r3").drained); assertEquals(v2, viewInfoRecordMap.get("r2").viewInfo); assertEquals(new ViewInfo(ev3), viewInfoRecordMap.get("r3").viewInfo); }