RequestHedgingProxyProvider extends
        ConfiguredFailoverProxyProvider<T> { @Override public synchronized void performFailover(T currentProxy) { toIgnore = ((RequestHedgingInvocationHandler) Proxy.getInvocationHandler( currentUsedHandler.proxy)).currentUsedProxy.proxyInfo; this.currentUsedHandler = null; } RequestHedgingProxyProvider(Configuration conf, URI uri,
      Class<T> xface, HAProxyFactory<T> proxyFactory); @SuppressWarnings("unchecked") @Override synchronized ProxyInfo<T> getProxy(); @Override synchronized void performFailover(T currentProxy); static final Logger LOG; }
@Test public void testPerformFailover() throws Exception { final AtomicInteger counter = new AtomicInteger(0); final int[] isGood = {1}; final ClientProtocol goodMock = Mockito.mock(ClientProtocol.class); Mockito.when(goodMock.getStats()).thenAnswer(new Answer<long[]>() { @Override public long[] answer(InvocationOnMock invocation) throws Throwable { counter.incrementAndGet(); if (isGood[0] == 1) { Thread.sleep(1000); return new long[]{1}; } throw new IOException("Was Good mock !!"); } }); final ClientProtocol badMock = Mockito.mock(ClientProtocol.class); Mockito.when(badMock.getStats()).thenAnswer(new Answer<long[]>() { @Override public long[] answer(InvocationOnMock invocation) throws Throwable { counter.incrementAndGet(); if (isGood[0] == 2) { Thread.sleep(1000); return new long[]{2}; } throw new IOException("Bad mock !!"); } }); RequestHedgingProxyProvider<ClientProtocol> provider = new RequestHedgingProxyProvider<>(conf, nnUri, ClientProtocol.class, createFactory(goodMock, badMock)); long[] stats = provider.getProxy().proxy.getStats(); Assert.assertTrue(stats.length == 1); Assert.assertEquals(1, stats[0]); Assert.assertEquals(2, counter.get()); Mockito.verify(badMock).getStats(); Mockito.verify(goodMock).getStats(); stats = provider.getProxy().proxy.getStats(); Assert.assertTrue(stats.length == 1); Assert.assertEquals(1, stats[0]); Mockito.verifyNoMoreInteractions(badMock); Assert.assertEquals(3, counter.get()); isGood[0] = 2; try { provider.getProxy().proxy.getStats(); Assert.fail("Should fail since previously successful proxy now fails "); } catch (Exception ex) { Assert.assertTrue(ex instanceof IOException); } Assert.assertEquals(4, counter.get()); provider.performFailover(provider.getProxy().proxy); stats = provider.getProxy().proxy.getStats(); Assert.assertTrue(stats.length == 1); Assert.assertEquals(2, stats[0]); Assert.assertEquals(5, counter.get()); stats = provider.getProxy().proxy.getStats(); Assert.assertTrue(stats.length == 1); Assert.assertEquals(2, stats[0]); Assert.assertEquals(6, counter.get()); isGood[0] = 1; try { provider.getProxy().proxy.getStats(); Assert.fail("Should fail since previously successful proxy now fails "); } catch (Exception ex) { Assert.assertTrue(ex instanceof IOException); } Assert.assertEquals(7, counter.get()); provider.performFailover(provider.getProxy().proxy); stats = provider.getProxy().proxy.getStats(); Assert.assertTrue(stats.length == 1); Assert.assertEquals(1, stats[0]); }