net.leanix.dropkit.util.DeploymentUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of leanix-dropkit Show documentation
Show all versions of leanix-dropkit Show documentation
Base functionality for leanIX dropwizard-based services
package net.leanix.dropkit.util;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import net.leanix.dropkit.etcd.EtcdException;
import net.leanix.dropkit.etcd.MinimalEtcdClient;
import net.leanix.dropkit.etcd.MinimalEtcdClientFactory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 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 {
private static final Logger LOG = LoggerFactory.getLogger(DeploymentUtil.class);
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 final MinimalEtcdClient etcdClient;
private final DeploymentColor containerColor;
public DeploymentUtil(MinimalEtcdClientFactory etcdClientFactory) {
String color = getEnvironmentVariable(CONTAINER_COLOR);
containerColor = DeploymentColor.fromString(color);
LOG.debug("Detected assigned deployment color '{}' for this container.", containerColor);
String etcdServer = getEnvironmentVariable(ETCD_SERVER);
URI etcdUri;
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));
}
if (etcdUri != null) {
etcdClient = etcdClientFactory.create(etcdUri);
} else {
etcdClient = null;
}
}
public DeploymentUtil() {
this(new MinimalEtcdClientFactory());
}
/**
* 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 (etcdClient == null) {
if (containerColor != DeploymentColor.WHITE) {
LOG.warn(
"Although the container color '{}' is specified, no environment variable '{}' exists to specify the etcd configuration.",
containerColor, ETCD_SERVER);
}
return true;
}
// read from etcd
try {
String currentColor = retrieveEtcdValue("deploy_current");
LOG.debug("Read current deployment color '{}' from etcd. This container has color {}.",
currentColor, containerColor);
return (containerColor.toString().equalsIgnoreCase(currentColor));
} catch (EtcdException e) {
LOG.warn("Problem accessing etcd (URL is '{}')", etcdClient.getEtcdUri(), e);
}
// 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 variable '{}' not found in Sytem.env(). Try to read from System.properties.", varName);
return System.getProperty(varName);
}
return env;
}
public String retrieveEtcdValue(String key) throws EtcdException {
String completeKey = buildKeyForVirtualHost(key);
if (etcdClient == null) {
LOG.info("Can not read etcd key '{}' because no etcd server was configured before.", completeKey);
return null;
}
String value = etcdClient.get(completeKey);
LOG.debug("Retrieved value '{}' under key '{}' from etcd. (URL: {})", value, completeKey, etcdClient.getEtcdUri());
return value;
}
public void writeEtcdValue(String key, String value) throws EtcdException {
String completeKey = buildKeyForVirtualHost(key);
if (etcdClient == null) {
LOG.info("Can not write etcd value '{}' to '{}' because no etcd server was configured before.", value, completeKey);
return;
}
etcdClient.set(completeKey, value);
LOG.debug("Set value '{}' under key '{}' in etcd. (URL: {})", value, completeKey, etcdClient.getEtcdUri());
}
public boolean writeEtcdValueIfNeeded(String key, String value) throws EtcdException {
String curValue = this.retrieveEtcdValue(key);
if (!StringUtils.equals(value, curValue)) {
this.writeEtcdValue(key, value);
LOG.info("Updated key '{}' with value '{}' in etcd.", key, value);
return true;
}
return false;
}
public List listEtcdKey(String key) throws EtcdException {
String completeKey = buildKeyForVirtualHost(key);
if (etcdClient == null) {
LOG.info("Can not list etcd key '{}' because no etcd server was configured before.", completeKey);
return null;
}
List originalValues = etcdClient.list(completeKey);
String replacement = buildKeyForVirtualHost("");
List values = new ArrayList<>();
for (String path : originalValues) {
values.add(path.replace(replacement, ""));
}
return values;
}
public void deleteEtcdKey(String key, boolean recursive) throws EtcdException {
String completeKey = buildKeyForVirtualHost(key);
if (etcdClient == null) {
LOG.info("Can not delete etcd key '{}' because no etcd server was configured before.", completeKey);
return;
}
etcdClient.delete(completeKey, recursive);
}
public boolean deleteEtcdKeyIfNeeded(String key, boolean recursive) throws EtcdException {
String completeKey = buildKeyForVirtualHost(key);
if (etcdClient == null) {
LOG.info("Can not delete etcd key '{}' because no etcd server was configured before.", completeKey);
return false;
}
if (this.etcdClient.exists(completeKey)) {
this.deleteEtcdKey(key, recursive);
LOG.info("Deleted key '{}' from etcd.", key);
return true;
}
return false;
}
public String getVirtualHost() {
return getEnvironmentVariable(VIRTUAL_HOST);
}
public String buildKeyForVirtualHost(String key) {
String virtualHost = getVirtualHost();
if (StringUtils.isEmpty(virtualHost)) {
virtualHost = "local-svc.leanix.net";
LOG.warn("Environment variable '{}' not found. Using '{}' as default.", VIRTUAL_HOST, virtualHost);
}
String completeKey = ROOT_VHOSTS + virtualHost.trim() + '/' + key;
return completeKey;
}
public MinimalEtcdClient getEtcdClient() {
return etcdClient;
}
public boolean isEtcdConfigured() {
return etcdClient != null && etcdClient.getEtcdUri() != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy