Search in sources :

Example 1 with HealthCheck

use of com.spotify.helios.common.descriptors.HealthCheck in project helios by spotify.

the class JobValidator method validateJobHealthCheck.

/**
 * Validate the Job's health check.
 *
 * @param job The Job to check.
 *
 * @return A set of error Strings
 */
private Set<String> validateJobHealthCheck(final Job job) {
    final HealthCheck healthCheck = job.getHealthCheck();
    if (healthCheck == null) {
        return emptySet();
    }
    final Set<String> errors = Sets.newHashSet();
    if (healthCheck instanceof ExecHealthCheck) {
        final List<String> command = ((ExecHealthCheck) healthCheck).getCommand();
        if (command == null || command.isEmpty()) {
            errors.add("A command must be defined for `docker exec`-based health checks.");
        }
    } else if (healthCheck instanceof HttpHealthCheck || healthCheck instanceof TcpHealthCheck) {
        final String port;
        if (healthCheck instanceof HttpHealthCheck) {
            port = ((HttpHealthCheck) healthCheck).getPort();
        } else {
            port = ((TcpHealthCheck) healthCheck).getPort();
        }
        final Map<String, PortMapping> ports = job.getPorts();
        if (isNullOrEmpty(port)) {
            errors.add("A port must be defined for HTTP and TCP health checks.");
        } else if (!ports.containsKey(port)) {
            errors.add(format("Health check port '%s' not defined in the job. Known ports are '%s'", port, Joiner.on(", ").join(ports.keySet())));
        }
    }
    return errors;
}
Also used : HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) HealthCheck(com.spotify.helios.common.descriptors.HealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) Map(java.util.Map)

Example 2 with HealthCheck

use of com.spotify.helios.common.descriptors.HealthCheck in project helios by spotify.

the class HealthCheckTest method testTcp.

@Test
public void testTcp() throws Exception {
    startDefaultMaster();
    final HeliosClient client = defaultClient();
    startDefaultAgent(testHost(), "--service-registry=" + registryAddress);
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    final HealthCheck healthCheck = TcpHealthCheck.of("health");
    final Job job = pokeJob(healthCheck);
    assertContainerRegistersAfterPoke(client, job);
}
Also used : HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) HealthCheck(com.spotify.helios.common.descriptors.HealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) HeliosClient(com.spotify.helios.client.HeliosClient) Job(com.spotify.helios.common.descriptors.Job) Test(org.junit.Test)

Example 3 with HealthCheck

use of com.spotify.helios.common.descriptors.HealthCheck in project helios by spotify.

the class HealthCheckTest method testHttp.

@Test
public void testHttp() throws Exception {
    startDefaultMaster();
    final HeliosClient client = defaultClient();
    startDefaultAgent(testHost(), "--service-registry=" + registryAddress);
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    final HealthCheck healthCheck = HttpHealthCheck.of("http", "/");
    // start a container that listens on a poke port, and once poked runs a web server
    final Job job = Job.newBuilder().setName(testJobName).setVersion(testJobVersion).setImage(NGINX).setCommand(asList("sh", "-c", "nc -l -p 4711 && nginx -g 'daemon off;'")).addPort("poke", PortMapping.of(4711)).addPort("http", PortMapping.of(80)).addRegistration(ServiceEndpoint.of("foo_service", "foo_proto"), ServicePorts.of("http")).setHealthCheck(healthCheck).build();
    assertContainerRegistersAfterPoke(client, job);
}
Also used : HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) HealthCheck(com.spotify.helios.common.descriptors.HealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) HeliosClient(com.spotify.helios.client.HeliosClient) Job(com.spotify.helios.common.descriptors.Job) Test(org.junit.Test)

Example 4 with HealthCheck

use of com.spotify.helios.common.descriptors.HealthCheck in project helios by spotify.

the class HealthCheckTest method testContainerDiesDuringHealthcheck.

@Test
public void testContainerDiesDuringHealthcheck() throws Exception {
    startDefaultMaster();
    final HeliosClient client = defaultClient();
    startDefaultAgent(testHost(), "--service-registry=" + registryAddress);
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    final HealthCheck healthCheck = TcpHealthCheck.of("health");
    final Job job = pokeJob(healthCheck);
    final JobId jobId = createJob(job);
    deployJob(jobId, testHost());
    awaitTaskState(jobId, testHost(), HEALTHCHECKING);
    // kill the underlying container
    final JobStatus jobStatus = getOrNull(client.jobStatus(jobId));
    final TaskStatus taskStatus = jobStatus.getTaskStatuses().get(testHost());
    getNewDockerClient().killContainer(taskStatus.getContainerId());
    // ensure the job is marked as failed
    final int timeout = WAIT_TIMEOUT_SECONDS;
    Polling.await(timeout, SECONDS, new Callable<Object>() {

        @Override
        public Object call() throws Exception {
            final TaskStatusEvents jobHistory = getOrNull(client.jobHistory(jobId));
            for (final TaskStatusEvent event : jobHistory.getEvents()) {
                if (event.getStatus().getState() == FAILED) {
                    return true;
                }
            }
            return null;
        }
    });
    // wait for the job to come back up and start healthchecking again
    awaitTaskState(jobId, testHost(), HEALTHCHECKING);
    pokeAndVerifyRegistration(client, jobId, timeout);
}
Also used : TaskStatusEvent(com.spotify.helios.common.descriptors.TaskStatusEvent) HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) HealthCheck(com.spotify.helios.common.descriptors.HealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) TaskStatusEvents(com.spotify.helios.common.protocol.TaskStatusEvents) HeliosClient(com.spotify.helios.client.HeliosClient) TaskStatus(com.spotify.helios.common.descriptors.TaskStatus) ServiceEndpoint(com.spotify.helios.common.descriptors.ServiceEndpoint) Endpoint(com.spotify.helios.serviceregistration.ServiceRegistration.Endpoint) IOException(java.io.IOException) JobStatus(com.spotify.helios.common.descriptors.JobStatus) Job(com.spotify.helios.common.descriptors.Job) JobId(com.spotify.helios.common.descriptors.JobId) Test(org.junit.Test)

Example 5 with HealthCheck

use of com.spotify.helios.common.descriptors.HealthCheck in project helios by spotify.

the class HealthCheckTest method testExec.

@Test
public void testExec() throws Exception {
    // CircleCI uses lxc which doesn't support exec - https://circleci.com/docs/docker/#docker-exec
    assumeFalse(isCircleCi());
    final DockerClient dockerClient = getNewDockerClient();
    assumeThat(dockerClient.version(), is(execCompatibleDockerVersion()));
    startDefaultMaster();
    final HeliosClient client = defaultClient();
    startDefaultAgent(testHost(), "--service-registry=" + registryAddress);
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    // check if "file" exists in the root directory as a healthcheck
    final HealthCheck healthCheck = ExecHealthCheck.of("test", "-e", "file");
    // start a container that listens on the service port
    final String portName = "service";
    final String serviceName = "foo_service";
    final String serviceProtocol = "foo_proto";
    final Job job = Job.newBuilder().setName(testJobName).setVersion(testJobVersion).setImage(BUSYBOX).setCommand(asList("sh", "-c", "nc -l -p 4711")).addPort(portName, PortMapping.of(4711)).addRegistration(ServiceEndpoint.of(serviceName, serviceProtocol), ServicePorts.of(portName)).setHealthCheck(healthCheck).build();
    final JobId jobId = createJob(job);
    deployJob(jobId, testHost());
    final TaskStatus jobState = awaitTaskState(jobId, testHost(), HEALTHCHECKING);
    // wait a few seconds to see if the service gets registered
    Thread.sleep(3000);
    // shouldn't be registered, since we haven't created the file yet
    verify(registrar, never()).register(any(ServiceRegistration.class));
    // create the file in the container to make the healthcheck succeed
    final String[] makeFileCmd = new String[] { "touch", "file" };
    final ExecCreation execCreation = dockerClient.execCreate(jobState.getContainerId(), makeFileCmd);
    final String execId = execCreation.id();
    dockerClient.execStart(execId);
    awaitTaskState(jobId, testHost(), RUNNING);
    dockerClient.close();
    verify(registrar, timeout((int) SECONDS.toMillis(LONG_WAIT_SECONDS))).register(registrationCaptor.capture());
    final ServiceRegistration serviceRegistration = registrationCaptor.getValue();
    assertEquals(1, serviceRegistration.getEndpoints().size());
    final Endpoint registeredEndpoint = serviceRegistration.getEndpoints().get(0);
    assertEquals("wrong service", serviceName, registeredEndpoint.getName());
    assertEquals("wrong protocol", serviceProtocol, registeredEndpoint.getProtocol());
}
Also used : ExecCreation(com.spotify.docker.client.messages.ExecCreation) DockerClient(com.spotify.docker.client.DockerClient) ServiceEndpoint(com.spotify.helios.common.descriptors.ServiceEndpoint) Endpoint(com.spotify.helios.serviceregistration.ServiceRegistration.Endpoint) HttpHealthCheck(com.spotify.helios.common.descriptors.HttpHealthCheck) HealthCheck(com.spotify.helios.common.descriptors.HealthCheck) ExecHealthCheck(com.spotify.helios.common.descriptors.ExecHealthCheck) TcpHealthCheck(com.spotify.helios.common.descriptors.TcpHealthCheck) HeliosClient(com.spotify.helios.client.HeliosClient) Job(com.spotify.helios.common.descriptors.Job) TaskStatus(com.spotify.helios.common.descriptors.TaskStatus) JobId(com.spotify.helios.common.descriptors.JobId) ServiceRegistration(com.spotify.helios.serviceregistration.ServiceRegistration) Test(org.junit.Test)

Aggregations

ExecHealthCheck (com.spotify.helios.common.descriptors.ExecHealthCheck)5 HealthCheck (com.spotify.helios.common.descriptors.HealthCheck)5 HttpHealthCheck (com.spotify.helios.common.descriptors.HttpHealthCheck)5 TcpHealthCheck (com.spotify.helios.common.descriptors.TcpHealthCheck)5 HeliosClient (com.spotify.helios.client.HeliosClient)4 Job (com.spotify.helios.common.descriptors.Job)4 Test (org.junit.Test)4 JobId (com.spotify.helios.common.descriptors.JobId)2 ServiceEndpoint (com.spotify.helios.common.descriptors.ServiceEndpoint)2 TaskStatus (com.spotify.helios.common.descriptors.TaskStatus)2 Endpoint (com.spotify.helios.serviceregistration.ServiceRegistration.Endpoint)2 DockerClient (com.spotify.docker.client.DockerClient)1 ExecCreation (com.spotify.docker.client.messages.ExecCreation)1 JobStatus (com.spotify.helios.common.descriptors.JobStatus)1 TaskStatusEvent (com.spotify.helios.common.descriptors.TaskStatusEvent)1 TaskStatusEvents (com.spotify.helios.common.protocol.TaskStatusEvents)1 ServiceRegistration (com.spotify.helios.serviceregistration.ServiceRegistration)1 IOException (java.io.IOException)1 Map (java.util.Map)1