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

com.sap.cloud.sdk.cloudplatform.cache.CacheKey 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.Arrays;
import java.util.Optional;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

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;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

/**
 * CacheKey with either global visibility, tenant isolation, or tenant & user isolation.
 */
@EqualsAndHashCode
@ToString
public final class CacheKey
{
    @Nullable
    private final String tenantId;

    @Nullable
    private final String userName;

    @Getter
    private final ArrayList components = new ArrayList<>();

    /**
     * Getter for the Id of the tenant for which the key is used.
     * 
     * @return The tenant Id.
     */
    @Nonnull
    public Optional getTenantId()
    {
        return Optional.ofNullable(tenantId);
    }

    /**
     * Getter for the name of the user for which the key is used.
     * 
     * @return The user name.
     */
    @Nonnull
    public Optional getUserName()
    {
        return Optional.ofNullable(userName);
    }

    private CacheKey( @Nullable final String tenantId, @Nullable final String userName )
    {
        this.tenantId = tenantId;
        this.userName = userName;
    }

    /**
     * Appends the given Objects to this instance. In order to compare cache keys, {@link Object#equals(Object)} and
     * {@link Object#hashCode()} are used. The given objects must not be {@code null}.
     *
     * @param objects
     *            Additional objects that should be used to identify a cache key.
     *
     * @throws IllegalArgumentException
     *             If any of the given objects is {@code null}.
     *
     * @return This instance with the objects added.
     */
    @Nonnull
    public CacheKey append( @Nonnull final Iterable objects )
        throws IllegalArgumentException
    {
        for( final Object object : objects ) {
            if( object == null ) {
                throw new IllegalArgumentException("Object must not be null.");
            }
            components.add(object);
        }
        return this;
    }

    /**
     * Appends the given Objects to this instance. In order to compare cache keys, {@link Object#equals(Object)} and
     * {@link Object#hashCode()} are used. The given objects must not be {@code null}.
     *
     * @param objects
     *            Additional objects that should be used to identify a cache key.
     *
     * @throws IllegalArgumentException
     *             If any of the given objects is {@code null}.
     *
     * @return This instance with the objects added.
     */
    @Nonnull
    public CacheKey append( @Nonnull final Object... objects )
        throws IllegalArgumentException
    {
        append(Arrays.asList(objects));
        return this;
    }

    /**
     * Constructs a {@link CacheKey} for the given tenant identifier and user name, independent of whether they are
     * {@code null} or not. This provides the highest flexibility for defining different levels of isolation.
     *
     * @param tenantId
     *            The identifier of the tenant. If {@code null}, there is not tenant isolation.
     * @param userName
     *            The name of the user. If {@code null}, there is no user isolation.
     *
     * @return A new {@link CacheKey} constructed from the given tenant identifier and user name.
     */
    @Nonnull
    public static CacheKey of( @Nullable final String tenantId, @Nullable final String userName )
    {
        return new CacheKey(tenantId, userName);
    }

    /**
     * Constructs an instance of {@link CacheKey} without tenant or user isolation. This can be used to share a cache
     * globally within the application.
     *
     * @return A new {@link CacheKey} without isolation.
     */
    @Nonnull
    public static CacheKey ofNoIsolation()
    {
        return of(null, null);
    }

    /**
     * Constructs a tenant-isolated instance of {@link CacheKey}. This can be used to share a cache among the users of a
     * tenant.
     * 

* When using this method, the tenant isolation is strictly enforced. This means that if the tenant is not * available, an exception is thrown. * * @throws TenantNotAvailableException * If the tenant is not available. This typically occurs when trying to access the tenant within code * that is running outside any tenant context, e.g., within a background task. * * @throws TenantAccessException * If there is an issue while accessing the tenant. * * @return A new {@link CacheKey} with tenant isolation based on the current tenant. */ @Nonnull public static CacheKey ofTenantIsolation() throws TenantNotAvailableException, TenantAccessException { return of(TenantAccessor.getCurrentTenant().getTenantId(), null); } /** * Constructs a tenant- and user-isolated instance of {@link CacheKey}. *

* When using this method, the tenant and user isolation is strictly enforced. This means that if the tenant is not * available or the user is not authenticated, an exception is thrown. * * @throws TenantNotAvailableException * If the tenant is not available. This typically occurs when trying to access the tenant within code * that is running outside any tenant context, e.g., within a background task. * * @throws TenantAccessException * If there is an issue while accessing the tenant. * * @throws UserNotAuthenticatedException * If the user is not authenticated. * * @throws UserAccessException * If there is an issue while accessing the user. * * @return A new {@link CacheKey} with tenant and user isolation based on the current tenant and user. */ @Nonnull public static CacheKey ofTenantAndUserIsolation() throws TenantNotAvailableException, TenantAccessException, UserNotAuthenticatedException, UserAccessException { return of(TenantAccessor.getCurrentTenant().getTenantId(), UserAccessor.getCurrentUser().getName()); } }