All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.descoped.secrets.dynamic.configuration.DynamicSecretConfigurationClient Maven / Gradle / Ivy

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() {
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy