All Downloads are FREE. Search and download functionalities are using the official Maven repository.

consul.HealthService Maven / Gradle / Ivy

package consul;

import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class HealthService extends ConsulChain {
    public static final String INDEX_HEADER = "X-Consul-Index".toLowerCase();

    public HealthService(Consul c) {
        super(c);
    }

    /**
     * Calls consul's health check for service, only returns services with passing health checks
     *
     * https://www.consul.io/docs/agent/http/health.html#health_service
     * @param name Service name to look up
     * @return List of HealServiceChecks
     * @throws ConsulException
     */
    public List check(String name) throws ConsulException {
        return check(name, null, 30, true).getServiceList();
    }

    // Need this to 'soften' the IOException for use with CompletableFuture.
    private HttpResp doGet(final String url) {
        try {
            return Http.get(url);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Call the health service check consul end point
     *
     * When consul index is specified the consul service will wait to to return services until either the waitTime has expired or
     * a change has happened to the specified service.
     *
     * More details: https://www.consul.io/docs/agent/watches.html
     *
     * @param name Service name to look up
     * @param consulIndex When not null passes this index to consul to allow a blocked query
     * @param waitTimeSeconds time to pass to consul to wait for changes to a service
     * @param passing if true only returns services that are passing their health check.
     * @return Response object with Consul-Index and a list of services
     * @throws ConsulException
     */
    public HealthServiceCheckResponse check(String name, String consulIndex, int waitTimeSeconds, boolean passing) throws ConsulException {
        return check(name, consulIndex, waitTimeSeconds, passing, Executors.newSingleThreadExecutor());
    }

    /**
     * Call the health service check consul end point
     *
     * When consul index is specified the consul service will wait to to return services until either the waitTime has expired or
     * a change has happened to the specified service.
     *
     * More details: https://www.consul.io/docs/agent/watches.html
     *
     * @param name Service name to look up
     * @param consulIndex When not null passes this index to consul to allow a blocked query
     * @param waitTimeSeconds time to pass to consul to wait for changes to a service
     * @param passing if true only returns services that are passing their health check.
     * @param executorService An executor service for use with completable future
     * @throws ConsulException
     */
    public HealthServiceCheckResponse check(
        String name, String consulIndex, int waitTimeSeconds, boolean passing, ExecutorService executorService
    ) throws ConsulException {
        HttpResp resp;
        String prefix = "?";
        String params = "";
        if (consulIndex != null) {
            params = params + prefix + "index=" + consulIndex;
            params = params + "&wait=" + waitTimeSeconds + "s";
            prefix = "&";
        }
        if (passing) {
            params = params + prefix + "passing=true";
        }
        final String p = params; // ugh! java lambdas
        try {
            resp = CompletableFuture.supplyAsync(
                () -> doGet(consul().getUrl() + EndpointCategory.HealthService.getUri() + name + p),
                executorService
            ).get((long)Math.ceil(1.1f * waitTimeSeconds), TimeUnit.SECONDS);
        } catch (RuntimeException | ExecutionException | InterruptedException | TimeoutException e) {
           throw new ConsulException(e);
        }
        final String newConsulIndex = resp.getFirstHeader(INDEX_HEADER);
        final List serviceChecks = new ArrayList<>();
        if (resp.getStatus() >= Http.INTERNAL_SERVER_ERROR) {
            throw new ConsulException("Error Status Code: " + resp.getStatus() + "  body: " + resp.getBody());
        }
        final JsonNode arr = parseJson(resp.getBody());
        for (int i = 0; i < arr.size(); i++) {
            serviceChecks.add(new HealthServiceCheck(arr.get(i)));
        }
        return new HealthServiceCheckResponse(newConsulIndex, serviceChecks);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy