@Override
    public Future<String> getValue(String name) throws GuacamoleException {

        CompletableFuture<CachedSecret> refreshEntry;

        try {

            // Attempt to use cached result of previous call
            Future<CachedSecret> cachedEntry = cache.get(name);
            if (cachedEntry != null) {

                // Use cached result if not yet expired
                CachedSecret secret = cachedEntry.get();
                if (!secret.isExpired()) {
                    logger.debug("Using cached secret for \"{}\".", name);
                    return secret.getValue();
                }

                // Evict if expired
                else {
                    logger.debug("Cached secret for \"{}\" is expired.", name);
                    cache.remove(name, cachedEntry);
                }

            }

            // If no cached result, or result is too old, race with other
            // threads to be the thread which refreshes the entry
            refreshEntry = new CompletableFuture<>();
            cachedEntry = cache.putIfAbsent(name, refreshEntry);

            // If a refresh operation is already in progress, wait for that
            // operation to complete and use its value
            if (cachedEntry != null)
                return cachedEntry.get().getValue();

        }
        catch (InterruptedException | ExecutionException e) {
            throw new GuacamoleServerException("Attempt to retrieve secret "
                    + "failed.", e);
        }

        // If we reach this far, the cache entry is stale or missing, and it's
        // this thread's responsibility to refresh the entry
        try {
            CachedSecret secret = refreshCachedSecret(name);
            refreshEntry.complete(secret);
            logger.debug("Cached secret for \"{}\" will be refreshed.", name);
            return secret.getValue();
        }

        // Abort the refresh operation if an error occurs
        catch (Error | RuntimeException | GuacamoleException e) {
            refreshEntry.completeExceptionally(e);
            cache.remove(name, refreshEntry);
            logger.debug("Cached secret for \"{}\" could not be refreshed.", name);
            throw e;
        }

    }
Explicitly retrieves the value of the secret having the given name,
returning a result that can be cached. The length of time that this
specific value will be cached is determined by the TTL value provided to
the returned CachedSecret. This function will be automatically invoked
in response to calls to getValue() when the requested secret is either
not cached or has expired. Expired secrets are not removed from the
cache until another request is made for that secret.

@param name
    The name of the secret to retrieve.

@return
    A CachedSecret which defines the current value of the secret and the
    point in time that value should be considered potentially
    out-of-date.

@throws GuacamoleException
    If an error occurs while retrieving the secret from the vault.
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/CachedVaultSecretService.java