package eu.eudat.commons.scope.tenant; import eu.eudat.data.tenant.TenantScopedBaseEntity; import jakarta.persistence.EntityManager; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; import javax.management.InvalidApplicationException; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; @Component @RequestScope public class TenantScope { public static final String TenantReplaceParameter = "::TenantCode::"; private final MultitenancyProperties multitenancy; private final AtomicReference tenant = new AtomicReference<>(); private final AtomicReference tenantCode = new AtomicReference<>(); private final AtomicReference initialTenant = new AtomicReference<>(); private final AtomicReference initialTenantCode = new AtomicReference<>(); @Autowired public TenantScope(MultitenancyProperties multitenancy) { this.multitenancy = multitenancy; } public Boolean isMultitenant() { return multitenancy.isMultitenant(); } public String getDefaultTenantCode() { return multitenancy.getDefaultTenantCode(); } public Boolean isSet() { if (!this.isMultitenant()) return Boolean.TRUE; return this.tenant.get() != null || this.isDefaultTenant(); } public Boolean isDefaultTenant() { if (!this.isMultitenant()) return Boolean.TRUE; return this.multitenancy.getDefaultTenantCode().equalsIgnoreCase(this.tenantCode.get()); } public UUID getTenant() throws InvalidApplicationException { if (!this.isMultitenant()) return null; if (this.tenant.get() == null && !this.isDefaultTenant()) throw new InvalidApplicationException("tenant not set"); return this.isDefaultTenant() ? null : this.tenant.get(); } public String getTenantCode() throws InvalidApplicationException { if (!this.isMultitenant()) return null; if (this.tenantCode.get() == null) throw new InvalidApplicationException("tenant not set"); return this.tenantCode.get(); } public void setTempTenant(EntityManager entityManager, UUID tenant, String tenantCode) { this.tenant.set(tenant); this.tenantCode.set(tenantCode); if (this.tenant.get() != null || this.isDefaultTenant()) { if(!this.isDefaultTenant()) { entityManager .unwrap(Session.class) .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); } else { entityManager .unwrap(Session.class) .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); } } } public void removeTempTenant(EntityManager entityManager) { this.tenant.set(this.initialTenant.get()); this.tenantCode.set(this.initialTenantCode.get()); if (this.initialTenant.get() != null || this.isDefaultTenant()) { if(!this.isDefaultTenant()) { entityManager .unwrap(Session.class) .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); } else { entityManager .unwrap(Session.class) .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); } } } public void setTenant(UUID tenant, String tenantCode) { if (this.isMultitenant()) { this.tenant.set(tenant); this.initialTenant.set(tenant); this.tenantCode.set(tenantCode); this.initialTenantCode.set(tenantCode); } } }