io.descoped.secrets.dynamic.configuration.DynamicSecretConfigurationClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of secrets-provider-dynamic-configuration Show documentation
Show all versions of secrets-provider-dynamic-configuration Show documentation
Secrets Provider Dynamic Configuration
The newest version!
package io.descoped.secrets.dynamic.configuration;
import io.descoped.config.StoreBasedDynamicConfiguration;
import io.descoped.secrets.api.SecretManagerClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Optional.ofNullable;
public class DynamicSecretConfigurationClient implements SecretManagerClient {
static final Logger LOG = LoggerFactory.getLogger(DynamicSecretConfigurationClient.class);
final Map map = new ConcurrentHashMap<>();
final String propertyResourcePath;
final Object lock = new Object();
public DynamicSecretConfigurationClient(String propertyResourcePath) {
new StoreBasedDynamicConfiguration.Builder()
.propertiesResource(propertyResourcePath)
.build()
.asMap()
.forEach((key, value) -> map.put(key, Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8))));
this.propertyResourcePath = propertyResourcePath;
}
public DynamicSecretConfigurationClient(Map configuration) {
configuration.forEach((key, value) -> map.put(key, Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8))));
this.propertyResourcePath = null;
}
@Override
public byte[] readBytes(String secretName, String secretVersion) {
return ofNullable(map.get(secretName)).map(s -> Base64.getDecoder().decode(s)).orElse(null);
}
@Override
public String addVersion(String secretName, byte[] secretValue) {
String encodedSecretValue = Base64.getEncoder().encodeToString(secretValue);
map.put(secretName, encodedSecretValue);
Path path = Path.of(propertyResourcePath);
if (!Files.isWritable(path)) {
LOG.warn("Secret configuration is NOT writable: {}", path.normalize().toAbsolutePath());
return "latest";
}
synchronized (lock) {
try {
String secretResources = Files.readString(path);
Properties props = new Properties();
props.load(new StringReader(secretResources));
props.put(secretName, encodedSecretValue);
try (FileOutputStream out = new FileOutputStream(path.toFile())) {
props.store(out, null);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return "latest";
}
@Override
public void close() {
}
}