Browse Source

Cache for VersionControlSettings

pull/6597/head
Andrii Shvaika 4 years ago
parent
commit
5bb9bdface
  1. 2
      application/src/main/java/org/thingsboard/server/service/session/SessionRedisCache.java
  2. 66
      application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java
  3. 98
      application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultTbVersionControlSettingsService.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java
  5. 31
      application/src/main/java/org/thingsboard/server/service/sync/vc/TbVersionControlSettingsService.java
  6. 36
      application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlSettingsCaffeineCache.java
  7. 41
      application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlSettingsRedisCache.java
  8. 3
      application/src/main/resources/thingsboard.yml
  9. 1
      common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java

2
application/src/main/java/org/thingsboard/server/service/session/SessionRedisCache.java

@ -33,7 +33,7 @@ import org.thingsboard.server.gen.transport.TransportProtos;
public class SessionRedisCache extends RedisTbTransactionalCache<DeviceId, TransportProtos.DeviceSessionsCacheEntry> {
public SessionRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ASSET_CACHE, cacheSpecsMap, connectionFactory, configuration, new RedisSerializer<>() {
super(CacheConstants.SESSIONS_CACHE, cacheSpecsMap, connectionFactory, configuration, new RedisSerializer<>() {
@Override
public byte[] serialize(TransportProtos.DeviceSessionsCacheEntry deviceSessionsCacheEntry) throws SerializationException {
return deviceSessionsCacheEntry.toByteArray();

66
application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java

@ -25,9 +25,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.StringUtils;
@ -36,7 +34,6 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
@ -46,7 +43,6 @@ import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod;
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
import org.thingsboard.server.common.data.sync.vc.VersionLoadResult;
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
@ -61,7 +57,6 @@ import org.thingsboard.server.common.data.sync.vc.request.load.SingleEntityVersi
import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadConfig;
import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
@ -86,10 +81,10 @@ import java.util.stream.Collectors;
@Slf4j
public class DefaultEntitiesVersionControlService implements EntitiesVersionControlService {
private final TbVersionControlSettingsService vcSettingsService;
private final GitVersionControlQueueService gitServiceQueue;
private final EntitiesExportImportService exportImportService;
private final ExportableEntitiesService exportableEntitiesService;
private final AdminSettingsService adminSettingsService;
private final TransactionTemplate transactionTemplate;
private ListeningExecutorService executor;
@ -311,54 +306,24 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
@Override
public EntitiesVersionControlSettings getVersionControlSettings(TenantId tenantId) {
AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, SETTINGS_KEY);
if (adminSettings != null) {
try {
return JacksonUtil.convertValue(adminSettings.getJsonValue(), EntitiesVersionControlSettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load version control settings!", e);
}
}
return null;
return vcSettingsService.get(tenantId);
}
@Override
public EntitiesVersionControlSettings saveVersionControlSettings(TenantId tenantId, EntitiesVersionControlSettings versionControlSettings) {
AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, SETTINGS_KEY);
EntitiesVersionControlSettings storedSettings = null;
if (adminSettings != null) {
try {
storedSettings = JacksonUtil.convertValue(adminSettings.getJsonValue(), EntitiesVersionControlSettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load version control settings!", e);
}
}
versionControlSettings = this.restoreCredentials(versionControlSettings, storedSettings);
if (adminSettings == null) {
adminSettings = new AdminSettings();
adminSettings.setKey(SETTINGS_KEY);
adminSettings.setTenantId(tenantId);
}
versionControlSettings = this.vcSettingsService.restore(tenantId, versionControlSettings);
try {
//TODO: ashvayka: replace future.get with deferred result. Don't forget to call when tenant is deleted.
gitServiceQueue.initRepository(tenantId, versionControlSettings).get();
} catch (Exception e) {
throw new RuntimeException("Failed to init repository!", e);
}
adminSettings.setJsonValue(JacksonUtil.valueToTree(versionControlSettings));
AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings);
EntitiesVersionControlSettings savedVersionControlSettings;
try {
savedVersionControlSettings = JacksonUtil.convertValue(savedAdminSettings.getJsonValue(), EntitiesVersionControlSettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load version control settings!", e);
}
return savedVersionControlSettings;
return vcSettingsService.save(tenantId, versionControlSettings);
}
@Override
public void deleteVersionControlSettings(TenantId tenantId) throws Exception {
if (adminSettingsService.deleteAdminSettings(tenantId, SETTINGS_KEY)) {
if (vcSettingsService.delete(tenantId)) {
//TODO: ashvayka: replace future.get with deferred result. Don't forget to call when tenant is deleted.
gitServiceQueue.clearRepository(tenantId).get();
}
@ -366,8 +331,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
@Override
public void checkVersionControlAccess(TenantId tenantId, EntitiesVersionControlSettings settings) throws ThingsboardException {
EntitiesVersionControlSettings storedSettings = getVersionControlSettings(tenantId);
settings = this.restoreCredentials(settings, storedSettings);
settings = this.vcSettingsService.restore(tenantId, settings);
try {
//TODO: ashvayka: replace future.get with deferred result.
gitServiceQueue.testRepository(tenantId, settings).get();
@ -379,7 +343,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
private String getCauseMessage(Exception e) {
String message;
if(e.getCause() != null && StringUtils.isNotEmpty(e.getCause().getMessage())){
if (e.getCause() != null && StringUtils.isNotEmpty(e.getCause().getMessage())) {
message = e.getCause().getMessage();
} else {
message = e.getMessage();
@ -387,20 +351,4 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
return message;
}
private EntitiesVersionControlSettings restoreCredentials(EntitiesVersionControlSettings settings, EntitiesVersionControlSettings storedSettings) {
VersionControlAuthMethod authMethod = settings.getAuthMethod();
if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(authMethod) && settings.getPassword() == null) {
if (storedSettings != null) {
settings.setPassword(storedSettings.getPassword());
}
} else if (VersionControlAuthMethod.PRIVATE_KEY.equals(authMethod) && settings.getPrivateKey() == null) {
if (storedSettings != null) {
settings.setPrivateKey(storedSettings.getPrivateKey());
if (settings.getPrivateKeyPassword() == null) {
settings.setPrivateKeyPassword(storedSettings.getPrivateKeyPassword());
}
}
}
return settings;
}
}

98
application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultTbVersionControlSettingsService.java

@ -0,0 +1,98 @@
/**
* Copyright © 2016-2022 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.service.sync.vc;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cache.TbTransactionalCache;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.queue.util.TbCoreComponent;
@Service
@TbCoreComponent
@RequiredArgsConstructor
public class DefaultTbVersionControlSettingsService implements TbVersionControlSettingsService {
public static final String SETTINGS_KEY = "entitiesVersionControl";
private final AdminSettingsService adminSettingsService;
private final TbTransactionalCache<TenantId, EntitiesVersionControlSettings> cache;
@Override
public EntitiesVersionControlSettings restore(TenantId tenantId, EntitiesVersionControlSettings settings) {
EntitiesVersionControlSettings storedSettings = get(tenantId);
if (storedSettings != null) {
VersionControlAuthMethod authMethod = settings.getAuthMethod();
if (VersionControlAuthMethod.USERNAME_PASSWORD.equals(authMethod) && settings.getPassword() == null) {
settings.setPassword(storedSettings.getPassword());
} else if (VersionControlAuthMethod.PRIVATE_KEY.equals(authMethod) && settings.getPrivateKey() == null) {
settings.setPrivateKey(storedSettings.getPrivateKey());
if (settings.getPrivateKeyPassword() == null) {
settings.setPrivateKeyPassword(storedSettings.getPrivateKeyPassword());
}
}
}
return settings;
}
@Override
public EntitiesVersionControlSettings get(TenantId tenantId) {
return cache.getAndPutInTransaction(tenantId, () -> {
AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, SETTINGS_KEY);
if (adminSettings != null) {
try {
return JacksonUtil.convertValue(adminSettings.getJsonValue(), EntitiesVersionControlSettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load version control settings!", e);
}
}
return null;
}, true);
}
@Override
public EntitiesVersionControlSettings save(TenantId tenantId, EntitiesVersionControlSettings versionControlSettings) {
AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, SETTINGS_KEY);
if (adminSettings == null) {
adminSettings = new AdminSettings();
adminSettings.setKey(SETTINGS_KEY);
adminSettings.setTenantId(tenantId);
}
adminSettings.setJsonValue(JacksonUtil.valueToTree(versionControlSettings));
AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings);
EntitiesVersionControlSettings savedVersionControlSettings;
try {
savedVersionControlSettings = JacksonUtil.convertValue(savedAdminSettings.getJsonValue(), EntitiesVersionControlSettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load version control settings!", e);
}
//API calls to adminSettingsService are not in transaction, so we can simply evict the cache.
cache.evict(tenantId);
return savedVersionControlSettings;
}
@Override
public boolean delete(TenantId tenantId) {
boolean result = adminSettingsService.deleteAdminSettings(tenantId, SETTINGS_KEY);
cache.evict(tenantId);
return result;
}
}

2
application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java

@ -36,8 +36,6 @@ import java.util.concurrent.ExecutionException;
public interface EntitiesVersionControlService {
String SETTINGS_KEY = "entitiesVersionControl";
ListenableFuture<VersionCreationResult> saveEntitiesVersion(SecurityUser user, VersionCreateRequest request) throws Exception;
ListenableFuture<PageData<EntityVersion>> listEntityVersions(TenantId tenantId, String branch, EntityId externalId, PageLink pageLink) throws Exception;

31
application/src/main/java/org/thingsboard/server/service/sync/vc/TbVersionControlSettingsService.java

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2022 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.service.sync.vc;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
public interface TbVersionControlSettingsService {
EntitiesVersionControlSettings restore(TenantId tenantId, EntitiesVersionControlSettings versionControlSettings);
EntitiesVersionControlSettings get(TenantId tenantId);
EntitiesVersionControlSettings save(TenantId tenantId, EntitiesVersionControlSettings versionControlSettings);
boolean delete(TenantId tenantId);
}

36
application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlSettingsCaffeineCache.java

@ -0,0 +1,36 @@
/**
* Copyright © 2016-2022 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.service.sync.vc;
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.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
import org.thingsboard.server.gen.transport.TransportProtos;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true)
@Service("VersionControlCache")
public class VersionControlSettingsCaffeineCache extends CaffeineTbTransactionalCache<TenantId, EntitiesVersionControlSettings> {
public VersionControlSettingsCaffeineCache(CacheManager cacheManager) {
super(cacheManager, CacheConstants.VC_SETTINGS_CACHE);
}
}

41
application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlSettingsRedisCache.java

@ -0,0 +1,41 @@
/**
* Copyright © 2016-2022 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.service.sync.vc;
import com.google.protobuf.InvalidProtocolBufferException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
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.TbRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
import org.thingsboard.server.gen.transport.TransportProtos;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@Service("VersionControlCache")
public class VersionControlSettingsRedisCache extends RedisTbTransactionalCache<TenantId, EntitiesVersionControlSettings> {
public VersionControlSettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.VC_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbRedisSerializer<>());
}
}

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

@ -433,6 +433,9 @@ cache:
edges:
timeToLiveInMinutes: "${CACHE_SPECS_EDGES_TTL:1440}"
maxSize: "${CACHE_SPECS_EDGES_MAX_SIZE:10000}"
vcSettings:
timeToLiveInMinutes: "${CACHE_SPECS_VC_SETTINGS_TTL:1440}"
maxSize: "${CACHE_SPECS_VC_SETTINGS_MAX_SIZE:10000}"
redis:
# standalone or cluster

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

@ -31,4 +31,5 @@ public class CacheConstants {
public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime";
public static final String OTA_PACKAGE_CACHE = "otaPackages";
public static final String OTA_PACKAGE_DATA_CACHE = "otaPackagesData";
public static final String VC_SETTINGS_CACHE = "vcSettings";
}

Loading…
Cancel
Save