This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new c55be0dcd1 NIFI-15556 Add support for Parameter Tags to AWS Secrets
Manager Parameter Provider (#10859)
c55be0dcd1 is described below
commit c55be0dcd1a0b765af8d261fd4e38c8096b734cf
Author: Pierre Villard <[email protected]>
AuthorDate: Thu Feb 5 22:47:01 2026 +0100
NIFI-15556 Add support for Parameter Tags to AWS Secrets Manager Parameter
Provider (#10859)
Signed-off-by: David Handermann <[email protected]>
---
.../aws/AwsSecretsManagerParameterProvider.java | 78 +++++--
.../TestAwsSecretsManagerParameterProvider.java | 237 +++++++++++++++++----
2 files changed, 266 insertions(+), 49 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/main/java/org/apache/nifi/parameter/aws/AwsSecretsManagerParameterProvider.java
b/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/main/java/org/apache/nifi/parameter/aws/AwsSecretsManagerParameterProvider.java
index f5afd3536f..c962ca511d 100644
---
a/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/main/java/org/apache/nifi/parameter/aws/AwsSecretsManagerParameterProvider.java
+++
b/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/main/java/org/apache/nifi/parameter/aws/AwsSecretsManagerParameterProvider.java
@@ -31,6 +31,7 @@ import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.parameter.AbstractParameterProvider;
import org.apache.nifi.parameter.Parameter;
import org.apache.nifi.parameter.ParameterGroup;
+import org.apache.nifi.parameter.ParameterTag;
import org.apache.nifi.parameter.VerifiableParameterProvider;
import org.apache.nifi.processor.util.StandardValidators;
import
org.apache.nifi.processors.aws.credentials.provider.AwsCredentialsProviderService;
@@ -45,6 +46,8 @@ import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.retries.DefaultRetryStrategy;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
+import
software.amazon.awssdk.services.secretsmanager.model.DescribeSecretRequest;
+import
software.amazon.awssdk.services.secretsmanager.model.DescribeSecretResponse;
import
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
import software.amazon.awssdk.services.secretsmanager.model.ListSecretsRequest;
@@ -52,16 +55,15 @@ import
software.amazon.awssdk.services.secretsmanager.model.ListSecretsResponse;
import
software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
import software.amazon.awssdk.services.secretsmanager.model.SecretListEntry;
import
software.amazon.awssdk.services.secretsmanager.model.SecretsManagerException;
+import software.amazon.awssdk.services.secretsmanager.model.Tag;
import java.time.Duration;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Comparator;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Set;
import java.util.regex.Pattern;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
@@ -77,7 +79,7 @@ import javax.net.ssl.X509TrustManager;
"key/value pairs in the secret mapping to Parameters in the group.")
public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvider implements VerifiableParameterProvider {
enum ListingStrategy implements DescribedValue {
- ENUMERATION("Enumerate Secret Names", "Requires a set of secret names
to fetch. AWS actions required: GetSecretValue."),
+ ENUMERATION("Enumerate Secret Names", "Requires a set of secret names
to fetch. AWS actions required: DescribeSecret and GetSecretValue."),
PATTERN("Match Pattern", "Requires a regular expression pattern to
match secret names. AWS actions required: ListSecrets and GetSecretValue.");
@@ -196,10 +198,16 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
// Fetch either by pattern or by enumerated list. See description of
SECRET_LISTING_STRATEGY for more details.
final ListingStrategy listingStrategy =
context.getProperty(SECRET_LISTING_STRATEGY).asAllowableValue(ListingStrategy.class);
- final Set<String> fetchSecretNames = new HashSet<>();
+ final Map<String, List<Tag>> secretNameToTags = new HashMap<>();
+
if (listingStrategy == ListingStrategy.ENUMERATION) {
final String secretNames =
context.getProperty(SECRET_NAMES).getValue();
- fetchSecretNames.addAll(Arrays.asList(secretNames.split(",")));
+ for (final String secretName : secretNames.split(",")) {
+ final String trimmedName = secretName.trim();
+ // For enumeration strategy, we need to call DescribeSecret to
get tags
+ final List<Tag> tags = describeSecretTags(secretsManager,
trimmedName);
+ secretNameToTags.put(trimmedName, tags);
+ }
} else {
final Pattern secretNamePattern =
Pattern.compile(context.getProperty(SECRET_NAME_PATTERN).getValue());
@@ -212,7 +220,9 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
getLogger().debug("Secret [{}] does not match the
secret name pattern {}", secretName, secretNamePattern);
continue;
}
- fetchSecretNames.add(secretName);
+ // ListSecrets response includes tags, so we can use them
directly
+ final List<Tag> tags = entry.hasTags() ? entry.tags() :
List.of();
+ secretNameToTags.put(secretName, tags);
}
final String nextToken = listSecretsResponse.nextToken();
if (nextToken == null) {
@@ -223,8 +233,10 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
}
}
- for (final String secretName : fetchSecretNames) {
- final List<ParameterGroup> secretParameterGroups =
fetchSecret(secretsManager, secretName);
+ for (final Map.Entry<String, List<Tag>> entry :
secretNameToTags.entrySet()) {
+ final String secretName = entry.getKey();
+ final List<ParameterTag> parameterTags =
convertTags(entry.getValue());
+ final List<ParameterGroup> secretParameterGroups =
fetchSecret(secretsManager, secretName, parameterTags);
groups.addAll(secretParameterGroups);
}
return groups;
@@ -257,7 +269,8 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
return results;
}
- private List<ParameterGroup> fetchSecret(final SecretsManagerClient
secretsManager, final String secretName) {
+ private List<ParameterGroup> fetchSecret(final SecretsManagerClient
secretsManager, final String secretName,
+ final List<ParameterTag> tags) {
final List<ParameterGroup> groups = new ArrayList<>();
final List<Parameter> parameters = new ArrayList<>();
@@ -289,7 +302,7 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
}
final String parameterValue = valueNode.asText();
- parameters.add(createParameter(parameterName, parameterValue));
+ parameters.add(createParameter(parameterName, parameterValue,
tags));
}
groups.add(new ParameterGroup(secretName, parameters));
@@ -302,14 +315,55 @@ public class AwsSecretsManagerParameterProvider extends
AbstractParameterProvide
}
}
- private Parameter createParameter(final String parameterName, final String
parameterValue) {
+ private Parameter createParameter(final String parameterName, final String
parameterValue,
+ final List<ParameterTag> tags) {
return new Parameter.Builder()
.name(parameterName)
.value(parameterValue)
.provided(true)
+ .tags(tags)
.build();
}
+ /**
+ * Retrieves tags for a secret using DescribeSecret API.
+ * This is needed for the ENUMERATION strategy since GetSecretValue does
not return tags.
+ *
+ * @param secretsManager the Secrets Manager client
+ * @param secretName the name of the secret
+ * @return list of tags associated with the secret
+ */
+ private List<Tag> describeSecretTags(final SecretsManagerClient
secretsManager, final String secretName) {
+ try {
+ final DescribeSecretRequest describeRequest =
DescribeSecretRequest.builder()
+ .secretId(secretName)
+ .build();
+ final DescribeSecretResponse describeResponse =
secretsManager.describeSecret(describeRequest);
+ return describeResponse.hasTags() ? describeResponse.tags() :
List.of();
+ } catch (final ResourceNotFoundException e) {
+ getLogger().debug("Secret [{}] not found when describing for
tags", secretName);
+ return List.of();
+ } catch (final SecretsManagerException e) {
+ getLogger().warn("Error describing secret [{}] for tags: {}",
secretName, e.getMessage());
+ return List.of();
+ }
+ }
+
+ /**
+ * Converts AWS Secrets Manager Tags to NiFi ParameterTags.
+ *
+ * @param awsTags the AWS tags to convert
+ * @return list of NiFi ParameterTag objects
+ */
+ private List<ParameterTag> convertTags(final List<Tag> awsTags) {
+ if (awsTags == null || awsTags.isEmpty()) {
+ return List.of();
+ }
+ return awsTags.stream()
+ .map(tag -> new ParameterTag(tag.key(), tag.value()))
+ .toList();
+ }
+
private ClientOverrideConfiguration createConfiguration() {
return ClientOverrideConfiguration.builder()
.retryStrategy(DefaultRetryStrategy.doNotRetry())
diff --git
a/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/test/java/org/apache/nifi/parameter/aws/TestAwsSecretsManagerParameterProvider.java
b/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/test/java/org/apache/nifi/parameter/aws/TestAwsSecretsManagerParameterProvider.java
index da913ffcf9..ab1e22c3af 100644
---
a/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/test/java/org/apache/nifi/parameter/aws/TestAwsSecretsManagerParameterProvider.java
+++
b/nifi-extension-bundles/nifi-aws-bundle/nifi-aws-parameter-providers/src/test/java/org/apache/nifi/parameter/aws/TestAwsSecretsManagerParameterProvider.java
@@ -22,6 +22,7 @@ import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.parameter.Parameter;
import org.apache.nifi.parameter.ParameterGroup;
+import org.apache.nifi.parameter.ParameterTag;
import org.apache.nifi.parameter.VerifiableParameterProvider;
import org.apache.nifi.reporting.InitializationException;
import org.apache.nifi.util.MockComponentLog;
@@ -33,6 +34,8 @@ import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
+import
software.amazon.awssdk.services.secretsmanager.model.DescribeSecretRequest;
+import
software.amazon.awssdk.services.secretsmanager.model.DescribeSecretResponse;
import
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import
software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
import software.amazon.awssdk.services.secretsmanager.model.ListSecretsRequest;
@@ -40,6 +43,7 @@ import
software.amazon.awssdk.services.secretsmanager.model.ListSecretsResponse;
import
software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
import software.amazon.awssdk.services.secretsmanager.model.SecretListEntry;
import
software.amazon.awssdk.services.secretsmanager.model.SecretsManagerException;
+import software.amazon.awssdk.services.secretsmanager.model.Tag;
import java.util.ArrayList;
import java.util.Arrays;
@@ -90,12 +94,12 @@ public class TestAwsSecretsManagerParameterProvider {
@Test
public void testFetchParametersWithNoSecrets() throws
InitializationException {
final List<ParameterGroup> expectedGroups =
Collections.singletonList(new ParameterGroup("MySecret",
Collections.emptyList()));
- runProviderTest(mockSecretsManager(expectedGroups), 0,
ConfigVerificationResult.Outcome.SUCCESSFUL, "PATTERN", null);
+ runProviderTest(mockSecretsManagerWithTags(expectedGroups,
Collections.emptyMap()), 0, ConfigVerificationResult.Outcome.SUCCESSFUL,
"PATTERN", null);
}
@Test
public void testFetchParameters() throws InitializationException {
- runProviderTest(mockSecretsManager(mockParameterGroups), 8,
ConfigVerificationResult.Outcome.SUCCESSFUL, "PATTERN", null);
+ runProviderTest(mockSecretsManagerWithTags(mockParameterGroups,
Collections.emptyMap()), 8, ConfigVerificationResult.Outcome.SUCCESSFUL,
"PATTERN", null);
}
@Test
@@ -110,7 +114,8 @@ public class TestAwsSecretsManagerParameterProvider {
@Test
public void testFetchNonExistentSecret() throws InitializationException {
-
when(defaultSecretsManager.getSecretValue(argThat(matchesGetSecretValueRequest("MySecretDoesNotExist")))).thenThrow(ResourceNotFoundException.builder().message("Fake
exception").build());
+
when(defaultSecretsManager.describeSecret(argThat(matchesDescribeSecretRequest("BadSecret")))).thenThrow(ResourceNotFoundException.builder().message("Fake
exception").build());
+
when(defaultSecretsManager.getSecretValue(argThat(matchesGetSecretValueRequest("BadSecret")))).thenThrow(ResourceNotFoundException.builder().message("Fake
exception").build());
runProviderTest(defaultSecretsManager, 0,
ConfigVerificationResult.Outcome.FAILED, "ENUMERATION", "BadSecret");
}
@@ -142,6 +147,12 @@ public class TestAwsSecretsManagerParameterProvider {
.build();
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest("MixedSecret")))).thenReturn(response);
+ // Mock DescribeSecret for tags (returns empty tags)
+ final DescribeSecretResponse describeResponse =
DescribeSecretResponse.builder()
+ .name("MixedSecret")
+ .build();
+
when(secretsManager.describeSecret(argThat(matchesDescribeSecretRequest("MixedSecret")))).thenReturn(describeResponse);
+
final List<ParameterGroup> parameterGroups =
runProviderTest(secretsManager, 3, ConfigVerificationResult.Outcome.SUCCESSFUL,
"ENUMERATION", "MixedSecret");
assertEquals(1, parameterGroups.size());
@@ -170,6 +181,12 @@ public class TestAwsSecretsManagerParameterProvider {
.build();
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest("NestedSecret")))).thenReturn(response);
+ // Mock DescribeSecret for tags (returns empty tags)
+ final DescribeSecretResponse describeResponse =
DescribeSecretResponse.builder()
+ .name("NestedSecret")
+ .build();
+
when(secretsManager.describeSecret(argThat(matchesDescribeSecretRequest("NestedSecret")))).thenReturn(describeResponse);
+
final List<ParameterGroup> parameterGroups =
runProviderTest(secretsManager, 1, ConfigVerificationResult.Outcome.SUCCESSFUL,
"ENUMERATION", "NestedSecret");
assertEquals(1, parameterGroups.size());
@@ -183,6 +200,116 @@ public class TestAwsSecretsManagerParameterProvider {
assertEquals("validValue", parameterValues.get("validParam"));
}
+ @Test
+ public void testFetchParametersWithTagsPatternStrategy() throws
InitializationException {
+ final List<Tag> secretTags = List.of(
+ Tag.builder().key("environment").value("production").build(),
+ Tag.builder().key("team").value("data-platform").build()
+ );
+
+ final SecretsManagerClient secretsManager = mockSecretsManagerWithTags(
+ List.of(new ParameterGroup("TaggedSecret",
List.of(parameter("param1", "value1")))),
+ Map.of("TaggedSecret", secretTags)
+ );
+
+ final List<ParameterGroup> parameterGroups =
runProviderTest(secretsManager, 1,
+ ConfigVerificationResult.Outcome.SUCCESSFUL, "PATTERN", null);
+
+ assertEquals(1, parameterGroups.size());
+ final ParameterGroup group = parameterGroups.get(0);
+ assertEquals("TaggedSecret", group.getGroupName());
+ assertEquals(1, group.getParameters().size());
+
+ final Parameter parameter = group.getParameters().get(0);
+ assertEquals("param1", parameter.getDescriptor().getName());
+ assertEquals("value1", parameter.getValue());
+
+ // Verify tags are present
+ final List<ParameterTag> tags = parameter.getTags();
+ assertEquals(2, tags.size());
+ assertEquals("environment", tags.get(0).getKey());
+ assertEquals("production", tags.get(0).getValue());
+ assertEquals("team", tags.get(1).getKey());
+ assertEquals("data-platform", tags.get(1).getValue());
+ }
+
+ @Test
+ public void testFetchParametersWithTagsEnumerationStrategy() throws
InitializationException {
+ final List<Tag> secretTags = List.of(
+ Tag.builder().key("cost-center").value("12345").build()
+ );
+
+ final SecretsManagerClient secretsManager =
mock(SecretsManagerClient.class);
+
+ // Mock GetSecretValue
+ final String secretString = "{ \"dbPassword\": \"secret123\" }";
+ final GetSecretValueResponse response =
GetSecretValueResponse.builder()
+ .name("EnumeratedSecret")
+ .secretString(secretString)
+ .build();
+
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest("EnumeratedSecret")))).thenReturn(response);
+
+ // Mock DescribeSecret to return tags
+ final DescribeSecretResponse describeResponse =
DescribeSecretResponse.builder()
+ .name("EnumeratedSecret")
+ .tags(secretTags)
+ .build();
+
when(secretsManager.describeSecret(argThat(matchesDescribeSecretRequest("EnumeratedSecret")))).thenReturn(describeResponse);
+
+ final List<ParameterGroup> parameterGroups =
runProviderTest(secretsManager, 1,
+ ConfigVerificationResult.Outcome.SUCCESSFUL, "ENUMERATION",
"EnumeratedSecret");
+
+ assertEquals(1, parameterGroups.size());
+ final Parameter parameter =
parameterGroups.get(0).getParameters().get(0);
+ assertEquals("dbPassword", parameter.getDescriptor().getName());
+
+ // Verify tags are present
+ final List<ParameterTag> tags = parameter.getTags();
+ assertEquals(1, tags.size());
+ assertEquals("cost-center", tags.get(0).getKey());
+ assertEquals("12345", tags.get(0).getValue());
+ }
+
+ @Test
+ public void testFetchParametersWithMultipleSecretsAndTags() throws
InitializationException {
+ final Map<String, List<Tag>> secretTagsMap = Map.of(
+ "Secret1",
List.of(Tag.builder().key("app").value("app1").build()),
+ "Secret2",
List.of(Tag.builder().key("app").value("app2").build(),
Tag.builder().key("env").value("dev").build())
+ );
+
+ final List<ParameterGroup> mockGroups = List.of(
+ new ParameterGroup("Secret1", List.of(parameter("key1",
"val1"))),
+ new ParameterGroup("Secret2", List.of(parameter("key2",
"val2"), parameter("key3", "val3")))
+ );
+
+ final SecretsManagerClient secretsManager =
mockSecretsManagerWithTags(mockGroups, secretTagsMap);
+
+ final List<ParameterGroup> parameterGroups =
runProviderTest(secretsManager, 3,
+ ConfigVerificationResult.Outcome.SUCCESSFUL, "PATTERN", null);
+
+ assertEquals(2, parameterGroups.size());
+
+ // Find Secret1 group
+ final ParameterGroup secret1Group = parameterGroups.stream()
+ .filter(g -> "Secret1".equals(g.getGroupName()))
+ .findFirst()
+ .orElseThrow();
+ assertEquals(1, secret1Group.getParameters().size());
+ assertEquals(1, secret1Group.getParameters().get(0).getTags().size());
+ assertEquals("app1",
secret1Group.getParameters().get(0).getTags().get(0).getValue());
+
+ // Find Secret2 group
+ final ParameterGroup secret2Group = parameterGroups.stream()
+ .filter(g -> "Secret2".equals(g.getGroupName()))
+ .findFirst()
+ .orElseThrow();
+ assertEquals(2, secret2Group.getParameters().size());
+ // Both parameters in Secret2 should have the same tags
+ for (final Parameter param : secret2Group.getParameters()) {
+ assertEquals(2, param.getTags().size());
+ }
+ }
+
private AwsSecretsManagerParameterProvider getParameterProvider() {
return spy(new AwsSecretsManagerParameterProvider());
}
@@ -203,6 +330,13 @@ public class TestAwsSecretsManagerParameterProvider {
final GetSecretValueResponse response =
GetSecretValueResponse.builder().name(groupName).secretString(secretString).build();
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest(groupName))))
.thenReturn(response);
+
+ // Mock DescribeSecret for tags (returns empty tags)
+ final DescribeSecretResponse describeResponse =
DescribeSecretResponse.builder()
+ .name(groupName)
+ .build();
+
when(secretsManager.describeSecret(argThat(matchesDescribeSecretRequest(groupName))))
+ .thenReturn(describeResponse);
} catch (final JsonProcessingException e) {
throw new IllegalStateException(e);
}
@@ -211,40 +345,6 @@ public class TestAwsSecretsManagerParameterProvider {
});
return secretsManager;
}
- private SecretsManagerClient mockSecretsManager(final List<ParameterGroup>
mockParameterGroups) {
- final SecretsManagerClient secretsManager =
mock(SecretsManagerClient.class);
-
when(emptyListSecretsResponse.secretList()).thenReturn(Collections.emptyList());
-
- String currentToken = null;
- for (int i = 0; i < mockParameterGroups.size(); i++) {
- final ParameterGroup group = mockParameterGroups.get(i);
- final List<SecretListEntry> secretList =
Collections.singletonList(SecretListEntry.builder().name(group.getGroupName()).build());
- final ListSecretsResponse listSecretsResponse =
mock(ListSecretsResponse.class);
- when(listSecretsResponse.secretList()).thenReturn(secretList);
-
when(secretsManager.listSecrets(argThat(ListSecretsRequestMatcher.hasToken(currentToken)))).thenReturn(listSecretsResponse);
-
- currentToken = "token-" + i;
- when(listSecretsResponse.nextToken()).thenReturn(currentToken);
- }
-
when(secretsManager.listSecrets(argThat(ListSecretsRequestMatcher.hasToken(currentToken)))).thenReturn(emptyListSecretsResponse);
-
- mockParameterGroups.forEach(group -> {
- final String groupName = group.getGroupName();
- final Map<String, String> keyValues =
group.getParameters().stream().collect(Collectors.toMap(
- param -> param.getDescriptor().getName(),
- Parameter::getValue));
- final String secretString;
- try {
- secretString = objectMapper.writeValueAsString(keyValues);
- final GetSecretValueResponse response =
GetSecretValueResponse.builder().name(groupName).secretString(secretString).build();
-
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest(groupName))))
- .thenReturn(response);
- } catch (final JsonProcessingException e) {
- throw new IllegalStateException(e);
- }
- });
- return secretsManager;
- }
private List<ParameterGroup> runProviderTest(final SecretsManagerClient
secretsManager,
final int expectedCount,
@@ -287,6 +387,51 @@ public class TestAwsSecretsManagerParameterProvider {
return parameterGroups;
}
+ private SecretsManagerClient mockSecretsManagerWithTags(final
List<ParameterGroup> mockParameterGroups,
+ final Map<String,
List<Tag>> secretTags) {
+ final SecretsManagerClient secretsManager =
mock(SecretsManagerClient.class);
+
when(emptyListSecretsResponse.secretList()).thenReturn(Collections.emptyList());
+
+ String currentToken = null;
+ for (int i = 0; i < mockParameterGroups.size(); i++) {
+ final ParameterGroup group = mockParameterGroups.get(i);
+ final String groupName = group.getGroupName();
+ final List<Tag> tags = secretTags.getOrDefault(groupName,
Collections.emptyList());
+
+ // Build SecretListEntry with tags
+ final SecretListEntry.Builder entryBuilder =
SecretListEntry.builder().name(groupName);
+ if (!tags.isEmpty()) {
+ entryBuilder.tags(tags);
+ }
+ final List<SecretListEntry> secretList =
Collections.singletonList(entryBuilder.build());
+
+ final ListSecretsResponse listSecretsResponse =
mock(ListSecretsResponse.class);
+ when(listSecretsResponse.secretList()).thenReturn(secretList);
+
when(secretsManager.listSecrets(argThat(ListSecretsRequestMatcher.hasToken(currentToken)))).thenReturn(listSecretsResponse);
+
+ currentToken = "token-" + i;
+ when(listSecretsResponse.nextToken()).thenReturn(currentToken);
+ }
+
when(secretsManager.listSecrets(argThat(ListSecretsRequestMatcher.hasToken(currentToken)))).thenReturn(emptyListSecretsResponse);
+
+ mockParameterGroups.forEach(group -> {
+ final String groupName = group.getGroupName();
+ final Map<String, String> keyValues =
group.getParameters().stream().collect(Collectors.toMap(
+ param -> param.getDescriptor().getName(),
+ Parameter::getValue));
+ final String secretString;
+ try {
+ secretString = objectMapper.writeValueAsString(keyValues);
+ final GetSecretValueResponse response =
GetSecretValueResponse.builder().name(groupName).secretString(secretString).build();
+
when(secretsManager.getSecretValue(argThat(matchesGetSecretValueRequest(groupName))))
+ .thenReturn(response);
+ } catch (final JsonProcessingException e) {
+ throw new IllegalStateException(e);
+ }
+ });
+ return secretsManager;
+ }
+
private static Parameter parameter(final String name, final String value) {
return new Parameter.Builder()
.name(name)
@@ -298,6 +443,10 @@ public class TestAwsSecretsManagerParameterProvider {
return new GetSecretValueRequestMatcher(groupName);
}
+ private static ArgumentMatcher<DescribeSecretRequest>
matchesDescribeSecretRequest(final String secretId) {
+ return new DescribeSecretRequestMatcher(secretId);
+ }
+
private static class GetSecretValueRequestMatcher implements
ArgumentMatcher<GetSecretValueRequest> {
private final String secretId;
@@ -329,4 +478,18 @@ public class TestAwsSecretsManagerParameterProvider {
return argument != null && Objects.equals(argument.nextToken(),
token);
}
}
+
+ private static class DescribeSecretRequestMatcher implements
ArgumentMatcher<DescribeSecretRequest> {
+
+ private final String secretId;
+
+ private DescribeSecretRequestMatcher(final String secretId) {
+ this.secretId = secretId;
+ }
+
+ @Override
+ public boolean matches(final DescribeSecretRequest argument) {
+ return argument != null && argument.secretId().equals(secretId);
+ }
+ }
}