Browse Source

Merge branch 'feature/entities-version-control' of github.com:thingsboard/thingsboard into feature/entities-version-control

pull/6615/head
Igor Kulikov 4 years ago
parent
commit
c8abe3ac95
  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. 4
      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
  10. 2
      common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java
  11. 17
      common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java
  12. 1
      docker/.env
  13. 1
      docker/.gitignore
  14. 6
      docker/docker-compose.confluent.yml
  15. 10
      docker/docker-compose.kafka.yml
  16. 10
      docker/docker-compose.postgres.volumes.yml
  17. 33
      docker/docker-compose.pubsub.yml
  18. 32
      docker/docker-compose.rabbitmq.yml
  19. 30
      docker/docker-compose.service-bus.yml
  20. 32
      docker/docker-compose.yml
  21. 2
      docker/docker-create-log-folders.sh
  22. 2
      docker/tb-vc-executor.env
  23. 51
      docker/tb-vc-executor/conf/logback.xml
  24. 23
      docker/tb-vc-executor/conf/tb-vc-executor.conf
  25. 10
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java
  26. 3
      msa/vc-executor-docker/docker/Dockerfile

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;
}
}

4
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;
@ -50,10 +48,8 @@ public interface EntitiesVersionControlService {
ListenableFuture<List<VersionedEntityInfo>> listAllEntitiesAtVersion(TenantId tenantId, String branch, String versionId) throws Exception;
ListenableFuture<List<VersionLoadResult>> loadEntitiesVersion(SecurityUser user, VersionLoadRequest request) throws Exception;
ListenableFuture<List<String>> listBranches(TenantId tenantId) throws Exception;
EntitiesVersionControlSettings getVersionControlSettings(TenantId tenantId);

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";
}

2
common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java

@ -54,7 +54,7 @@ public class HashPartitionService implements PartitionService {
private String coreTopic;
@Value("${queue.core.partitions:100}")
private Integer corePartitions;
@Value("${queue.vc.topic}")
@Value("${queue.vc.topic:tb_version_control}")
private String vcTopic;
@Value("${queue.vc.partitions:10}")
private Integer vcPartitions;

17
common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java

@ -189,8 +189,9 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
ToVersionControlServiceMsg msg = msgWrapper.getValue();
var ctx = new VersionControlRequestCtx(msg, msg.hasClearRepositoryRequest() ? null : getEntitiesVersionControlSettings(msg));
long startTs = System.currentTimeMillis();
log.trace("[{}][{}] Submitting task.", ctx.getTenantId(), ctx.getRequestId());
ListenableFuture<Void> future = ioThreads.get(ctx.getTenantId().hashCode() % ioPoolSize).submit(() -> processMessage(ctx, msg));
log.trace("[{}][{}] RECEIVED task: {}", ctx.getTenantId(), ctx.getRequestId(), msg);
int threadIdx = Math.abs(ctx.getTenantId().hashCode() % ioPoolSize);
ListenableFuture<Void> future = ioThreads.get(threadIdx).submit(() -> processMessage(ctx, msg));
logTaskExecution(ctx, future, startTs);
futures.add(future);
}
@ -444,13 +445,17 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
.setRequestIdMSB(ctx.getRequestId().getMostSignificantBits())
.setRequestIdLSB(ctx.getRequestId().getLeastSignificantBits());
if (e.isPresent()) {
log.debug("[{}][{}] Failed to process task", ctx.getTenantId(), ctx.getRequestId(), e.get());
builder.setError(e.get().getMessage());
}
if (enrichFunction != null) {
builder = enrichFunction.apply(builder);
} else {
builder.setGenericResponse(TransportProtos.GenericRepositoryResponseMsg.newBuilder().build());
if (enrichFunction != null) {
builder = enrichFunction.apply(builder);
} else {
builder.setGenericResponse(TransportProtos.GenericRepositoryResponseMsg.newBuilder().build());
}
log.debug("[{}][{}] Processed task", ctx.getTenantId(), ctx.getRequestId());
}
ToCoreNotificationMsg msg = ToCoreNotificationMsg.newBuilder().setVcResponseMsg(builder).build();
log.trace("[{}][{}] PUSHING reply: {} to: {}", ctx.getTenantId(), ctx.getRequestId(), msg, tpi);
producer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);

1
docker/.env

@ -10,6 +10,7 @@ HTTP_TRANSPORT_DOCKER_NAME=tb-http-transport
COAP_TRANSPORT_DOCKER_NAME=tb-coap-transport
LWM2M_TRANSPORT_DOCKER_NAME=tb-lwm2m-transport
SNMP_TRANSPORT_DOCKER_NAME=tb-snmp-transport
TB_VC_EXECUTOR_DOCKER_NAME=tb-vc-executor
TB_VERSION=latest

1
docker/.gitignore

@ -5,4 +5,5 @@ tb-node/db/**
tb-node/postgres/**
tb-node/cassandra/**
tb-transports/*/log
tb-vc-executor/log/**
!.env

6
docker/docker-compose.confluent.yml

@ -61,3 +61,9 @@ services:
tb-snmp-transport:
env_file:
- queue-confluent.env
tb-vc-executor1:
env_file:
- queue-confluent.env
tb-vc-executor2:
env_file:
- queue-confluent.env

10
docker/docker-compose.kafka.yml

@ -90,3 +90,13 @@ services:
- queue-kafka.env
depends_on:
- kafka
tb-vc-executor1:
env_file:
- queue-kafka.env
depends_on:
- kafka
tb-vc-executor2:
env_file:
- queue-kafka.env
depends_on:
- kafka

10
docker/docker-compose.postgres.volumes.yml

@ -53,6 +53,13 @@ services:
tb-snmp-transport:
volumes:
- tb-snmp-transport-log-volume:/var/log/tb-snmp-transport
tb-vc-executor1:
volumes:
- tb-vc-executor-log-volume:/var/log/tb-vc-executor
tb-vc-executor2:
volumes:
- tb-vc-executor-log-volume:/var/log/tb-vc-executor
volumes:
postgres-db-volume:
@ -76,3 +83,6 @@ volumes:
tb-snmp-transport-log-volume:
external: true
name: ${TB_SNMP_TRANSPORT_LOG_VOLUME}
tb-vc-executor-log-volume:
external: true
name: ${TB_VC_EXECUTOR_LOG_VOLUME}

33
docker/docker-compose.pubsub.yml

@ -23,59 +23,40 @@ services:
tb-core1:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
- redis
tb-core2:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
- redis
tb-rule-engine1:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
- redis
tb-rule-engine2:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
- redis
tb-mqtt-transport1:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-mqtt-transport2:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-http-transport1:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-http-transport2:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-coap-transport:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-lwm2m-transport:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-snmp-transport:
env_file:
- queue-pubsub.env
depends_on:
- zookeeper
tb-vc-executor1:
env_file:
- queue-pubsub.env
tb-vc-executor2:
env_file:
- queue-pubsub.env

32
docker/docker-compose.rabbitmq.yml

@ -23,59 +23,39 @@ services:
tb-core1:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
- redis
tb-core2:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
- redis
tb-rule-engine1:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
- redis
tb-rule-engine2:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
- redis
tb-mqtt-transport1:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-mqtt-transport2:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-http-transport1:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-http-transport2:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-coap-transport:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-lwm2m-transport:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-snmp-transport:
env_file:
- queue-rabbitmq.env
depends_on:
- zookeeper
tb-vc-executor1:
env_file:
- queue-rabbitmq.env
tb-vc-executor2:
env_file:
- queue-rabbitmq.env

30
docker/docker-compose.service-bus.yml

@ -23,57 +23,39 @@ services:
tb-core1:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
- redis
tb-core2:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
- redis
tb-rule-engine1:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
- redis
tb-rule-engine2:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
- redis
tb-mqtt-transport1:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-mqtt-transport2:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-http-transport1:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-http-transport2:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-coap-transport:
env_file:
- queue-service-bus.env
tb-lwm2m-transport:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-snmp-transport:
env_file:
- queue-service-bus.env
depends_on:
- zookeeper
tb-vc-executor1:
env_file:
- queue-service-bus.env
tb-vc-executor2:
env_file:
- queue-service-bus.env

32
docker/docker-compose.yml

@ -257,6 +257,38 @@ services:
- "8080"
env_file:
- tb-web-ui.env
tb-vc-executor1:
restart: always
image: "${DOCKER_REPO}/${TB_VC_EXECUTOR_DOCKER_NAME}:${TB_VERSION}"
ports:
- "8081"
environment:
TB_SERVICE_ID: tb-vc-executor1
env_file:
- tb-vc-executor.env
volumes:
- ./tb-vc-executor/conf:/config
- ./tb-vc-executor/log:/var/log/tb-vc-executor
depends_on:
- zookeeper
- tb-core1
- tb-core2
tb-vc-executor2:
restart: always
image: "${DOCKER_REPO}/${TB_VC_EXECUTOR_DOCKER_NAME}:${TB_VERSION}"
ports:
- "8081"
environment:
TB_SERVICE_ID: tb-vc-executor2
env_file:
- tb-vc-executor.env
volumes:
- ./tb-vc-executor/conf:/config
- ./tb-vc-executor/log:/var/log/tb-vc-executor
depends_on:
- zookeeper
- tb-core1
- tb-core2
haproxy:
restart: always
container_name: "${LOAD_BALANCER_NAME}"

2
docker/docker-create-log-folders.sh

@ -26,3 +26,5 @@ mkdir -p tb-transports/http/log && sudo chown -R 799:799 tb-transports/http/log
mkdir -p tb-transports/mqtt/log && sudo chown -R 799:799 tb-transports/mqtt/log
mkdir -p tb-transports/snmp/log && sudo chown -R 799:799 tb-transports/snmp/log
mkdir -p tb-vc-executor/log && sudo chown -R 799:799 tb-vc-executor/log

2
docker/tb-vc-executor.env

@ -0,0 +1,2 @@
ZOOKEEPER_ENABLED=true
ZOOKEEPER_URL=zookeeper:2181

51
docker/tb-vc-executor/conf/logback.xml

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->
<!DOCTYPE configuration>
<configuration scan="true" scanPeriod="10 seconds">
<appender name="fileLogAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/tb-vc-executor/${TB_SERVICE_ID}/tb-vc-executor.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/var/log/tb-vc-executor/${TB_SERVICE_ID}/tb-vc-executor.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.thingsboard.server.queue" level="INFO" />
<logger name="org.thingsboard.server" level="TRACE" />
<root level="INFO">
<appender-ref ref="fileLogAppender"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>

23
docker/tb-vc-executor/conf/tb-vc-executor.conf

@ -0,0 +1,23 @@
#
# 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.
#
export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/tb-vc-executor/${TB_SERVICE_ID}-gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/tb-vc-executor/${TB_SERVICE_ID}-heapdump.bin"
export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
export JAVA_OPTS="$JAVA_OPTS -XX:+ExitOnOutOfMemoryError"
export LOG_FILENAME=tb-vc-executor.out
export LOADER_PATH=/usr/share/tb-vc-executor/conf

10
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java

@ -34,6 +34,7 @@ public class ThingsBoardDbInstaller extends ExternalResource {
private final static String TB_HTTP_TRANSPORT_LOG_VOLUME = "tb-http-transport-log-test-volume";
private final static String TB_MQTT_TRANSPORT_LOG_VOLUME = "tb-mqtt-transport-log-test-volume";
private final static String TB_SNMP_TRANSPORT_LOG_VOLUME = "tb-snmp-transport-log-test-volume";
private final static String TB_VC_EXECUTOR_LOG_VOLUME = "tb-vc-executor-log-test-volume";
private final DockerComposeExecutor dockerCompose;
@ -44,6 +45,7 @@ public class ThingsBoardDbInstaller extends ExternalResource {
private final String tbHttpTransportLogVolume;
private final String tbMqttTransportLogVolume;
private final String tbSnmpTransportLogVolume;
private final String tbVcExecutorLogVolume;
private final Map<String, String> env;
public ThingsBoardDbInstaller() {
@ -61,6 +63,7 @@ public class ThingsBoardDbInstaller extends ExternalResource {
tbHttpTransportLogVolume = project + "_" + TB_HTTP_TRANSPORT_LOG_VOLUME;
tbMqttTransportLogVolume = project + "_" + TB_MQTT_TRANSPORT_LOG_VOLUME;
tbSnmpTransportLogVolume = project + "_" + TB_SNMP_TRANSPORT_LOG_VOLUME;
tbVcExecutorLogVolume = project + "_" + TB_VC_EXECUTOR_LOG_VOLUME;
dockerCompose = new DockerComposeExecutor(composeFiles, project);
@ -72,6 +75,7 @@ public class ThingsBoardDbInstaller extends ExternalResource {
env.put("TB_HTTP_TRANSPORT_LOG_VOLUME", tbHttpTransportLogVolume);
env.put("TB_MQTT_TRANSPORT_LOG_VOLUME", tbMqttTransportLogVolume);
env.put("TB_SNMP_TRANSPORT_LOG_VOLUME", tbSnmpTransportLogVolume);
env.put("TB_VC_EXECUTOR_LOG_VOLUME", tbVcExecutorLogVolume);
dockerCompose.withEnv(env);
}
@ -104,6 +108,9 @@ public class ThingsBoardDbInstaller extends ExternalResource {
dockerCompose.withCommand("volume create " + tbSnmpTransportLogVolume);
dockerCompose.invokeDocker();
dockerCompose.withCommand("volume create " + tbVcExecutorLogVolume);
dockerCompose.invokeDocker();
dockerCompose.withCommand("up -d redis postgres");
dockerCompose.invokeCompose();
@ -126,10 +133,11 @@ public class ThingsBoardDbInstaller extends ExternalResource {
copyLogs(tbHttpTransportLogVolume, "./target/tb-http-transport-logs/");
copyLogs(tbMqttTransportLogVolume, "./target/tb-mqtt-transport-logs/");
copyLogs(tbSnmpTransportLogVolume, "./target/tb-snmp-transport-logs/");
copyLogs(tbVcExecutorLogVolume, "./target/tb-vc-executor-logs/");
dockerCompose.withCommand("volume rm -f " + postgresDataVolume + " " + tbLogVolume +
" " + tbCoapTransportLogVolume + " " + tbLwm2mTransportLogVolume + " " + tbHttpTransportLogVolume +
" " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume);
" " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume + " " + tbVcExecutorLogVolume);
dockerCompose.invokeDocker();
}

3
msa/vc-executor-docker/docker/Dockerfile

@ -18,6 +18,9 @@ FROM thingsboard/openjdk11
COPY start-tb-vc-executor.sh ${pkg.name}.deb /tmp/
RUN mkdir -p /home/thingsboard/.config/jgit
RUN chown -R ${pkg.user}:${pkg.user} /home/thingsboard
RUN chmod a+x /tmp/*.sh \
&& mv /tmp/start-tb-vc-executor.sh /usr/bin

Loading…
Cancel
Save