private void validateCache() throws GuacamoleException {

        long currentTime = System.currentTimeMillis();

        // Perform a read-only check that the cache has actually expired before
        // continuing
        cacheLock.readLock().lock();
        try {
            if (currentTime - cacheTimestamp < cacheInterval)
                return;
        }
        finally {
            cacheLock.readLock().unlock();
        }

        cacheLock.writeLock().lock();
        try {

            // Cache may have been updated since the read-only check. Re-verify
            // that the cache has expired before continuing with a full refresh
            if (currentTime - cacheTimestamp < cacheInterval)
                return;

            // Attempt to pull all records first, allowing that operation to
            // succeed/fail BEFORE we clear out the last cached success
            KeeperSecrets secrets = SecretsManager.getSecrets(ksmConfig);
            List<KeeperRecord> records = secrets.getRecords();

            // Store all secrets within cache
            cachedSecrets = secrets;

            // Clear unambiguous cache of all records by UID
            cachedRecordsByUid.clear();

            // Clear cache of host-based records
            cachedAmbiguousHosts.clear();
            cachedRecordsByHost.clear();

            // Clear cache of login-based records
            cachedAmbiguousUsers.clear();
            cachedRecordsByUser.clear();

            // Clear cache of domain-based records
            cachedAmbiguousDomains.clear();
            cachedRecordsByDomain.clear();

            // Parse configuration
            final boolean shouldSplitUsernames = confService.getSplitWindowsUsernames();
            final boolean shouldMatchByDomain = confService.getMatchUserRecordsByDomain();

            // Store all records, sorting each into host-based, login-based,
            // and domain-based buckets
            records.forEach(record -> {

                // Store based on UID ...
                cachedRecordsByUid.put(record.getRecordUid(), record);

                // ... and hostname/address
                String hostname = recordService.getHostname(record);
                addRecordForHost(record, hostname);

                // ... and domain
                String domain = recordService.getDomain(record);
                addRecordForDomain(record, domain);

                // Get the username off of the record
                String username = recordService.getUsername(record);

                // If we have a username, and there isn't already a domain explicitly defined
                if (username != null && domain == null && shouldSplitUsernames) {

                    // Attempt to split out the domain of the username
                    WindowsUsername usernameAndDomain = (
                            WindowsUsername.splitWindowsUsernameFromDomain(username));

                    // Use the username-split domain if available
                    if (usernameAndDomain.hasDomain()) {
                        domain = usernameAndDomain.getDomain();
                        username = usernameAndDomain.getUsername();
                        addRecordForDomain(record, domain);
                    }

                }

                // If domain matching is not enabled for user records,
                // explicitly set all domains to null to allow matching
                // on username only
                if (!shouldMatchByDomain)
                    domain = null;

                // Store based on login ONLY if no hostname (will otherwise
                // result in ambiguous entries for servers tied to identical
                // accounts)
                if (hostname == null)
                    addRecordForLogin(record, username, domain);

            });

            // Cache has been refreshed
            this.cacheTimestamp = System.currentTimeMillis();

        }
        finally {
            cacheLock.writeLock().unlock();
        }

    }
Validates that all cached data is current with respect to
{@link #cacheInterval}, refreshing data from the server as needed.

@throws GuacamoleException
    If an error occurs preventing the cached data from being refreshed.
extensions/guacamole-vault/modules/guacamole-vault-ksm/src/main/java/org/apache/guacamole/vault/ksm/secret/KsmClient.java