Skip to content

NIFI-15791 - Add per-secret TTL cache to ParameterProviderSecretsManager#11100

Merged
exceptionfactory merged 2 commits intoapache:mainfrom
pvillard31:NIFI-15791
Apr 6, 2026
Merged

NIFI-15791 - Add per-secret TTL cache to ParameterProviderSecretsManager#11100
exceptionfactory merged 2 commits intoapache:mainfrom
pvillard31:NIFI-15791

Conversation

@pvillard31
Copy link
Copy Markdown
Contributor

Summary

NIFI-15791 - Add per-secret TTL cache to ParameterProviderSecretsManager

Adds a TTL-based cache for resolved secret values in ParameterProviderSecretsManager to avoid redundant calls to ParameterProvider.fetchParameterValues() on every secret lookup. Each secret is cached independently by its fully qualified name and expires after a configurable TTL (default 5 minutes). Caching can be disabled by setting the TTL to 0 sec.

A follow-up improvement will be done to expose an API to invalidate the cache in case a user wants to force the refresh on the secrets while configuring a connector.

Changes

  • SecretsManager — Added invalidateCache() to support programmatic cache clearing.
  • SecretsManagerInitializationContext — Added getProperty(String) to receive configuration properties without coupling the API to NiFiProperties.
  • NiFiProperties — Added nifi.secrets.manager.cache.ttl property key.
  • StandardSecretsManagerInitializationContext — Extended to accept and expose an immutable properties map, implementing the new getProperty() method.
  • FlowController.createSecretsManager() — Reads the cache TTL from NiFiProperties and passes it through the initialization context.
  • ParameterProviderSecretsManager — Core caching implementation:
    • Per-secret ConcurrentHashMap cache keyed by FQN with individual timestamps.
    • TTL of 0 disables all cache reads and writes, preserving existing behavior.
    • getSecret() checks cache before calling the provider; getSecrets() partitions references into cache hits and misses, batch-fetching only the misses.
    • findProvider() refactored to accept a pre-fetched provider set to avoid redundant getSecretProviders() calls.
    • invalidateCache() clears all cached entries.

Tracking

Please complete the following tracking steps prior to pull request creation.

Issue Tracking

Pull Request Tracking

  • Pull Request title starts with Apache NiFi Jira issue number, such as NIFI-00000
  • Pull Request commit message starts with Apache NiFi Jira issue number, as such NIFI-00000
  • Pull request contains commits signed with a registered key indicating Verified status

Pull Request Formatting

  • Pull Request based on current revision of the main branch
  • Pull Request refers to a feature branch with one commit containing changes

Verification

Please indicate the verification steps performed prior to pull request creation.

Build

  • Build completed using ./mvnw clean install -P contrib-check
    • JDK 21
    • JDK 25

Licensing

  • New dependencies are compatible with the Apache License 2.0 according to the License Policy
  • New dependencies are documented in applicable LICENSE and NOTICE files

Documentation

  • Documentation formatting appears as expected in rendered files

Copy link
Copy Markdown
Contributor

@exceptionfactory exceptionfactory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together @pvillard31.

On initial review, it would be helpful to update the Administrator's Guide with documentation for the new application property.

Regarding the property name, what do you think about cache.duration or cache.expiration instead of cache.ttl? Using a word instead of the acronym seems a bit clearer, although TTL is more common than some acronyms.

@pvillard31
Copy link
Copy Markdown
Contributor Author

Thanks for the initial review. There is no documentation yet for Connectors but I added a section for the configuration of the Secrets Manager.

Copy link
Copy Markdown
Contributor

@exceptionfactory exceptionfactory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the renaming @pvillard31, I noted a few more more recommendations, and then this should be ready to go.

}

private boolean isExpired(final CachedSecret cached) {
return Duration.ofNanos(System.nanoTime() - cached.timestampNanos()).compareTo(cacheDuration) >= 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend breaking this out to multiple lines to declare intermediate variables for easier reading. It should also be possible to compare on Duration to another.

* @param key the property key
* @return the property value, or {@code null}
*/
String getProperty(String key);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend naming this getApplicationProperty() for clarity, since it sources from NiFi application properties.

Copy link
Copy Markdown
Contributor

@exceptionfactory exceptionfactory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the updates @pvillard31, the latest version looks good. +1 merging

@exceptionfactory exceptionfactory merged commit a671bc2 into apache:main Apr 6, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants