@Override public HostAndPort findOpenSocketOnNode(NodeMetadata node, final int port, long timeout, TimeUnit timeUnits) { ImmutableSet<HostAndPort> sockets = checkNodeHasIps(node).transform(new Function<String, HostAndPort>() { @Override public HostAndPort apply(String from) { return HostAndPort.fromParts(from, port); } }).toSet(); // Specify a retry period of 1s, expressed in the same time units. long period = timeUnits.convert(1, TimeUnit.SECONDS); // For retrieving the socket found (if any) AtomicReference<HostAndPort> result = newReference(); Predicate<Iterable<HostAndPort>> findOrBreak = or(updateRefOnSocketOpen(result), throwISEIfNoLongerRunning(node)); logger.debug(">> blocking on sockets %s for %d %s", sockets, timeout, timeUnits); boolean passed = retryPredicate(findOrBreak, timeout, period, timeUnits).apply(sockets); if (passed) { logger.debug("<< socket %s opened", result); assert result.get() != null; return result.get(); } else { logger.warn("<< sockets %s didn't open after %d %s", sockets, timeout, timeUnits); throw new NoSuchElementException(format("could not connect to any ip address port %d on node %s", port, node)); } }
@Test public void testReturnsReachable() throws Exception { SocketOpen secondSocketOpen = new SocketOpen() { @Override public boolean apply(HostAndPort input) { return HostAndPort.fromParts("1.2.3.5", 22).equals(input); } }; OpenSocketFinder finder = new ConcurrentOpenSocketFinder(secondSocketOpen, nodeRunning, userExecutor); HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); assertEquals(result, HostAndPort.fromParts("1.2.3.5", 22)); }
@Test public void testSocketFinderAllowedInterfacesAll() throws Exception { FluentIterable<String> ips = ConcurrentOpenSocketFinder.checkNodeHasIps(node, AllowedInterfaces.ALL); assertTrue(ips.contains(PUBLIC_IP)); assertTrue(ips.contains(PRIVATE_IP)); }
@Test public void testSocketFinderAllowedInterfacesPrivate() throws Exception { FluentIterable<String> ips = ConcurrentOpenSocketFinder.checkNodeHasIps(node, AllowedInterfaces.PRIVATE); assertFalse(ips.contains(PUBLIC_IP)); assertTrue(ips.contains(PRIVATE_IP)); }
@Override public HostAndPort findOpenSocketOnNode(NodeMetadata node, final int port, long timeout, TimeUnit timeUnits) { ImmutableSet<HostAndPort> sockets = checkNodeHasIps(node).transform(new Function<String, HostAndPort>() { @Override public HostAndPort apply(String from) { return HostAndPort.fromParts(from, port); } }).toSet(); // Specify a retry period of 1s, expressed in the same time units. long period = timeUnits.convert(1, TimeUnit.SECONDS); // For retrieving the socket found (if any) AtomicReference<HostAndPort> result = newReference(); Predicate<Iterable<HostAndPort>> findOrBreak = or(updateRefOnSocketOpen(result), throwISEIfNoLongerRunning(node)); logger.debug(">> blocking on sockets %s for %d %s", sockets, timeout, timeUnits); boolean passed = retryPredicate(findOrBreak, timeout, period, timeUnits).apply(sockets); if (passed) { logger.debug("<< socket %s opened", result); assert result.get() != null; return result.get(); } else { logger.warn("<< sockets %s didn't open after %d %s", sockets, timeout, timeUnits); throw new NoSuchElementException(format("could not connect to any ip address port %d on node %s", port, node)); } }
@Test public void testSocketFinderAllowedInterfacesPublic() throws Exception { FluentIterable<String> ips = ConcurrentOpenSocketFinder.checkNodeHasIps(node, AllowedInterfaces.PUBLIC); assertTrue(ips.contains(PUBLIC_IP)); assertFalse(ips.contains(PRIVATE_IP)); }
@Test public void testReturnsReachable() throws Exception { SocketOpen secondSocketOpen = new SocketOpen() { @Override public boolean apply(HostAndPort input) { return HostAndPort.fromParts(PRIVATE_IP, 22).equals(input); } }; OpenSocketFinder finder = new ConcurrentOpenSocketFinder(secondSocketOpen, nodeRunning, userExecutor); HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); assertEquals(result, HostAndPort.fromParts(PRIVATE_IP, 22)); }
@Override public HostAndPort findOpenSocketOnNode(NodeMetadata node, final int port, long timeout, TimeUnit timeUnits) { ImmutableSet<HostAndPort> sockets = checkNodeHasIps(node, allowedInterfaces).transform(new Function<String, HostAndPort>() { @Override public HostAndPort apply(String from) { return HostAndPort.fromParts(from, port); } }).toSet(); // Specify a retry period of 1s, expressed in the same time units. long period = timeUnits.convert(1, TimeUnit.SECONDS); // For retrieving the socket found (if any) AtomicReference<HostAndPort> result = newReference(); Predicate<Iterable<HostAndPort>> findOrBreak = or(updateRefOnSocketOpen(result), throwISEIfNoLongerRunning(node)); logger.debug(">> blocking on sockets %s for %d %s", sockets, timeout, timeUnits); boolean passed = retryPredicate(findOrBreak, timeout, period, timeUnits).apply(sockets); if (passed) { logger.debug("<< socket %s opened", result); assert result.get() != null; return result.get(); } else { logger.warn("<< sockets %s didn't open after %d %s", sockets, timeout, timeUnits); throw new NoSuchElementException(format("could not connect to any ip address port %d on node %s", port, node)); } }
@Test public void testRespectsTimeout() throws Exception { final long timeoutMs = 1000; OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeRunning, userExecutor); Stopwatch stopwatch = new Stopwatch(); stopwatch.start(); try { finder.findOpenSocketOnNode(node, 22, timeoutMs, MILLISECONDS); fail(); } catch (NoSuchElementException success) { // expected } long timetaken = stopwatch.elapsed(MILLISECONDS); assertTrue(timetaken >= timeoutMs - EARLY_GRACE && timetaken <= timeoutMs + SLOW_GRACE, "timetaken=" + timetaken); }
@Override public HostAndPort findOpenSocketOnNode(NodeMetadata node, final int port, long timeout, TimeUnit timeUnits) { ImmutableSet<HostAndPort> sockets = checkNodeHasIps(node, allowedInterfaces).transform(new Function<String, HostAndPort>() { @Override public HostAndPort apply(String from) { return HostAndPort.fromParts(from, port); } }).toSet(); // Specify a retry period of 1s, expressed in the same time units. long period = timeUnits.convert(1, TimeUnit.SECONDS); // For retrieving the socket found (if any) AtomicReference<HostAndPort> result = newReference(); Predicate<Iterable<HostAndPort>> findOrBreak = or(updateRefOnSocketOpen(result), throwISEIfNoLongerRunning(node)); logger.debug(">> blocking on sockets %s for %d %s", sockets, timeout, timeUnits); boolean passed = retryPredicate(findOrBreak, timeout, period, timeUnits).apply(sockets); if (passed) { logger.debug("<< socket %s opened", result); assert result.get() != null; return result.get(); } else { logger.warn("<< sockets %s didn't open after %d %s", sockets, timeout, timeUnits); throw new NoSuchElementException(format("could not connect to any ip address port %d on node %s", port, node)); } }
@Test public void testRespectsTimeout() throws Exception { final long timeoutMs = 1000; OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeRunning, userExecutor); Stopwatch stopwatch = Stopwatch.createUnstarted(); stopwatch.start(); try { finder.findOpenSocketOnNode(node, 22, timeoutMs, MILLISECONDS); fail(); } catch (NoSuchElementException success) { // expected } long timetaken = stopwatch.elapsed(MILLISECONDS); assertTrue(timetaken >= timeoutMs - EARLY_GRACE && timetaken <= timeoutMs + SLOW_GRACE, "timetaken=" + timetaken); }
@Test public void testChecksSocketsConcurrently() throws Exception { ControllableSocketOpen socketTester = new ControllableSocketOpen(ImmutableMap.of( HostAndPort.fromParts(PUBLIC_IP, 22), new SlowCallable<Boolean>(true, 1500), HostAndPort.fromParts(PRIVATE_IP, 22), new SlowCallable<Boolean>(true, 1000))); OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketTester, nodeRunning, userExecutor); HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); assertEquals(result, HostAndPort.fromParts(PRIVATE_IP, 22)); }
@Test public void testChecksSocketsConcurrently() throws Exception { ControllableSocketOpen socketTester = new ControllableSocketOpen(ImmutableMap.of( HostAndPort.fromParts("1.2.3.4", 22), new SlowCallable<Boolean>(true, 1500), HostAndPort.fromParts("1.2.3.5", 22), new SlowCallable<Boolean>(true, 1000))); OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketTester, nodeRunning, userExecutor); HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); assertEquals(result, HostAndPort.fromParts("1.2.3.5", 22)); }