ReachableSocketFinder { public HostAndPort findOpenSocketOnNode(final Iterable<? extends HostAndPort> sockets, Duration timeout) { checkNotNull(sockets, "sockets"); checkState(!Iterables.isEmpty(sockets), "No hostAndPort sockets supplied"); checkNotNull(timeout, "timeout"); Iterable<HostAndPort> reachable = Optional.presentInstances(tryReachable(sockets, timeout, false)); Iterator<HostAndPort> iter = reachable.iterator(); if (iter.hasNext()) { return iter.next(); } else { LOG.warn("No sockets in {} reachable after {}", sockets, timeout); throw new NoSuchElementException("Could not connect to any socket in " + sockets); } } ReachableSocketFinder();  ReachableSocketFinder(Predicate<? super HostAndPort> socketTester);  ReachableSocketFinder(Predicate<? super HostAndPort> socketTester, Duration gracePeriod); HostAndPort findOpenSocketOnNode(final Iterable<? extends HostAndPort> sockets, Duration timeout); Iterable<HostAndPort> findOpenSocketsOnNode(final Iterable<? extends HostAndPort> sockets, Duration timeout);  }
@Test(expectedExceptions=IllegalStateException.class) public void testFindWhenNoSocketsThrowsIllegalState() throws Exception { finder.findOpenSocketOnNode(ImmutableList.<HostAndPort>of(), TIMEOUT); }
@Test public void testReturnsReachableSocket() throws Exception { reachabilityResults.put(socket1, true); reachabilityResults.put(socket2, false); assertEquals(finder.findOpenSocketOnNode(ImmutableList.of(socket1, socket2), TIMEOUT), socket1); reachabilityResults.put(socket1, false); reachabilityResults.put(socket2, true); assertEquals(finder.findOpenSocketOnNode(ImmutableList.of(socket1, socket2), TIMEOUT), socket2); }
@Test public void testPollsUntilPortReachable() throws Exception { reachabilityResults.put(socket1, false); reachabilityResults.put(socket2, false); final ListenableFuture<HostAndPort> future = executor.submit(new Callable<HostAndPort>() { @Override public HostAndPort call() throws Exception { return finder.findOpenSocketOnNode(ImmutableList.of(socket1, socket2), TIMEOUT); }}); Asserts.succeedsContinually(ImmutableMap.of("timeout", SHORT_WAIT), new Runnable() { @Override public void run() { assertFalse(future.isDone()); }}); reachabilityResults.put(socket1, true); assertEquals(future.get(), socket1); }
@Test(groups="Integration") public void testReturnsRealReachableSocket() throws Exception { ReachableSocketFinder realFinder = new ReachableSocketFinder(); ServerSocket socket = connectToPort(); try { HostAndPort addr = HostAndPort.fromParts(socket.getInetAddress().getHostAddress(), socket.getLocalPort()); HostAndPort wrongAddr = HostAndPort.fromParts(socket.getInetAddress().getHostAddress(), findAvailablePort()); assertEquals(realFinder.findOpenSocketOnNode(ImmutableList.of(addr, wrongAddr), TIMEOUT), addr); } finally { if (socket != null) { socket.close(); } } }
@Test(groups="Integration") public void testFailsIfRealSocketUnreachable() throws Exception { ReachableSocketFinder realFinder = new ReachableSocketFinder(); HostAndPort wrongAddr = HostAndPort.fromParts(Networking.getReachableLocalHost().getHostAddress(), findAvailablePort()); try { HostAndPort result = realFinder.findOpenSocketOnNode(ImmutableList.of(wrongAddr), Duration.FIVE_SECONDS); fail("Expected failure, but got "+result); } catch (NoSuchElementException e) { } }