|
|
|
@ -5,7 +5,7 @@ |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* You may obtain a copy of the License at |
|
|
|
* |
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
@ -18,10 +18,11 @@ package org.thingsboard.server.dao.tenant; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.hibernate.exception.ConstraintViolationException; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.cache.Cache; |
|
|
|
import org.springframework.cache.CacheManager; |
|
|
|
import org.springframework.cache.annotation.Cacheable; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Propagation; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.transaction.event.TransactionalEventListener; |
|
|
|
import org.thingsboard.server.common.data.EntityInfo; |
|
|
|
import org.thingsboard.server.common.data.TenantProfile; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
@ -30,49 +31,57 @@ import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
|
|
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; |
|
|
|
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|
|
|
import org.thingsboard.server.dao.entity.AbstractCachedEntityService; |
|
|
|
import org.thingsboard.server.dao.exception.DataValidationException; |
|
|
|
import org.thingsboard.server.dao.service.DataValidator; |
|
|
|
import org.thingsboard.server.dao.service.PaginatedRemover; |
|
|
|
import org.thingsboard.server.dao.service.Validator; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import static org.thingsboard.server.common.data.CacheConstants.TENANT_PROFILE_CACHE; |
|
|
|
import static org.thingsboard.server.dao.service.Validator.validateId; |
|
|
|
|
|
|
|
@Service |
|
|
|
@Slf4j |
|
|
|
public class TenantProfileServiceImpl extends AbstractEntityService implements TenantProfileService { |
|
|
|
public class TenantProfileServiceImpl extends AbstractCachedEntityService<TenantProfileCacheKey, TenantProfile, TenantProfileEvictEvent> implements TenantProfileService { |
|
|
|
|
|
|
|
private static final String INCORRECT_TENANT_PROFILE_ID = "Incorrect tenantProfileId "; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private TenantProfileDao tenantProfileDao; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private CacheManager cacheManager; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private DataValidator<TenantProfile> tenantProfileValidator; |
|
|
|
|
|
|
|
@Cacheable(cacheNames = TENANT_PROFILE_CACHE, key = "{#tenantProfileId.id}") |
|
|
|
@TransactionalEventListener(classes = TenantProfileEvictEvent.class) |
|
|
|
@Override |
|
|
|
public void handleEvictEvent(TenantProfileEvictEvent event) { |
|
|
|
List<TenantProfileCacheKey> keys = new ArrayList<>(2); |
|
|
|
keys.add(TenantProfileCacheKey.fromId(event.getTenantProfileId())); |
|
|
|
if (event.isDefaultProfile()) { |
|
|
|
keys.add(TenantProfileCacheKey.defaultProfile()); |
|
|
|
} |
|
|
|
cache.evict(keys); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId) { |
|
|
|
log.trace("Executing findTenantProfileById [{}]", tenantProfileId); |
|
|
|
Validator.validateId(tenantProfileId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); |
|
|
|
return tenantProfileDao.findById(tenantId, tenantProfileId.getId()); |
|
|
|
return cache.getAndPutInTransaction(TenantProfileCacheKey.fromId(tenantProfileId), |
|
|
|
() -> tenantProfileDao.findById(tenantId, tenantProfileId.getId()), true); |
|
|
|
} |
|
|
|
|
|
|
|
@Cacheable(cacheNames = TENANT_PROFILE_CACHE, key = "{'info', #tenantProfileId.id}") |
|
|
|
@Override |
|
|
|
public EntityInfo findTenantProfileInfoById(TenantId tenantId, TenantProfileId tenantProfileId) { |
|
|
|
log.trace("Executing findTenantProfileInfoById [{}]", tenantProfileId); |
|
|
|
Validator.validateId(tenantProfileId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); |
|
|
|
return tenantProfileDao.findTenantProfileInfoById(tenantId, tenantProfileId.getId()); |
|
|
|
TenantProfile profile = findTenantProfileById(tenantId, tenantProfileId); |
|
|
|
return profile == null ? null : new EntityInfo(profile.getId(), profile.getName()); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public TenantProfile saveTenantProfile(TenantId tenantId, TenantProfile tenantProfile) { |
|
|
|
log.trace("Executing saveTenantProfile [{}]", tenantProfile); |
|
|
|
@ -80,6 +89,7 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T |
|
|
|
TenantProfile savedTenantProfile; |
|
|
|
try { |
|
|
|
savedTenantProfile = tenantProfileDao.save(tenantId, tenantProfile); |
|
|
|
publishEvictEvent(new TenantProfileEvictEvent(savedTenantProfile.getId(), savedTenantProfile.isDefault())); |
|
|
|
} catch (Exception t) { |
|
|
|
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|
|
|
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("tenant_profile_name_unq_key")) { |
|
|
|
@ -88,16 +98,10 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T |
|
|
|
throw t; |
|
|
|
} |
|
|
|
} |
|
|
|
Cache cache = cacheManager.getCache(TENANT_PROFILE_CACHE); |
|
|
|
cache.evict(Collections.singletonList(savedTenantProfile.getId().getId())); |
|
|
|
cache.evict(Arrays.asList("info", savedTenantProfile.getId().getId())); |
|
|
|
if (savedTenantProfile.isDefault()) { |
|
|
|
cache.evict(Collections.singletonList("default")); |
|
|
|
cache.evict(Arrays.asList("default", "info")); |
|
|
|
} |
|
|
|
return savedTenantProfile; |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public void deleteTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { |
|
|
|
log.trace("Executing deleteTenantProfile [{}]", tenantProfileId); |
|
|
|
@ -121,13 +125,7 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T |
|
|
|
} |
|
|
|
} |
|
|
|
deleteEntityRelations(tenantId, tenantProfileId); |
|
|
|
Cache cache = cacheManager.getCache(TENANT_PROFILE_CACHE); |
|
|
|
cache.evict(Collections.singletonList(tenantProfileId.getId())); |
|
|
|
cache.evict(Arrays.asList("info", tenantProfileId.getId())); |
|
|
|
if (isDefault) { |
|
|
|
cache.evict(Collections.singletonList("default")); |
|
|
|
cache.evict(Arrays.asList("default", "info")); |
|
|
|
} |
|
|
|
publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, isDefault)); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@ -163,47 +161,43 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T |
|
|
|
return defaultTenantProfile; |
|
|
|
} |
|
|
|
|
|
|
|
@Cacheable(cacheNames = TENANT_PROFILE_CACHE, key = "{'default'}") |
|
|
|
@Override |
|
|
|
public TenantProfile findDefaultTenantProfile(TenantId tenantId) { |
|
|
|
log.trace("Executing findDefaultTenantProfile"); |
|
|
|
return tenantProfileDao.findDefaultTenantProfile(tenantId); |
|
|
|
return cache.getAndPutInTransaction(TenantProfileCacheKey.defaultProfile(), |
|
|
|
() -> tenantProfileDao.findDefaultTenantProfile(tenantId), true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Cacheable(cacheNames = TENANT_PROFILE_CACHE, key = "{'default', 'info'}") |
|
|
|
@Override |
|
|
|
public EntityInfo findDefaultTenantProfileInfo(TenantId tenantId) { |
|
|
|
log.trace("Executing findDefaultTenantProfileInfo"); |
|
|
|
return tenantProfileDao.findDefaultTenantProfileInfo(tenantId); |
|
|
|
var tenantProfile = findDefaultTenantProfile(tenantId); |
|
|
|
return tenantProfile == null ? null : new EntityInfo(tenantProfile.getId(), tenantProfile.getName()); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public boolean setDefaultTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { |
|
|
|
log.trace("Executing setDefaultTenantProfile [{}]", tenantProfileId); |
|
|
|
validateId(tenantId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); |
|
|
|
TenantProfile tenantProfile = tenantProfileDao.findById(tenantId, tenantProfileId.getId()); |
|
|
|
if (!tenantProfile.isDefault()) { |
|
|
|
Cache cache = cacheManager.getCache(TENANT_PROFILE_CACHE); |
|
|
|
tenantProfile.setDefault(true); |
|
|
|
TenantProfile previousDefaultTenantProfile = findDefaultTenantProfile(tenantId); |
|
|
|
boolean changed = false; |
|
|
|
if (previousDefaultTenantProfile == null) { |
|
|
|
tenantProfileDao.save(tenantId, tenantProfile); |
|
|
|
publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, true)); |
|
|
|
changed = true; |
|
|
|
} else if (!previousDefaultTenantProfile.getId().equals(tenantProfile.getId())) { |
|
|
|
previousDefaultTenantProfile.setDefault(false); |
|
|
|
tenantProfileDao.save(tenantId, previousDefaultTenantProfile); |
|
|
|
tenantProfileDao.save(tenantId, tenantProfile); |
|
|
|
cache.evict(Collections.singletonList(previousDefaultTenantProfile.getId().getId())); |
|
|
|
cache.evict(Arrays.asList("info", previousDefaultTenantProfile.getId().getId())); |
|
|
|
publishEvictEvent(new TenantProfileEvictEvent(previousDefaultTenantProfile.getId(), false)); |
|
|
|
publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, true)); |
|
|
|
changed = true; |
|
|
|
} |
|
|
|
if (changed) { |
|
|
|
cache.evict(Collections.singletonList(tenantProfile.getId().getId())); |
|
|
|
cache.evict(Arrays.asList("info", tenantProfile.getId().getId())); |
|
|
|
cache.evict(Collections.singletonList("default")); |
|
|
|
cache.evict(Arrays.asList("default", "info")); |
|
|
|
} |
|
|
|
return changed; |
|
|
|
} |
|
|
|
return false; |
|
|
|
@ -216,7 +210,7 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T |
|
|
|
} |
|
|
|
|
|
|
|
private final PaginatedRemover<String, TenantProfile> tenantProfilesRemover = |
|
|
|
new PaginatedRemover<String, TenantProfile>() { |
|
|
|
new PaginatedRemover<>() { |
|
|
|
|
|
|
|
@Override |
|
|
|
protected PageData<TenantProfile> findEntities(TenantId tenantId, String id, PageLink pageLink) { |
|
|
|
|