All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.sdk.cloudplatform.cache.CacheManager Maven / Gradle / Ivy

There is a newer version: 2.28.0
Show newest version
/*
 * Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
 */

package com.sap.cloud.sdk.cloudplatform.cache;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;

import org.slf4j.Logger;

import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableList;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.security.user.UserAccessor;
import com.sap.cloud.sdk.cloudplatform.security.user.exception.UserAccessException;
import com.sap.cloud.sdk.cloudplatform.security.user.exception.UserNotAuthenticatedException;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantAccessException;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantNotAvailableException;

/**
 * Grants bulk processing for all (statically) registered caches.
 */
public final class CacheManager
{
    private static final Logger logger = CloudLoggerFactory.getLogger(CacheManager.class);

    private static final List> cacheList = new ArrayList<>();

    /**
     * Getter for a list of all caches registered in the {@link CacheManager}.
     * 
     * @return The list of all caches.
     */
    @Nonnull
    public static ImmutableList> getCacheList()
    {
        return ImmutableList.copyOf(cacheList);
    }

    /**
     * Registers a cache at in the {@link CacheManager}.
     * 
     * @param cache
     *            The cache to be registered.
     * @param 
     *            The type of the values in the cache.
     * @return The given cache.
     */
    @Nonnull
    public static synchronized  Cache register( @Nonnull final Cache cache )
    {
        cacheList.add(cache);
        return cache;
    }

    /**
     * Cleans up all cache entries that have been invalidated.
     */
    public static void cleanUp()
    {
        for( final Cache cache : cacheList ) {
            cache.cleanUp();
        }

        if( logger.isInfoEnabled() ) {
            logger.info("Clean up of invalidated caches finished successfully.");
        }
    }

    /**
     * Invalidates all entries in all caches.
     *
     * @return The number of invalidated cache entries.
     */
    public static long invalidateAll()
    {
        long size = 0;

        for( final Cache cache : cacheList ) {
            size += cache.size();
            cache.invalidateAll();
        }

        if( logger.isInfoEnabled() ) {
            logger.info(
                "Successfully invalidated "
                    + size
                    + " "
                    + (size == 1 ? "entry" : "entries")
                    + " in "
                    + cacheList.size()
                    + " "
                    + (cacheList.size() == 1 ? "cache" : "caches")
                    + ".");
        }
        return size;
    }

    /**
     * Invalidates all caches of the current tenant.
     *
     * @return The number of invalidated cache entries.
     *
     * @throws TenantNotAvailableException
     *             If the current tenant is not available.
     * @throws TenantAccessException
     *             If there is an issue while accessing the current tenant.
     */
    public static long invalidateTenantCaches()
        throws TenantNotAvailableException,
            TenantAccessException
    {
        return invalidateTenantCaches(TenantAccessor.getCurrentTenant().getTenantId());
    }

    /**
     * Invalidates all caches of the given tenant.
     *
     * @param tenantId
     *            The tenant to invalidate all caches for.
     *
     * @return The number of invalidated cache entries.
     */
    public static long invalidateTenantCaches( final String tenantId )
    {
        long size = 0;

        for( final Cache cache : cacheList ) {
            final List keysToInvalidate = new ArrayList<>();

            for( final CacheKey cacheKey : cache.asMap().keySet() ) {
                if( logger.isDebugEnabled() ) {
                    logger.debug("Checking cache invalidation for tenant '" + tenantId + "': " + cacheKey + ".");
                }

                if( tenantId.equals(cacheKey.getTenantId().orElse(null)) ) {
                    keysToInvalidate.add(cacheKey);
                }
            }

            if( logger.isDebugEnabled() ) {
                logger.debug("Invalidating caches of tenant '" + tenantId + "': " + keysToInvalidate + ".");
            }

            size += keysToInvalidate.size();
            cache.invalidateAll(keysToInvalidate);
        }

        logger.info("Successfully invalidated caches of tenant '" + tenantId + "': " + size + ".");
        return size;
    }

    /**
     * Invalidates all caches of the current user.
     *
     * @return The number of invalidated cache entries.
     *
     * @throws TenantNotAvailableException
     *             If the current tenant is not available.
     * @throws TenantAccessException
     *             If there is an issue while accessing the current tenant.
     * @throws UserNotAuthenticatedException
     *             If the current user is not authenticated.
     * @throws UserAccessException
     *             If there is an issue while accessing the current user.
     */
    public static long invalidateUserCaches()
        throws TenantNotAvailableException,
            TenantAccessException,
            UserNotAuthenticatedException,
            UserAccessException
    {
        return invalidateUserCaches(
            TenantAccessor.getCurrentTenant().getTenantId(),
            UserAccessor.getCurrentUser().getName());
    }

    /**
     * Invalidates all caches of the given user.
     *
     * @param tenantId
     *            The Id of the tenant for which all user caches should be invalidated.
     * @param userName
     *            The name of the user for which all caches should be invalidated.
     *
     * @return The number of invalidated cache entries.
     */
    public static long invalidateUserCaches( final String tenantId, final String userName )
    {
        long size = 0;

        for( final Cache cache : cacheList ) {
            if( logger.isDebugEnabled() ) {
                logger.debug("Invalidating user cache entries.");
            }
            size += invalidateUserEntries(tenantId, userName, cache);
        }

        logger.info(
            "Successfully invalidated caches of user '" + userName + "' within tenant '" + tenantId + "': " + size);
        return size;
    }

    /**
     * Invalidates all cache entries of the current tenant-specific user.
     *
     * @param cache
     *            The cache in which all caches of the current user should be invalidated.
     *
     * @return The number of invalidated cache entries.
     *
     * @throws TenantNotAvailableException
     *             If the current tenant is not available.
     * @throws TenantAccessException
     *             If there is an issue while accessing the current tenant.
     * @throws UserNotAuthenticatedException
     *             If the current user is not authenticated.
     * @throws UserAccessException
     *             If there is an issue while accessing the current user.
     */
    public static long invalidateUserEntries( final Cache cache )
        throws TenantNotAvailableException,
            TenantAccessException,
            UserNotAuthenticatedException,
            UserAccessException
    {
        return invalidateUserEntries(
            TenantAccessor.getCurrentTenant().getTenantId(),
            UserAccessor.getCurrentUser().getName(),
            cache);
    }

    /**
     * Invalidates all cache entries of the given tenant-specific user.
     *
     * @param tenantId
     *            The Id of the tenant for which all user cache emtries should be invalidated.
     * @param userName
     *            The name of the user for which all cache entries should be invalidated.
     * @param cache
     *            The cache in which the entries of the user should be invalidated.
     *
     * @return The number of invalidated cache entries.
     */
    public static
        long
        invalidateUserEntries( final String tenantId, final String userName, final Cache cache )
    {
        final List keysToInvalidate = new ArrayList<>();

        for( final CacheKey cacheKey : cache.asMap().keySet() ) {
            if( logger.isDebugEnabled() ) {
                logger.debug(
                    "Checking invalidation "
                        + " for user '"
                        + userName
                        + "' within tenant '"
                        + tenantId
                        + "': "
                        + cacheKey);
            }

            final boolean isEqualTenantId = tenantId.equals(cacheKey.getTenantId().orElse(null));
            final boolean isEqualUserName = userName.equals(cacheKey.getUserName().orElse(null));

            if( isEqualTenantId && isEqualUserName ) {
                keysToInvalidate.add(cacheKey);
            }
        }

        if( logger.isDebugEnabled() ) {
            logger.debug(
                "Invalidating caches of user '" + userName + "' within tenant '" + tenantId + "': " + keysToInvalidate);
        }

        final long size = keysToInvalidate.size();
        cache.invalidateAll(keysToInvalidate);
        return size;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy