<commit_before>package jhberges.camel.consul.leader;

import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.DefaultProducerTemplate;
import org.apache.camel.support.LifecycleStrategySupport;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ConsulLeaderElector extends LifecycleStrategySupport implements Runnable {
	public static class Builder {
		public static final Builder forConsulHost(final String url) {
			return new Builder(url);
		}

		private final String consulUrl;
		private String serviceName;
		private String routeId;
		private CamelContext camelContext;
		private String username;
		private String password;
		private ScheduledExecutorService executor;

		private Builder(final String url) {
			this.consulUrl = url;
		}

		public ConsulLeaderElector build() throws Exception {
			final ConsulLeaderElector consulLeaderElector = new ConsulLeaderElector(
					consulUrl,
					Optional.ofNullable(username), Optional.ofNullable(password),
					serviceName,
					routeId, camelContext);
			executor.scheduleAtFixedRate(consulLeaderElector, 1, 5, TimeUnit.SECONDS);
			camelContext.addLifecycleStrategy(consulLeaderElector);
			return consulLeaderElector;
		}

		public Builder controllingRoute(final String routeId) {
			this.routeId = routeId;
			return this;
		}

		public Builder inCamelContext(final CamelContext camelContext) {
			this.camelContext = camelContext;
			return this;
		}

		public Builder usingBasicAuth(final String username, final String password) {
			this.username = username;
			this.password = password;
			return this;
		}

		public Builder usingExecutor(final ScheduledExecutorService executor) {
			this.executor = executor;
			return this;
		}

		public Builder usingServiceName(final String serviceName) {
			this.serviceName = serviceName;
			return this;
		}
	}

	private static final String CONTROLBUS_ROUTE = "controlbus:language:simple";

	private static final Logger logger = LoggerFactory.getLogger(ConsulLeaderElector.class);

	private static final ObjectMapper objectMapper = new ObjectMapper();

	private static Optional<String> createSession(final Executor executor, final String consulUrl, final String serviceName) {
		HttpResponse response;
		try {
			response = executor.execute(
					Request.Put(String.format("%s/v1/session/create", consulUrl))
							.bodyString(String.format("{\"Name\": \"%s\"}", serviceName), ContentType.APPLICATION_JSON)).returnResponse();
			if (response.getStatusLine().getStatusCode() == 200) {
				final Optional<String> newSessionKey = unpackSessionKey(response.getEntity());
				logger.info("Consul sessionKey={}", newSessionKey);
				return newSessionKey;
			} else {
				logger.warn("Unable to obtain sessionKey -- will continue as an island");
				return Optional.empty();
			}
		} catch (final ClientProtocolException e) {
			logger.warn("Failed to obtain sessionKey \"{}\" -- will continue as an island", e.getMessage());
			return Optional.empty();
		} catch (final IOException e) {
			logger.error("Failed to obtain sessionKey \"{}\" -- will continue as an island", e.getMessage());
			return Optional.empty();
		}
	}

	private static void destroySession(final Executor executor, final String consulUrl, final String sessionKey) {
		logger.info("Destroying consul session {}", sessionKey);
		try {
			final HttpResponse response = executor.execute(
					Request.Put(String.format("%s/v1/session/destroy/%s", consulUrl, sessionKey))).returnResponse();
			if (response.getStatusLine().getStatusCode() == 200) {
				logger.debug("All OK");
			} else {
				logger.warn("Failed to destroy consul session: {}",
						response.getStatusLine().toString(), EntityUtils.toString(response.getEntity()));
			}<commit_msg>Use `TTL`<commit_after>package jhberges.camel.consul.leader;

import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.DefaultProducerTemplate;
import org.apache.camel.support.LifecycleStrategySupport;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ConsulLeaderElector extends LifecycleStrategySupport implements Runnable {
	public static class Builder {

		public static final Builder forConsulHost(final String url) {
			return new Builder(url);
		}

		private final String consulUrl;
		private String serviceName;
		private String routeId;
		private CamelContext camelContext;
		private String username;
		private String password;
		private ScheduledExecutorService executor;

		private Builder(final String url) {
			this.consulUrl = url;
		}

		public ConsulLeaderElector build() throws Exception {
			final ConsulLeaderElector consulLeaderElector = new ConsulLeaderElector(
					consulUrl,
					Optional.ofNullable(username), Optional.ofNullable(password),
					serviceName,
					routeId, camelContext);
			executor.scheduleAtFixedRate(consulLeaderElector, 1, POLL_INTERVAL, TimeUnit.SECONDS);
			camelContext.addLifecycleStrategy(consulLeaderElector);
			return consulLeaderElector;
		}

		public Builder controllingRoute(final String routeId) {
			this.routeId = routeId;
			return this;
		}

		public Builder inCamelContext(final CamelContext camelContext) {
			this.camelContext = camelContext;
			return this;
		}

		public Builder usingBasicAuth(final String username, final String password) {
			this.username = username;
			this.password = password;
			return this;
		}

		public Builder usingExecutor(final ScheduledExecutorService executor) {
			this.executor = executor;
			return this;
		}

		public Builder usingServiceName(final String serviceName) {
			this.serviceName = serviceName;
			return this;
		}
	}

	private static final int POLL_INTERVAL = 5;

	private static final String CONTROLBUS_ROUTE = "controlbus:language:simple";

	private static final Logger logger = LoggerFactory.getLogger(ConsulLeaderElector.class);

	private static final ObjectMapper objectMapper = new ObjectMapper();

	private static Optional<String> createSession(final Executor executor, final String consulUrl, final String serviceName) {
		HttpResponse response;
		try {
			final String sessionUrl = String.format("%s/v1/session/create", consulUrl);
			final int ttlByInterval = (int) (POLL_INTERVAL * 1.5);
			final String sessionBody = String.format("{\"Name\": \"%s\", \"TTL\": \"%ds\"}",
					serviceName,
					10 > ttlByInterval ? 10 : ttlByInterval);
			logger.debug("PUT {}\n{}", sessionUrl, sessionBody);
			response = executor.execute(
					Request.Put(sessionUrl)
							.bodyString(
									sessionBody,
									ContentType.APPLICATION_JSON)).returnResponse();
			if (response.getStatusLine().getStatusCode() == 200) {
				final Optional<String> newSessionKey = unpackSessionKey(response.getEntity());
				logger.info("Consul sessionKey={}", newSessionKey);
				return newSessionKey;
			} else {
				logger.warn("Unable to obtain sessionKey -- will continue as an island: {}",
						EntityUtils.toString(response.getEntity()));
				return Optional.empty();
			}
		} catch (final ClientProtocolException e) {
			logger.warn("Failed to obtain sessionKey \"{}\" -- will continue as an island", e.getMessage());
			return Optional.empty();
		} catch (final IOException e) {
			logger.error("Failed to obtain sessionKey \"{}\" -- will continue as an island", e.getMessage());
			return Optional.empty();
		}
	}

	private static void destroySession(final Executor executor, final String consulUrl, final String sessionKey) {
		logger.info("Destroying consul session {}", sessionKey);
		try {
			final HttpResponse response = executor.execute(
					Request.Put(String.format("%s/v1/session/destroy/%s", consulUrl, sessionKey))).returnResponse();
			if (response.getStatusLine().getStatusCode() == 200) {
				logger.debug("All OK");
			} else {
				logger.warn("Failed to destroy consul session: {}",
						response.getStatusLine().toString(), EntityUtils.toString(response.getEntity()));
			}
{'fraction_non_alphanumeric': 0.10410666666666667, 'fraction_numerical': 0.0032, 'mean_word_length': 4.79839208410637, 'pattern_counts': {'":': 3, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3140712', 'n_tokens_mistral': 3062, 'n_tokens_neox': 2660, 'n_words': 647}