/*
* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.secretsmanager.caching;
import com.amazonaws.secretsmanager.caching.cache.LRUCache;
import com.amazonaws.secretsmanager.caching.cache.SecretCacheItem;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
import java.nio.ByteBuffer;
/**
* Provides the primary entry-point to the AWS Secrets Manager client cache SDK.
* Most people will want to use either
* {@link #getSecretString(String)} or
* {@link #getSecretBinary(String)} to retrieve a secret from the cache.
*
*
* The core concepts (and classes) in this SDK are:
*
* - {@link SecretCache}
*
- {@link SecretCacheConfiguration}
*
*
*
* {@link SecretCache} provides an in-memory cache for secrets requested from
* AWS Secrets Manager.
*
*/
public class SecretCache implements AutoCloseable {
/** The cached secret items. */
private final LRUCache cache;
/** The cache configuration. */
private final SecretCacheConfiguration config;
/** The AWS Secrets Manager client to use when requesting secrets. */
private final AWSSecretsManager client;
/**
* Constructs a new secret cache using the standard AWS Secrets Manager client with default options.
*/
public SecretCache() {
this(AWSSecretsManagerClientBuilder.standard());
}
/**
* Constructs a new secret cache using an AWS Secrets Manager client created using the
* provided builder.
*
* @param builder
* The builder to use for creating the AWS Secrets Manager client.
*/
public SecretCache(AWSSecretsManagerClientBuilder builder) {
this(null == builder ?
AWSSecretsManagerClientBuilder.standard().build() :
builder.build());
}
/**
* Constructs a new secret cache using the provided AWS Secrets Manager client.
*
* @param client
* The AWS Secrets Manager client to use for requesting secret values.
*/
public SecretCache(AWSSecretsManager client) {
this(new SecretCacheConfiguration().withClient(client));
}
/**
* Constructs a new secret cache using the provided cache configuration.
*
* @param config
* The secret cache configuration.
*/
public SecretCache(SecretCacheConfiguration config) {
if (null == config) { config = new SecretCacheConfiguration(); }
this.cache = new LRUCache(config.getMaxCacheSize());
this.config = config;
this.client = config.getClient() != null ? config.getClient() :
AWSSecretsManagerClientBuilder.standard().build();
}
/**
* Method to retrieve the cached secret item.
*
* @param secretId
* The identifier for the secret being requested.
* @return The cached secret item
*/
private SecretCacheItem getCachedSecret(final String secretId) {
SecretCacheItem secret = this.cache.get(secretId);
if (null == secret) {
this.cache.putIfAbsent(secretId,
new SecretCacheItem(secretId, this.client, this.config));
secret = this.cache.get(secretId);
}
return secret;
}
/**
* Method to retrieve a string secret from AWS Secrets Manager.
*
* @param secretId
* The identifier for the secret being requested.
* @return The string secret
*/
public String getSecretString(final String secretId) {
SecretCacheItem secret = this.getCachedSecret(secretId);
GetSecretValueResult gsv = secret.getSecretValue();
if (null == gsv) { return null; }
return gsv.getSecretString();
}
/**
* Method to retrieve a binary secret from AWS Secrets Manager.
*
* @param secretId
* The identifier for the secret being requested.
* @return The binary secret
*/
public ByteBuffer getSecretBinary(final String secretId) {
SecretCacheItem secret = this.getCachedSecret(secretId);
GetSecretValueResult gsv = secret.getSecretValue();
if (null == gsv) { return null; }
return gsv.getSecretBinary();
}
/**
* Method to force the refresh of a cached secret state.
*
* @param secretId
* The identifier for the secret being refreshed.
* @return True if the refresh completed without error.
* @throws InterruptedException
* If the thread is interrupted while waiting for the refresh.
*/
public boolean refreshNow(final String secretId) throws InterruptedException {
SecretCacheItem secret = this.getCachedSecret(secretId);
return secret.refreshNow();
}
/**
* Method to close the cache.
*/
@Override
public void close() {
this.cache.clear();
}
}