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

co.com.bancolombia.secretsmanager.connector.AWSSecretManagerConnectorAsync Maven / Gradle / Ivy

package co.com.bancolombia.secretsmanager.connector;

import co.com.bancolombia.secretsmanager.api.GenericManagerAsync;
import co.com.bancolombia.secretsmanager.api.exceptions.SecretException;
import co.com.bancolombia.secretsmanager.commons.utils.GsonUtils;
import co.com.bancolombia.secretsmanager.config.AWSSecretsManagerConfig;
import com.github.benmanes.caffeine.cache.AsyncCache;
import com.github.benmanes.caffeine.cache.Caffeine;
import reactor.core.publisher.Mono;
import software.amazon.awssdk.auth.credentials.*;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClient;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClientBuilder;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;

import java.net.URI;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class AWSSecretManagerConnectorAsync implements GenericManagerAsync {

    private final AWSSecretsManagerConfig config;
    private final SecretsManagerAsyncClient client;
    private final AsyncCache cache;
    private final Logger logger = Logger.getLogger("connector.AWSSecretManagerConnector");

    public AWSSecretManagerConnectorAsync(AWSSecretsManagerConfig config) {
        this.config = config;
        this.client = buildClient(SecretsManagerAsyncClient.builder());
        this.cache = initCache();
    }

    /**
     * For unit tests
     * @param config
     * @param builder
     */
    public AWSSecretManagerConnectorAsync(AWSSecretsManagerConfig config, SecretsManagerAsyncClientBuilder builder) {
        this.config = config;
        this.client = buildClient(builder);
        this.cache = initCache();
    }

    @Override
    public Mono getSecret(String secretName) {
        return Mono.fromFuture(cache.get(secretName,
                (s, ex) -> getSecretValue(secretName).toFuture().toCompletableFuture()));
    }

    @Override
    public  Mono getSecret(String secretName, Class cls) {
        return this.getSecret(secretName)
                .flatMap((data -> Mono.just(GsonUtils.getInstance().stringToModel(data, cls))))
                .onErrorMap(e -> new SecretException(e.getMessage()));
    }


    private Mono getSecretValue(String secretName) {
        GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder().secretId(secretName).build();

        return Mono.fromFuture(client.getSecretValue(getSecretValueRequest))
                .switchIfEmpty(Mono.defer(() -> Mono.error(new SecretException("Secret value is null"))))
                .onErrorMap(e -> new SecretException(e.getMessage()))
                .flatMap(secretResult -> {
                    if (secretResult.secretString() != null) {
                        String result = secretResult.secretString();
                        return Mono.just(result);
                    }
                    return Mono.error(new SecretException("Secret value is not a String"));
                })
                .doOnError(err -> logger.warning("Error retrieving the secret: " + err.getMessage()));
    }

    /**
     * Default provider chain extended with extra CredentialProvider and
     * specif order defined.
     *
     * @see AwsCredentialsProviderChain
     */
    private AwsCredentialsProviderChain getProviderChain() {
        return AwsCredentialsProviderChain.builder()
                .addCredentialsProvider(EnvironmentVariableCredentialsProvider.create())
                .addCredentialsProvider(SystemPropertyCredentialsProvider.create())
                .addCredentialsProvider(WebIdentityTokenFileCredentialsProvider.create())
                .addCredentialsProvider(ProfileCredentialsProvider.create())
                .addCredentialsProvider(ContainerCredentialsProvider.builder().build())
                .addCredentialsProvider(InstanceProfileCredentialsProvider.create())
                .build();
    }

    private SecretsManagerAsyncClient buildClient(SecretsManagerAsyncClientBuilder builder) {
        builder.credentialsProvider(getProviderChain());
        builder.region(config.getRegion());
        if (!"".equals(config.getEndpoint())) {
            builder.endpointOverride(URI.create(config.getEndpoint()));
        }
        return builder.build();
    }

    private AsyncCache initCache() {
        return Caffeine.newBuilder()
                .maximumSize(config.getCacheSize())
                .expireAfterWrite(config.getCacheSeconds(), TimeUnit.SECONDS)
                .buildAsync();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy