Browse Source

Remove cache

pull/14074/head
Andrii Landiak 1 year ago
parent
commit
7b114d9092
  1. 3
      application/src/main/resources/thingsboard.yml
  2. 1
      common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
  3. 40
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyCacheKey.java
  4. 33
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyCaffeineCache.java
  5. 4
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyDao.java
  6. 19
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyEvictEvent.java
  7. 36
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyRedisCache.java
  8. 30
      dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyServiceImpl.java
  9. 18
      dao/src/main/java/org/thingsboard/server/dao/sql/pat/ApiKeyRepository.java
  10. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/pat/JpaApiKeyDao.java

3
application/src/main/resources/thingsboard.yml

@ -666,9 +666,6 @@ cache:
aiModel:
timeToLiveInMinutes: "${CACHE_SPECS_AI_MODEL_TTL:1440}" # AI model cache TTL
maxSize: "${CACHE_SPECS_AI_MODEL_MAX_SIZE:10000}" # 0 means the cache is disabled
apiKeys:
timeToLiveInMinutes: "${CACHE_SPECS_API_KEYS_TTL:1440}" # API keys cache TTL
maxSize: "${CACHE_SPECS_API_KEYS_MAX_SIZE:10000}" # 0 means the cache is disabled
# Deliberately placed outside the 'specs' group above
notificationRules:

1
common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java

@ -40,7 +40,6 @@ public final class CacheConstants {
public static final String SENT_NOTIFICATIONS_CACHE = "sentNotifications";
public static final String TRENDZ_SETTINGS_CACHE = "trendzSettings";
public static final String AI_MODEL_CACHE = "aiModel";
public static final String API_KEYS_CACHE = "apiKeys";
public static final String ASSET_PROFILE_CACHE = "assetProfiles";
public static final String ATTRIBUTES_CACHE = "attributes";

40
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyCacheKey.java

@ -1,40 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.pat;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.Serializable;
import static java.util.Objects.requireNonNull;
record ApiKeyCacheKey(String hash) implements Serializable {
ApiKeyCacheKey {
requireNonNull(hash);
}
static ApiKeyCacheKey of(String hash) {
return new ApiKeyCacheKey(hash);
}
@NonNull
@Override
public String toString() {
return /* cache name */ "_" + hash;
}
}

33
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyCaffeineCache.java

@ -1,33 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.pat;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.thingsboard.server.cache.CaffeineTbTransactionalCache;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.pat.ApiKey;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true)
@Service("ApiKeyCache")
public class ApiKeyCaffeineCache extends CaffeineTbTransactionalCache<ApiKeyCacheKey, ApiKey> {
public ApiKeyCaffeineCache(CacheManager cacheManager) {
super(cacheManager, CacheConstants.API_KEYS_CACHE);
}
}

4
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyDao.java

@ -26,9 +26,9 @@ public interface ApiKeyDao extends Dao<ApiKey> {
ApiKey findByHash(String hash);
Set<String> deleteByTenantId(TenantId tenantId);
void deleteByTenantId(TenantId tenantId);
Set<String> deleteByUserId(TenantId tenantId, UserId userId);
void deleteByUserId(TenantId tenantId, UserId userId);
int deleteAllByExpirationTimeBefore(long ts);

19
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyEvictEvent.java

@ -1,19 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.pat;
public record ApiKeyEvictEvent(String hash) {
}

36
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyRedisCache.java

@ -1,36 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.pat;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Service;
import org.thingsboard.server.cache.CacheSpecsMap;
import org.thingsboard.server.cache.RedisTbTransactionalCache;
import org.thingsboard.server.cache.TBRedisCacheConfiguration;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.pat.ApiKey;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@Service("ApiKeyCache")
public class ApiKeyRedisCache extends RedisTbTransactionalCache<ApiKeyCacheKey, ApiKey> {
public ApiKeyRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.API_KEYS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(ApiKey.class));
}
}

30
dao/src/main/java/org/thingsboard/server/dao/pat/ApiKeyServiceImpl.java

@ -18,7 +18,6 @@ package org.thingsboard.server.dao.pat;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.ApiKeyId;
@ -30,12 +29,10 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.pat.ApiKey;
import org.thingsboard.server.common.data.pat.ApiKeyInfo;
import org.thingsboard.server.dao.entity.AbstractCachedEntityService;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.service.validator.ApiKeyDataValidator;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.dao.service.Validator.validateId;
@ -45,7 +42,7 @@ import static org.thingsboard.server.dao.user.UserServiceImpl.INCORRECT_USER_ID;
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiKeyServiceImpl extends AbstractCachedEntityService<ApiKeyCacheKey, ApiKey, ApiKeyEvictEvent> implements ApiKeyService {
public class ApiKeyServiceImpl extends AbstractEntityService implements ApiKeyService {
private static final String INCORRECT_API_KEY_ID = "Incorrect ApiKeyId ";
private static final int DEFAULT_API_KEY_BYTES = 32;
@ -54,12 +51,6 @@ public class ApiKeyServiceImpl extends AbstractCachedEntityService<ApiKeyCacheKe
private final ApiKeyInfoDao apiKeyInfoDao;
private final ApiKeyDataValidator apiKeyValidator;
@Override
@TransactionalEventListener
public void handleEvictEvent(ApiKeyEvictEvent event) {
cache.evict(ApiKeyCacheKey.of(event.hash()));
}
@Override
public ApiKey saveApiKey(TenantId tenantId, ApiKeyInfo apiKeyInfo) {
log.trace("Executing saveApiKey [{}]", apiKeyInfo);
@ -72,12 +63,7 @@ public class ApiKeyServiceImpl extends AbstractCachedEntityService<ApiKeyCacheKe
} else {
apiKey.setHash(old.getHash());
}
var savedApiKey = apiKeyDao.save(tenantId, apiKey);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedApiKey.getId()).entity(savedApiKey).created(apiKey.getId() == null).build());
if (old != null && old.isEnabled() != apiKey.isEnabled()) {
publishEvictEvent(new ApiKeyEvictEvent(apiKey.getHash()));
}
return savedApiKey;
return apiKeyDao.save(tenantId, apiKey);
} catch (Exception e) {
checkConstraintViolation(e, "api_hash_unq_key", "Api Key with such hash already exists!");
throw e;
@ -121,30 +107,26 @@ public class ApiKeyServiceImpl extends AbstractCachedEntityService<ApiKeyCacheKe
return;
}
apiKeyDao.removeById(tenantId, apiKeyId);
publishEvictEvent(new ApiKeyEvictEvent(apiKey.getHash()));
}
@Override
public void deleteByTenantId(TenantId tenantId) {
log.trace("Executing deleteApiKeysByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, id -> INCORRECT_TENANT_ID + id);
Set<String> hashes = apiKeyDao.deleteByTenantId(tenantId);
hashes.forEach(hash -> publishEvictEvent(new ApiKeyEvictEvent(hash)));
apiKeyDao.deleteByTenantId(tenantId);
}
@Override
public void deleteByUserId(TenantId tenantId, UserId userId) {
log.trace("Executing deleteApiKeysByUserId, tenantId [{}]", tenantId);
validateId(userId, id -> INCORRECT_USER_ID + id);
Set<String> hashes = apiKeyDao.deleteByUserId(tenantId, userId);
hashes.forEach(hash -> publishEvictEvent(new ApiKeyEvictEvent(hash)));
apiKeyDao.deleteByUserId(tenantId, userId);
}
@Override
public ApiKey findApiKeyByHash(String hash) {
log.trace("Executing findApiKeyByHash [{}]", hash);
var cacheKey = ApiKeyCacheKey.of(hash);
return cache.getAndPutInTransaction(cacheKey, () -> apiKeyDao.findByHash(hash), true);
return apiKeyDao.findByHash(hash);
}
private static String generateApiKeySecret() {

18
dao/src/main/java/org/thingsboard/server/dao/sql/pat/ApiKeyRepository.java

@ -31,23 +31,13 @@ public interface ApiKeyRepository extends JpaRepository<ApiKeyEntity, UUID> {
@Transactional
@Modifying
@Query(value = """
DELETE FROM api_key
WHERE tenant_id = :tenantId
RETURNING hash
""", nativeQuery = true
)
Set<String> deleteByTenantId(@Param("tenantId") UUID tenantId);
@Query("DELETE FROM ApiKeyEntity ak WHERE ak.tenantId = :tenantId")
void deleteByTenantId(@Param("tenantId") UUID tenantId);
@Transactional
@Modifying
@Query(value = """
DELETE FROM api_key
WHERE tenant_id = :tenantId AND user_id = :userId
RETURNING hash
""", nativeQuery = true
)
Set<String> deleteByUserId(@Param("tenantId") UUID tenantId,
@Query("DELETE FROM ApiKeyEntity ak WHERE ak.tenantId = :tenantId AND ak.userId = :userId")
void deleteByUserId(@Param("tenantId") UUID tenantId,
@Param("userId") UUID userId);
@Transactional

8
dao/src/main/java/org/thingsboard/server/dao/sql/pat/JpaApiKeyDao.java

@ -46,13 +46,13 @@ public class JpaApiKeyDao extends JpaAbstractDao<ApiKeyEntity, ApiKey> implement
}
@Override
public Set<String> deleteByTenantId(TenantId tenantId) {
return apiKeyRepository.deleteByTenantId(tenantId.getId());
public void deleteByTenantId(TenantId tenantId) {
apiKeyRepository.deleteByTenantId(tenantId.getId());
}
@Override
public Set<String> deleteByUserId(TenantId tenantId, UserId userId) {
return apiKeyRepository.deleteByUserId(tenantId.getId(), userId.getId());
public void deleteByUserId(TenantId tenantId, UserId userId) {
apiKeyRepository.deleteByUserId(tenantId.getId(), userId.getId());
}
@Override

Loading…
Cancel
Save