/** * Determines if this was a successful wait result. * * @return true if the wait succeeded. */ public boolean succeeded() { return !failed(); }
/** * Creates a new instance of a port listening wait. * * @param port the port to attempt to connect to. * @return a new instance. */ public static PortListeningWait portListening(int port) { return new PortListeningWait(port); }
/** * Creates a new port status wait instance. * * @param port the port to test against. * @param expectedStatus the status to block until we get. * @return a new instance. */ public static PortStatusWait portStatus(int port, int expectedStatus) { return new PortStatusWait(port, expectedStatus); }
@Override public WaitResult wait(DockerFacade dockerClient, Container container) { return new PortWait().wait(port, dockerClient, container, (ipAddress, externalPort) -> { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(ipAddress, externalPort), 500); return WaitResult.success(); } catch (IOException e) { return WaitResult.failure("Port not available: %s", port); } }); } }
@Override public WaitResult wait(DockerFacade dockerClient, Container container) { if (dockerClient .containers() .readLogs(container.getId(), PARAMS) .execute() .anyMatch(m -> m.getMessage().contains(checkFor))) { return WaitResult.success(); } return WaitResult.failure("Logs not found for: %s", checkFor); } }
/** * Queries Docker to find the port bindings for the specified port and then performs the provided * {@code waitFunction}. * * @param containerPort the container port to decode and test against. * @param dockerClient the docker client to use. * @param container the container to test against. * @param waitFunction the wait function to use. * @return a {@link WaitResult}. */ public WaitResult wait(int containerPort, DockerFacade dockerClient, Container container, BiFunction<String, Integer, WaitResult> waitFunction) { for (Binding portBinding : getPortBindings(containerPort, container, dockerClient)) { String ipAddress = portBinding.getHostIp(); if (ipAddress.equals(DEFAULT_BINDING)) { ipAddress = dockerClient.hostInfo().getIpAddress(); } int externalPort = Integer.valueOf(portBinding.getHostPortSpec()); LOG.info("Running wait against: [{}:{}]: [{}]: [{}]", ipAddress, externalPort, container.getName(), waitFunction.getClass().getName()); return waitFunction.apply(ipAddress, externalPort); } return WaitResult.success(); }
@Override public final T build() { checkState(deployable.getType() == DeployableType.WAR || deployable.getType() == DeployableType.DIR, "Can only deploy directories or WARs"); String sourcePath = deployable.getPath().getAbsolutePath(); LOG.debug("Deploying: [{}]: [{}]", deployable.getType(), sourcePath); getSpecBuilder().property("context", deployContext); getSpecBuilder().port(PortMappingSpec.random(defaultPort())).waitFor(PortListeningWait.portListening(defaultPort())) .waitFor(LogCheckWait.logMessage(getStartupLogText())).waitFor(ContextPathStatusWait.contextStatus(getDeployContext(), defaultPort(), 200)); copy(sourcePath, getContainerAppPath(), deployFileName + ".war"); if (!servletVariables.isEmpty()) { env(javaOpts(), new ServletVariableProvider(servletVariables)); } return buildInstance(getSpecBuilder()); }
/** * Creates a new successful result. * @return a new instance. */ public static WaitResult success() { return new WaitResult(Optional.empty()); }
/** * Creates a new {@link LogCheckWait} that will block testing until * the container's logs contain the string {@code checkFor}. * * @param checkFor the log message to check for, * @return a new instance. */ public static LogCheckWait logMessage(String checkFor) { return new LogCheckWait(checkFor); }
private Binding[] getPortBindings(int containerPort, Container container, DockerFacade dockerClient) { NetworkSettings networkSettings = getNetworkSettings(container, dockerClient); return networkSettings.getPorts().getBindings().get(ExposedPort.tcp(containerPort)); }
@Override public WaitResult wait(DockerFacade dockerClient, Container container) { return new PortWait().wait(port, dockerClient, container, (ipAddress, externalPort) -> { try { String uri = String.format("http://%s:%s", ipAddress, externalPort); HttpURLConnection connection = (HttpURLConnection) new URL(uri).openConnection(); connection.setRequestMethod("GET"); connection.connect(); if (expectedStatus != connection.getResponseCode()) { return WaitResult.failure("Status on [%s] not expected [%s]", port, expectedStatus); } return WaitResult.success(); } catch (IOException e) { return WaitResult.failure(e.getMessage()); } }); } }
/** * Creates a failed result. Uses {@link String#format(String, Object...)} to replace * portions of the {@code message}. * * @param message the failure message. * @param replacements any string replacements for the message. * @return a new instance. */ public static WaitResult failure(String message, Object... replacements) { return new WaitResult(Optional.of(String.format(message, replacements))); }
@Override public WaitResult wait(DockerFacade dockerClient, Container container) { return new PortWait().wait(port, dockerClient, container, (ipAddress, externalPort) -> { try { String uri = String.format("http://%s:%s/%s", ipAddress, externalPort, context); HttpURLConnection connection = (HttpURLConnection) new URL(uri).openConnection(); connection.setRequestMethod("GET"); connection.connect(); if (expectedStatus != connection.getResponseCode()) { return WaitResult.failure("Status on [%s] not expected [%s]", port, expectedStatus); } return WaitResult.success(); } catch (IOException e) { return WaitResult.failure(e.getMessage()); } }); } }