@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)); }
@Override public Void call() { checkState(!tainted, "this object is not designed to be reused: %s", toString()); tainted = true; String originalId = node.get().getId(); try { if (options.shouldBlockUntilRunning()) { pollNodeRunning.apply(node); if (statement != null) { RunScriptOnNode runner = initScriptRunnerFactory.create(node.get(), statement, options, badNodes).call(); if (runner != null) { ExecResponse exec = runner.call(); customizationResponses.put(node.get(), exec); } } if (options.getPort() > 0) { openSocketFinder.findOpenSocketOnNode(node.get(), options.getPort(), options.getSeconds(), TimeUnit.SECONDS); } } logger.debug("<< customized node(%s)", originalId); goodNodes.add(node.get()); } catch (Exception e) { logger.error(e, "<< problem customizing node(%s): ", originalId, getRootCause(e).getMessage()); badNodes.put(node.get(), e); } return null; }
@Test public void testAbortsWhenNodeNotRunning() throws Exception { OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeNotRunning, userExecutor) { @Override protected <T> Predicate<T> retryPredicate(final Predicate<T> findOrBreak, long timeout, long period, TimeUnit timeUnits) { return new Predicate<T>() { @Override public boolean apply(T input) { try { findOrBreak.apply(input); fail("should have thrown IllegalStateException"); } catch (IllegalStateException e) { } return false; } }; } }; try { finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); fail(); } catch (NoSuchElementException e) { // success // Note: don't get the "no longer running" message, because // logged+swallowed by RetryablePredicate } }
@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 Void call() { checkState(!tainted, "this object is not designed to be reused: %s", toString()); tainted = true; String originalId = node.get().getId(); try { if (options.shouldBlockUntilRunning()) { pollNodeRunning.apply(node); Statement statement = nodeAndTemplateOptionsToStatement.apply(node.get(), options); if (statement != null) { RunScriptOnNode runner = initScriptRunnerFactory.create(node.get(), statement, options, badNodes).call(); if (runner != null) { ExecResponse exec = runner.call(); customizationResponses.put(node.get(), exec); } } if (options.getPort() > 0) { openSocketFinder.findOpenSocketOnNode(node.get(), options.getPort(), options.getSeconds(), TimeUnit.SECONDS); } } logger.debug("<< customized node(%s)", originalId); goodNodes.add(node.get()); } catch (Exception e) { logger.error(e, "<< problem customizing node(%s): ", originalId, getRootCause(e).getMessage()); badNodes.put(node.get(), e); } return null; }
@Override public Void call() { checkState(!tainted, "this object is not designed to be reused: %s", toString()); tainted = true; String originalId = node.get().getId(); try { if (options.shouldBlockUntilRunning()) { pollNodeRunning.apply(node); if (statement != null) { RunScriptOnNode runner = initScriptRunnerFactory.create(node.get(), statement, options, badNodes).call(); if (runner != null) { ExecResponse exec = runner.call(); customizationResponses.put(node.get(), exec); } } if (options.getPort() > 0) { openSocketFinder.findOpenSocketOnNode(node.get(), options.getPort(), options.getSeconds(), TimeUnit.SECONDS); } } logger.debug("<< customized node(%s)", originalId); goodNodes.add(node.get()); } catch (Exception e) { logger.error(e, "<< problem customizing node(%s): ", originalId, getRootCause(e).getMessage()); badNodes.put(node.get(), e); } return null; }
@Override public Void call() { checkState(!tainted, "this object is not designed to be reused: %s", toString()); tainted = true; String originalId = node.get().getId(); try { if (options.shouldBlockUntilRunning()) { pollNodeRunning.apply(node); Statement statement = nodeAndTemplateOptionsToStatement.apply(node.get(), options); if (statement != null) { RunScriptOnNode runner = initScriptRunnerFactory.create(node.get(), statement, options, badNodes).call(); if (runner != null) { ExecResponse exec = runner.call(); customizationResponses.put(node.get(), exec); } } if (options.getPort() > 0) { openSocketFinder.findOpenSocketOnNode(node.get(), options.getPort(), options.getSeconds(), TimeUnit.SECONDS); } } logger.debug("<< customized node(%s)", originalId); goodNodes.add(node.get()); } catch (Exception e) { logger.error(e, "<< problem customizing node(%s): ", originalId, getRootCause(e).getMessage()); badNodes.put(node.get(), e); } return null; }
@Test public void testAbortsWhenNodeNotRunning() throws Exception { OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeNotRunning, userExecutor) { @Override protected <T> Predicate<T> retryPredicate(final Predicate<T> findOrBreak, long timeout, long period, TimeUnit timeUnits) { return new Predicate<T>() { @Override public boolean apply(T input) { try { findOrBreak.apply(input); fail("should have thrown IllegalStateException"); } catch (IllegalStateException e) { } return false; } }; } }; try { finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS); fail(); } catch (NoSuchElementException e) { // success // Note: don't get the "no longer running" message, because // logged+swallowed by RetryablePredicate } }
@Override public SshClient apply(NodeMetadata node) { checkState(sshFactory != null, "ssh requested, but no SshModule configured"); checkNotNull(node.getCredentials(), "no credentials found for node %s", node.getId()); checkNotNull(node.getCredentials().identity, "no login identity found for node %s", node.getId()); checkNotNull(node.getCredentials().credential, "no credential found for %s on node %s", node .getCredentials().identity, node.getId()); HostAndPort socket = openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), timeoutMs, TimeUnit.MILLISECONDS); return sshFactory.create(socket, node.getCredentials()); } }
@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 SshClient apply(NodeMetadata node) { checkState(sshFactory != null, "ssh requested, but no SshModule configured"); checkNotNull(node.getCredentials(), "no credentials found for node %s", node.getId()); checkNotNull(node.getCredentials().identity, "no login identity found for node %s", node.getId()); checkNotNull(node.getCredentials().credential, "no credential found for %s on node %s", node .getCredentials().identity, node.getId()); HostAndPort socket = openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), timeoutMs, TimeUnit.MILLISECONDS); return sshFactory.create(socket, node.getCredentials()); } }
@Override public SshClient apply(NodeMetadata node) { checkState(sshFactory != null, "ssh requested, but no SshModule configured"); checkNotNull(node.getCredentials(), "no credentials found for node %s", node.getId()); checkNotNull(node.getCredentials().identity, "no login identity found for node %s", node.getId()); checkArgument(node.getCredentials().credential != null || sshFactory.isAgentAvailable(), "no credential or ssh agent found for %s on node %s", node .getCredentials().identity, node.getId()); HostAndPort socket = openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), timeoutMs, TimeUnit.MILLISECONDS); return sshFactory.create(socket, node.getCredentials()); } }
@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); }
@Override public SshClient apply(NodeMetadata node) { checkState(sshFactory != null, "ssh requested, but no SshModule configured"); checkNotNull(node.getCredentials(), "no credentials found for node %s", node.getId()); checkNotNull(node.getCredentials().identity, "no login identity found for node %s", node.getId()); checkArgument(node.getCredentials().credential != null || sshFactory.isAgentAvailable(), "no credential or ssh agent found for %s on node %s", node .getCredentials().identity, node.getId()); HostAndPort socket = openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), timeoutMs, TimeUnit.MILLISECONDS); return sshFactory.create(socket, node.getCredentials()); } }
@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)); }
protected ServiceStats trackAvailabilityOfProcessOnNode(Statement process, String processName, NodeMetadata node) { ServiceStats stats = new ServiceStats(); Stopwatch watch = Stopwatch.createStarted(); ExecResponse exec = client.runScriptOnNode(node.getId(), process, runAsRoot(false).wrapInInitScript(false)); stats.backgroundProcessMilliseconds = watch.elapsed(TimeUnit.MILLISECONDS); watch.reset().start(); HostAndPort socket = null; try { socket = openSocketFinder.findOpenSocketOnNode(node, 8080, 600, TimeUnit.SECONDS); } catch (NoSuchElementException e) { throw new NoSuchElementException(format("%s%n%s%s", e.getMessage(), exec.getOutput(), exec.getError())); } stats.socketOpenMilliseconds = watch.elapsed(TimeUnit.MILLISECONDS); getAnonymousLogger().info(format("<< %s on node(%s)[%s] %s", processName, node.getId(), socket, stats)); return stats; }
final NodeMetadata runningNode = new NodeMetadataBuilder().ids("id").status(Status.RUNNING).build(); expect(openSocketFinder.findOpenSocketOnNode(runningNode, 22, portTimeoutSecs, TimeUnit.SECONDS)).andThrow( new NoSuchElementException("could not connect to any ip address port")).once();
protected void trackProcessOnNode(Statement process, String processName, NodeMetadata node) { ServiceStats stats = new ServiceStats(); Stopwatch watch = Stopwatch.createStarted(); ExecResponse exec = client.runScriptOnNode(node.getId(), process, runAsRoot(false).wrapInInitScript(false)); stats.backgroundProcessMilliseconds = watch.elapsed(TimeUnit.MILLISECONDS); Container container = client.getContext().unwrapApi(DockerApi.class).getContainerApi().inspectContainer(node.getId()); Map<String, List<Map<String, String>>> ports = container.networkSettings().ports(); int port = Integer.parseInt(getOnlyElement(ports.get("8080/tcp")).get("HostPort")); watch.reset().start(); HostAndPort socket; try { socket = openSocketFinder.findOpenSocketOnNode(node, port, 600, TimeUnit.SECONDS); } catch (NoSuchElementException e) { throw new NoSuchElementException(format("%s%n%s%s", e.getMessage(), exec.getOutput(), exec.getError())); } stats.socketOpenMilliseconds = watch.elapsed(TimeUnit.MILLISECONDS); getAnonymousLogger().info(format("<< %s on node(%s)[%s] %s", processName, node.getId(), socket, stats)); }
protected ServiceStats trackAvailabilityOfProcessOnNode(Statement process, String processName, NodeMetadata node) { ServiceStats stats = new ServiceStats(); Stopwatch watch = new Stopwatch().start(); ExecResponse exec = client.runScriptOnNode(node.getId(), process, runAsRoot(false).wrapInInitScript(false)); stats.backgroundProcessMilliseconds = watch.elapsedTime(TimeUnit.MILLISECONDS); watch.reset().start(); HostAndPort socket = null; try { socket = openSocketFinder.findOpenSocketOnNode(node, 8080, 60, TimeUnit.SECONDS); } catch (NoSuchElementException e) { throw new NoSuchElementException(format("%s%n%s%s", e.getMessage(), exec.getOutput(), exec.getError())); } stats.socketOpenMilliseconds = watch.elapsedTime(TimeUnit.MILLISECONDS); getAnonymousLogger().info(format("<< %s on node(%s)[%s] %s", processName, node.getId(), socket, stats)); return stats; }