net.leanix.dropkit.util.DeploymentUtil Maven / Gradle / Ivy
package net.leanix.dropkit.util;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.TimeoutException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import mousio.client.retry.RetryNTimes;
import mousio.etcd4j.EtcdClient;
import mousio.etcd4j.promises.EtcdResponsePromise;
import mousio.etcd4j.responses.EtcdAuthenticationException;
import mousio.etcd4j.responses.EtcdException;
import mousio.etcd4j.responses.EtcdKeysResponse;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helper class to detect the deployment color and if current instance is active or not. The logic to detect if instance is active or
* inactive is based on the configuration in etcd under key /vhosts/local-svc.leanix.net/deploy_current
or
* /vhosts/local-eam.leanix.net/deploy_current
. In oder to use this class you have to specify:
*
*
* * ETCD_SERVER : the etcd server, e.g. '192.168.59.103:4001'
* * CONTAINER_COLOR: 'green', 'blue' or 'white'
* * VIRTUAL_HOST : the virtual host name e.g. 'local-eam.leanix.net' (default: local-svc.leanix.net)
*
*
* @author ralfwehner
*
*/
public class DeploymentUtil {
static String ROOT_VHOSTS = "/vhosts/";
public static final String VIRTUAL_HOST = "VIRTUAL_HOST";
public static final String CONTAINER_COLOR = "CONTAINER_COLOR";
public static final String ETCD_SERVER = "ETCD_SERVER";
private static final Logger LOG = LoggerFactory.getLogger(DeploymentUtil.class);
private final DeploymentColor containerColor;
final URI etcdUri;
public DeploymentUtil() {
String color = getEnvironmentVariable(CONTAINER_COLOR);
containerColor = DeploymentColor.fromString(color);
LOG.debug("Detected assigned deployment color '{}' for this container.", containerColor);
String etcdServer = getEnvironmentVariable(ETCD_SERVER);
if (StringUtils.isEmpty(etcdServer)) {
LOG.debug(
"No etcd server configuration detected. Is this container running in an on premise environment? ETCD configuration will be skipped.");
etcdUri = null;
} else {
etcdUri = URI.create(String.format("http://%s", etcdServer));
}
}
/**
* Returns current container color if set.
*
* @return container color if env variable CONTAINER_COLOR is defined, otherwise null
*/
public DeploymentColor getContainerColor() {
return containerColor;
}
/**
* Returns current color or defaultColor if not set.
*
* @param defaultColor
* @return container color if env variable CONTAINER_COLOR is defined, otherwise defaultColor
*/
public DeploymentColor getContainerColorOrDefault(DeploymentColor defaultColor) {
checkNotNull(defaultColor, "defaultColor must not be null");
return getContainerColor() != null ? getContainerColor() : defaultColor;
}
public boolean isInstanceCurrentlyActive() {
// If we can not detect the color of this container, maybe we are running in an on premise installation, this container returns NO.
if (containerColor == null) {
LOG.warn("Can not detect container color and return: NO - this container is not currently active.");
return false;
} else if (containerColor == DeploymentColor.WHITE) {
return true;
} else if (etcdUri == null) {
if (containerColor != DeploymentColor.WHITE) {
LOG.warn(
"Althought the container color '{}' is specified, no environment variable '{}' exists to specify the etcd configuration.",
containerColor, ETCD_SERVER);
}
return true;
}
// setup key to look for in etcd
String virtualHost = getEnvironmentVariable(VIRTUAL_HOST);
if (StringUtils.isEmpty(virtualHost)) {
virtualHost = "local-svc.leanix.net";
LOG.warn("Environment variable '{}' not found. Using '{}' as default.", VIRTUAL_HOST, virtualHost);
}
String key = ROOT_VHOSTS + virtualHost.trim() + "/deploy_current";
// FIXME rwe: Netty-Client needs jackson-core:2.6.4 but our dropwizard version is set to jackson-core 2.3.0 !
// Update dropwizard as soon as possible!
// read from etcd
try (EtcdClient client = new EtcdClient(etcdUri)) {
// Set the retry policy for only one request
// Will retry 2 times with an interval of 300ms
LOG.trace("Using key '{}', container color is: {}", key, containerColor);
EtcdResponsePromise promise = client.get(key).setRetryPolicy(new RetryNTimes(300, 2)).send();
EtcdKeysResponse etcdKeysResponse = promise.get();
String currentColor = etcdKeysResponse.node.value;
LOG.debug("Read current deployment color '{}' from etcd. This container has color {}. (URL: {}, key: '{}')",
currentColor, containerColor, etcdUri, key);
return (containerColor.toString().equalsIgnoreCase(currentColor));
} catch (IOException | TimeoutException | EtcdAuthenticationException e) {
LOG.warn("Internal error: Can not connect to etcd server! (URL: " + etcdUri + ")", e);
} catch (EtcdException e) {
LOG.warn("Problem accessing etcd key '{}', URL is '{}', msg: {}", key, etcdUri, e.getMessage());
}
// etcd configuration is required, but we can not access it.
return false;
}
private String getEnvironmentVariable(String varName) {
String env = System.getenv(varName);
if (env == null) {
LOG.debug("Environment varible '{}' not found in Sytem.env(). Try to read from system.properties.", varName);
return System.getProperty(varName);
}
return env;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy