Импортировать файл в zookeeper в java
Я использую zookeeper для управления конфигурацией для моих микросервисов java. Для этого я использую apache curator и java zookeeper client.
Как я могу импортировать файл конфигурации (свойства или json) в zookeeper при инициализации микросервиса?
1 ответ
Вы должны использовать curator framework
если вы хотите загрузить свой конфиг в zookeeper. Смотрите пост о том, как вы можете использовать curator
фреймворк.
Есть некоторый базовый пример кода для yml
файлы (для весеннего конфига):
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
import org.springframework.core.io.ClassPathResource;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Slf4j
public class LoadConfigsInZoo {
// base path of your config
// /CONFIG_PATH/APP_NAME,CONTEXT_NAME
private static final String BASE_PATH = "/configuration/myApp";
private static final String ZOO_URL = "localhost:2181";
private static final String CONFIG_FILE = "bootstrap.yml";
private final ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) throws IOException {
new LoadConfigsInZoo().loadConfig();
}
private void loadConfig() throws IOException {
BoundedExponentialBackoffRetry retryPolicy =
new BoundedExponentialBackoffRetry(100, 300, 10);
Map<String, String> config = flattenInnerProperties("", getContentOfYaml(CONFIG_FILE));
try (CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(ZOO_URL)
.retryPolicy(retryPolicy)
.build()) {
client.start();
for (Map.Entry<String, String> entry : config.entrySet()) {
String path = createPath(BASE_PATH, entry.getKey());
try {
log.info("Try add node with name '{}'", path);
client.create()
.creatingParentsIfNeeded()
.forPath(path, entry.getValue().getBytes());
log.info("Node with name '{}' was created", path);
} catch (Exception e) {
log.warn("Unable to create node by path: {}, exception: {}", path, e.getMessage());
}
}
}
}
// need your own implementation for properties/json files
@SuppressWarnings("unchecked")
private Map<String, Object> getContentOfYaml(String path) throws IOException {
Yaml yaml = new Yaml();
try (InputStream in = new ClassPathResource(path).getInputStream()) {
return yaml.loadAs(in, Map.class);
}
}
@SuppressWarnings("unchecked")
private Map<String, String> getContentOfProperties(String path) throws IOException {
try (InputStream in = new ClassPathResource(path).getInputStream()) {
Properties properties = new Properties();
properties.load(in);
return (Map) (properties);
}
}
@SuppressWarnings("unchecked")
private Map<String, String> getContentOfJson(String path) throws IOException {
try (InputStream in = new ClassPathResource(path).getInputStream()) {
return new ObjectMapper().readValue(in, HashMap.class);
}
}
@SuppressWarnings("unchecked")
private Map<String, String> flattenInnerProperties(String prefix, Map<String, Object> rootMap) {
Map<String, String> result = new HashMap<>();
for (Map.Entry<String, Object> entry : rootMap.entrySet()) {
String newPrefix = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey();
Object value = entry.getValue();
if (value instanceof Map) {
result.putAll(flattenInnerProperties(newPrefix, (Map<String, Object>) value));
} else if (value instanceof List) {
result.putAll(flattenInnerListInProperties(newPrefix, (List) value));
} else {
result.put(newPrefix, String.valueOf(value));
}
}
return result;
}
@SuppressWarnings("unchecked")
private Map<String, String> flattenInnerListInProperties(String prefix, List value) {
int i = 0;
Map<String, String> result = new HashMap<>();
for (Object v : value) {
String listKey = prefix + "[" + i + "]";
if (v instanceof Map) {
result.putAll(flattenInnerProperties(listKey, (Map) v));
} else if (v instanceof List) {
result.putAll(flattenInnerListInProperties(listKey, (List) v));
} else {
result.put(listKey, String.valueOf(v));
}
i++;
}
return result;
}
private String createPath(String basePath, String configName) {
return basePath + "/" + configName.replaceAll("\\.", "/");
}
}
I had a similar problem, where we were using zookeeper as the config server and the configuration was stored in yml format in file. Instead of writing code for creating the znode hierarchy dynamically as per yml file, I found a groovy based tool which basically does the same.
You need to have groovy installed and run as below
zookeeperdump.groovy -s localhost:2181 -c /config/application < dump.yml