Browse Source

Merge branch 'YevhenBondarenko-feature/firmware' into feature/firmware

pull/4465/head
Andrii Shvaika 5 years ago
parent
commit
820fc4a9cd
  1. 1
      application/src/main/data/upgrade/3.2.2/schema_update.sql
  2. 6
      application/src/main/java/org/thingsboard/server/controller/FirmwareController.java
  3. 103
      application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java
  4. 3
      application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java
  5. 20
      application/src/main/java/org/thingsboard/server/service/firmware/FirmwareUpdateStatus.java
  6. 80
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  7. 2
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  8. 9
      application/src/main/resources/thingsboard.yml
  9. 2
      common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCacheReader.java
  10. 2
      common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCacheWriter.java
  11. 2
      common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareCacheWriter.java
  12. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
  13. 2
      common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
  14. 12
      common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java
  15. 11
      common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java
  16. 2
      common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java
  17. 2
      common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerTemplate.java
  18. 11
      common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java
  19. 18
      common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java
  20. 11
      common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java
  21. 20
      common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java
  22. 10
      common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java
  23. 26
      common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java
  24. 26
      common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java
  25. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java
  26. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java
  27. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java
  28. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java
  29. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java
  30. 12
      common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java
  31. 15
      common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java
  32. 3
      common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java
  33. 16
      common/queue/src/main/proto/queue.proto
  34. 14
      common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
  35. 2
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java
  36. 9
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  37. 58
      dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java
  38. 1
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  39. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java
  40. 41
      dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java
  41. 9
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
  42. 10
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
  43. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java
  44. 1
      dao/src/main/resources/sql/schema-entities-hsql.sql
  45. 1
      dao/src/main/resources/sql/schema-entities.sql
  46. 1
      dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java
  47. 7
      dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java
  48. 2
      transport/coap/src/main/java/org/thingsboard/server/coap/ThingsboardCoapTransportApplication.java
  49. 43
      transport/coap/src/main/resources/tb-coap-transport.yml
  50. 2
      transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java
  51. 43
      transport/http/src/main/resources/tb-http-transport.yml
  52. 36
      transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml
  53. 2
      transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java
  54. 43
      transport/mqtt/src/main/resources/tb-mqtt-transport.yml

1
application/src/main/data/upgrade/3.2.2/schema_update.sql

@ -70,6 +70,7 @@ CREATE TABLE IF NOT EXISTS firmware (
checksum_algorithm varchar(32),
checksum varchar(1020),
data bytea,
data_size bigint,
additional_info varchar,
search_text varchar(255),
CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)

6
application/src/main/java/org/thingsboard/server/controller/FirmwareController.java

@ -129,16 +129,18 @@ public class FirmwareController extends BaseController {
firmware.setVersion(info.getVersion());
firmware.setAdditionalInfo(info.getAdditionalInfo());
byte[] data = file.getBytes();
if (StringUtils.isEmpty(checksumAlgorithm)) {
checksumAlgorithm = "sha256";
checksum = Hashing.sha256().hashBytes(file.getBytes()).toString();
checksum = Hashing.sha256().hashBytes(data).toString();
}
firmware.setChecksumAlgorithm(checksumAlgorithm);
firmware.setChecksum(checksum);
firmware.setFileName(file.getOriginalFilename());
firmware.setContentType(file.getContentType());
firmware.setData(ByteBuffer.wrap(file.getBytes()));
firmware.setData(ByteBuffer.wrap(data));
firmware.setDataSize((long) data.length);
return firmwareService.saveFirmware(firmware);
} catch (Exception e) {
throw handleException(e);

103
application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.Firmware;
import org.thingsboard.server.common.data.FirmwareInfo;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId;
@ -34,16 +35,23 @@ import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.firmware.FirmwareService;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.TbCoreComponent;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM;
@ -61,12 +69,18 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
private final DeviceService deviceService;
private final DeviceProfileService deviceProfileService;
private final RuleEngineTelemetryService telemetryService;
private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer;
public DefaultFirmwareStateService(FirmwareService firmwareService, DeviceService deviceService, DeviceProfileService deviceProfileService, RuleEngineTelemetryService telemetryService) {
public DefaultFirmwareStateService(FirmwareService firmwareService,
DeviceService deviceService,
DeviceProfileService deviceProfileService,
RuleEngineTelemetryService telemetryService,
TbCoreQueueFactory coreQueueFactory) {
this.firmwareService = firmwareService;
this.deviceService = deviceService;
this.deviceProfileService = deviceProfileService;
this.telemetryService = telemetryService;
this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer();
}
@Override
@ -85,7 +99,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
if (!newFirmwareId.equals(oldFirmwareId)) {
// Device was updated and new firmware is different from previous firmware.
update(device, firmwareService.findFirmwareById(device.getTenantId(), newFirmwareId), System.currentTimeMillis());
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis());
}
} else {
// Device was updated and new firmware is not set.
@ -93,7 +107,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
} else if (newFirmwareId != null) {
// Device was created and firmware is defined.
update(device, firmwareService.findFirmwareById(device.getTenantId(), newFirmwareId), System.currentTimeMillis());
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis());
}
}
@ -103,9 +117,8 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
Consumer<Device> updateConsumer;
if (deviceProfile.getFirmwareId() != null) {
Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId());
long ts = System.currentTimeMillis();
updateConsumer = d -> update(d, firmware, ts);
updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts);
} else {
updateConsumer = this::remove;
}
@ -113,10 +126,9 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
PageLink pageLink = new PageLink(100);
PageData<Device> pageData;
do {
//TODO: create a query which will return devices without firmware
pageData = deviceService.findDevicesByTenantIdAndType(tenantId, deviceProfile.getName(), pageLink);
pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pageLink);
pageData.getData().stream().filter(d -> d.getFirmwareId() == null).forEach(updateConsumer);
pageData.getData().forEach(updateConsumer);
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -124,15 +136,80 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
} while (pageData.hasNext());
}
private void update(Device device, Firmware firmware, long ts) {
TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId();
@Override
public boolean process(ToFirmwareStateServiceMsg msg) {
boolean isSuccess = false;
FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB()));
DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB()));
TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
long ts = msg.getTs();
Device device = deviceService.findDeviceById(tenantId, deviceId);
if (device == null) {
log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId);
} else {
FirmwareId currentFirmwareId = device.getFirmwareId();
if (currentFirmwareId == null) {
currentFirmwareId = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()).getFirmwareId();
}
if (targetFirmwareId.equals(currentFirmwareId)) {
update(device, firmwareService.findFirmwareById(device.getTenantId(), targetFirmwareId), ts);
isSuccess = true;
} else {
log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetFirmwareId, currentFirmwareId);
}
}
return isSuccess;
}
private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts) {
ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder()
.setTenantIdMSB(tenantId.getId().getMostSignificantBits())
.setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
.setDeviceIdMSB(deviceId.getId().getMostSignificantBits())
.setDeviceIdLSB(deviceId.getId().getLeastSignificantBits())
.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits())
.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits())
.setTs(ts)
.build();
FirmwareInfo firmware = firmwareService.findFirmwareInfoById(tenantId, firmwareId);
if (firmware == null) {
log.warn("[{}] Failed to send firmware update because firmware was already deleted", firmwareId);
return;
}
TopicPartitionInfo tpi = new TopicPartitionInfo(fwStateMsgProducer.getDefaultTopic(), null, null, false);
fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
List<TsKvEntry> telemetry = new ArrayList<>();
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_TITLE, firmware.getTitle())));
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_VERSION, firmware.getVersion())));
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.QUEUED.name())));
telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() {
@Override
public void onSuccess(@Nullable Void tmp) {
log.trace("[{}] Success save firmware status!", deviceId);
}
@Override
public void onFailure(Throwable t) {
log.error("[{}] Failed to save firmware status!", deviceId, t);
}
});
}
private void update(Device device, FirmwareInfo firmware, long ts) {
TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId();
BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.INITIATED.name()));
telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() {
@Override
public void onSuccess(@Nullable Void tmp) {
log.trace("[{}] Success save telemetry with target firmware for device!", deviceId);
@ -149,7 +226,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_TITLE, firmware.getTitle())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_VERSION, firmware.getVersion())));
attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(FIRMWARE_SIZE, (long) firmware.getData().array().length)));
attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(FIRMWARE_SIZE, firmware.getDataSize())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM_ALGORITHM, firmware.getChecksumAlgorithm())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM, firmware.getChecksum())));
telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() {

3
application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.service.firmware;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
public interface FirmwareStateService {
@ -24,4 +25,6 @@ public interface FirmwareStateService {
void update(DeviceProfile deviceProfile);
boolean process(ToFirmwareStateServiceMsg msg);
}

20
application/src/main/java/org/thingsboard/server/service/firmware/FirmwareUpdateStatus.java

@ -0,0 +1,20 @@
/**
* Copyright © 2016-2021 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.firmware;
public enum FirmwareUpdateStatus {
QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
}

80
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -24,6 +24,7 @@ import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.server.actors.ActorSystemContext;
@ -35,7 +36,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.stats.StatsFactory;
import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
import org.thingsboard.server.gen.transport.TransportProtos.EdgeNotificationMsgProto;
import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
@ -49,6 +50,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseP
import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.queue.TbQueueConsumer;
@ -58,8 +60,8 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.edge.EdgeNotificationService;
import org.thingsboard.server.service.firmware.FirmwareStateService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.service.queue.processing.AbstractConsumerService;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
@ -97,6 +99,11 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
@Value("${queue.core.stats.enabled:false}")
private boolean statsEnabled;
@Value("${queue.core.firmware.pack-interval-ms:60000}")
private long firmwarePackInterval;
@Value("${queue.core.firmware.pack-size:100}")
private int firmwarePackSize;
private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> mainConsumer;
private final DeviceStateService stateService;
private final TbApiUsageStateService statsService;
@ -104,11 +111,15 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
private final SubscriptionManagerService subscriptionManagerService;
private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
private final EdgeNotificationService edgeNotificationService;
private final FirmwareStateService firmwareStateService;
private final TbCoreConsumerStats stats;
protected final TbQueueConsumer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> usageStatsConsumer;
private final TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> firmwareStatesConsumer;
protected volatile ExecutorService usageStatsExecutor;
private volatile ExecutorService firmwareStatesExecutor;
public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory,
ActorSystemContext actorContext,
DeviceStateService stateService,
@ -121,10 +132,12 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
TbApiUsageStateService statsService,
TbTenantProfileCache tenantProfileCache,
TbApiUsageStateService apiUsageStateService,
EdgeNotificationService edgeNotificationService) {
EdgeNotificationService edgeNotificationService,
FirmwareStateService firmwareStateService) {
super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, apiUsageStateService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer());
this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer();
this.firmwareStatesConsumer = tbCoreQueueFactory.createToFirmwareStateServiceMsgConsumer();
this.stateService = stateService;
this.localSubscriptionService = localSubscriptionService;
this.subscriptionManagerService = subscriptionManagerService;
@ -132,12 +145,14 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
this.edgeNotificationService = edgeNotificationService;
this.stats = new TbCoreConsumerStats(statsFactory);
this.statsService = statsService;
this.firmwareStateService = firmwareStateService;
}
@PostConstruct
public void init() {
super.init("tb-core-consumer", "tb-core-notifications-consumer");
this.usageStatsExecutor = Executors.newCachedThreadPool(ThingsBoardThreadFactory.forName("tb-core-usage-stats-consumer"));
this.usageStatsExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-usage-stats-consumer"));
this.firmwareStatesExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-firmware-notifications-consumer"));
}
@PreDestroy
@ -146,6 +161,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
if (usageStatsExecutor != null) {
usageStatsExecutor.shutdownNow();
}
if (firmwareStatesExecutor != null) {
firmwareStatesExecutor.shutdownNow();
}
}
@EventListener(ApplicationReadyEvent.class)
@ -153,6 +171,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
public void onApplicationEvent(ApplicationReadyEvent event) {
super.onApplicationEvent(event);
launchUsageStatsConsumer();
launchFirmwareUpdateNotificationConsumer();
}
@Override
@ -167,6 +186,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
.map(tpi -> tpi.newByTopic(usageStatsConsumer.getTopic()))
.collect(Collectors.toSet()));
}
this.firmwareStatesConsumer.subscribe();
}
@Override
@ -336,10 +356,59 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
});
}
private void launchFirmwareUpdateNotificationConsumer() {
long maxProcessingTimeoutPerRecord = firmwarePackInterval / firmwarePackSize;
firmwareStatesExecutor.submit(() -> {
while (!stopped) {
try {
List<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration());
if (msgs.isEmpty()) {
continue;
}
long timeToSleep = maxProcessingTimeoutPerRecord;
for (TbProtoQueueMsg<ToFirmwareStateServiceMsg> msg : msgs) {
try {
long startTime = System.currentTimeMillis();
boolean isSuccessUpdate = handleFirmwareUpdates(msg);
long endTime = System.currentTimeMillis();
long spentTime = endTime - startTime;
timeToSleep = timeToSleep - spentTime;
if (isSuccessUpdate) {
if (timeToSleep > 0) {
log.debug("Spent time per record is: [{}]!", spentTime);
Thread.sleep(timeToSleep);
timeToSleep = 0;
}
timeToSleep += maxProcessingTimeoutPerRecord;
}
} catch (Throwable e) {
log.warn("Failed to process firmware update msg: {}", msg, e);
}
}
firmwareStatesConsumer.commit();
} catch (Exception e) {
if (!stopped) {
log.warn("Failed to obtain usage stats from queue.", e);
try {
Thread.sleep(getNotificationPollDuration());
} catch (InterruptedException e2) {
log.trace("Failed to wait until the server has capacity to handle new firmware updates", e2);
}
}
}
}
log.info("TB Firmware States Consumer stopped.");
});
}
private void handleUsageStats(TbProtoQueueMsg<ToUsageStatsServiceMsg> msg, TbCallback callback) {
statsService.process(msg, callback);
}
private boolean handleFirmwareUpdates(TbProtoQueueMsg<ToFirmwareStateServiceMsg> msg) {
return firmwareStateService.process(msg.getValue());
}
private void forwardToCoreRpcService(FromDeviceRPCResponseProto proto, TbCallback callback) {
RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;
FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB())
@ -448,6 +517,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
if (usageStatsConsumer != null) {
usageStatsConsumer.unsubscribe();
}
if (firmwareStatesConsumer != null) {
firmwareStatesConsumer.unsubscribe();
}
}
}

2
application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java

@ -481,6 +481,8 @@ public class DefaultTransportApiService implements TransportApiService {
builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS);
builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits());
builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits());
builder.setTitle(firmware.getTitle());
builder.setVersion(firmware.getVersion());
builder.setFileName(firmware.getFileName());
builder.setContentType(firmware.getContentType());
firmwareCacheWriter.put(firmwareId.toString(), firmware.getData().array());

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

@ -744,6 +744,10 @@ queue:
sasl.mechanism: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM:PLAIN}"
sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}"
security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
consumer-properties-per-topic:
tb_firmware:
- key: max.poll.records
value: 10
other:
topic-properties:
rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
@ -751,6 +755,7 @@ queue:
transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1}"
fw-updates: "${TB_QUEUE_KAFKA_FW_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}"
consumer-stats:
enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}"
print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}"
@ -821,6 +826,10 @@ queue:
poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}"
firmware:
topic: "${TB_QUEUE_CORE_FW_TOPIC:tb_firmware}"
pack-interval-ms: "${TB_QUEUE_CORE_FW_PACK_INTERVAL_MS:60000}"
pack-size: "${TB_QUEUE_CORE_FW_PACK_SIZE:100}"
usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
stats:
enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}"

2
common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCacheReader.java

@ -22,7 +22,7 @@ import org.springframework.stereotype.Service;
import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE;
@Service
@ConditionalOnExpression("(('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport') && ('${cache.type:null}'=='caffeine' || '${cache.type:null}'=='caffeine')")
@ConditionalOnExpression("(('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport') && ('${cache.type:null}'=='caffeine' || '${cache.type:null}'=='null')")
public class CaffeineFirmwareCacheReader implements FirmwareCacheReader {
private final CacheManager cacheManager;

2
common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCacheWriter.java

@ -22,7 +22,7 @@ import org.springframework.stereotype.Service;
import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE;
@Service
@ConditionalOnExpression("(('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='core') && ('${cache.type:null}'=='caffeine' || '${cache.type:null}'=='caffeine')")
@ConditionalOnExpression("('${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core') && ('${cache.type:null}'=='caffeine' || '${cache.type:null}'=='null')")
public class CaffeineFirmwareCacheWriter implements FirmwareCacheWriter {
private final CacheManager cacheManager;

2
common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareCacheWriter.java

@ -21,7 +21,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Service;
@Service
@ConditionalOnExpression("(('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='core') && '${cache.type:null}'=='redis'")
@ConditionalOnExpression("('${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core') && '${cache.type:null}'=='redis'")
public class RedisFirmwareCacheWriter extends AbstractRedisFirmwareCache implements FirmwareCacheWriter {
public RedisFirmwareCacheWriter(RedisConnectionFactory redisConnectionFactory) {

2
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java

@ -61,6 +61,8 @@ public interface DeviceService {
PageData<Device> findDevicesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink);
PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
PageData<DeviceInfo> findDeviceInfosByTenantIdAndDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId, PageLink pageLink);

2
common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java

@ -99,7 +99,7 @@ public class DataConstants {
public static final String CURRENT_FIRMWARE_VERSION = "cur_fw_version";
public static final String TARGET_FIRMWARE_TITLE = "target_fw_title";
public static final String TARGET_FIRMWARE_VERSION = "target_fw_version";
public static final String CURRENT_FIRMWARE_STATE = "cur_fw_state";
public static final String FIRMWARE_STATE = "fw_state";
//attributes
//telemetry

12
common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java

@ -27,14 +27,6 @@ public class Firmware extends FirmwareInfo {
private static final long serialVersionUID = 3091601761339422546L;
private String fileName;
private String contentType;
private String checksumAlgorithm;
private String checksum;
private transient ByteBuffer data;
public Firmware() {
@ -47,10 +39,6 @@ public class Firmware extends FirmwareInfo {
public Firmware(Firmware firmware) {
super(firmware);
this.fileName = firmware.getFileName();
this.contentType = firmware.getContentType();
this.data = firmware.getData();
this.checksumAlgorithm = firmware.getChecksumAlgorithm();
this.checksum = firmware.getChecksum();
}
}

11
common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java

@ -32,6 +32,12 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
private String title;
private String version;
private boolean hasData;
private String fileName;
private String contentType;
private String checksumAlgorithm;
private String checksum;
private Long dataSize;
public FirmwareInfo() {
super();
@ -47,6 +53,11 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
this.title = firmwareInfo.getTitle();
this.version = firmwareInfo.getVersion();
this.hasData = firmwareInfo.isHasData();
this.fileName = firmwareInfo.getFileName();
this.contentType = firmwareInfo.getContentType();
this.checksumAlgorithm = firmwareInfo.getChecksumAlgorithm();
this.checksum = firmwareInfo.getChecksum();
this.dataSize = firmwareInfo.getDataSize();
}
@Override

2
common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java

@ -69,7 +69,7 @@ public class TbKafkaConsumerStatsService {
this.adminClient = AdminClient.create(kafkaSettings.toAdminProps());
this.statsPrintScheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("kafka-consumer-stats"));
Properties consumerProps = kafkaSettings.toConsumerProps();
Properties consumerProps = kafkaSettings.toConsumerProps(null);
consumerProps.put(ConsumerConfig.CLIENT_ID_CONFIG, "consumer-stats-loader-client");
consumerProps.put(ConsumerConfig.GROUP_ID_CONFIG, "consumer-stats-loader-client-group");
this.consumer = new KafkaConsumer<>(consumerProps);

2
common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerTemplate.java

@ -50,7 +50,7 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue
String clientId, String groupId, String topic,
TbQueueAdmin admin, TbKafkaConsumerStatsService statsService) {
super(topic);
Properties props = settings.toConsumerProps();
Properties props = settings.toConsumerProps(topic);
props.put(ConsumerConfig.CLIENT_ID_CONFIG, clientId);
if (groupId != null) {
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);

11
common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaSettings.java

@ -31,7 +31,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
@ -95,6 +97,9 @@ public class TbKafkaSettings {
@Setter
private List<TbKafkaProperty> other;
@Setter
private Map<String, List<TbKafkaProperty>> consumerPropertiesPerTopic = Collections.emptyMap();
public Properties toAdminProps() {
Properties props = toProps();
props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
@ -103,7 +108,7 @@ public class TbKafkaSettings {
return props;
}
public Properties toConsumerProps() {
public Properties toConsumerProps(String topic) {
Properties props = toProps();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
@ -113,6 +118,10 @@ public class TbKafkaSettings {
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class);
consumerPropertiesPerTopic
.getOrDefault(topic, Collections.emptyList())
.forEach(kv -> props.put(kv.getKey(), kv.getValue()));
return props;
}

18
common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java

@ -19,6 +19,7 @@ import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import javax.annotation.PostConstruct;
import java.util.HashMap;
@ -37,6 +38,8 @@ public class TbKafkaTopicConfigs {
private String notificationsProperties;
@Value("${queue.kafka.topic-properties.js-executor}")
private String jsExecutorProperties;
@Value("${queue.kafka.topic-properties.fw-updates:}")
private String fwUpdatesProperties;
@Getter
private Map<String, String> coreConfigs;
@ -48,6 +51,8 @@ public class TbKafkaTopicConfigs {
private Map<String, String> notificationsConfigs;
@Getter
private Map<String, String> jsExecutorConfigs;
@Getter
private Map<String, String> fwUpdatesConfigs;
@PostConstruct
private void init() {
@ -56,15 +61,18 @@ public class TbKafkaTopicConfigs {
transportApiConfigs = getConfigs(transportApiProperties);
notificationsConfigs = getConfigs(notificationsProperties);
jsExecutorConfigs = getConfigs(jsExecutorProperties);
fwUpdatesConfigs = getConfigs(fwUpdatesProperties);
}
private Map<String, String> getConfigs(String properties) {
Map<String, String> configs = new HashMap<>();
for (String property : properties.split(";")) {
int delimiterPosition = property.indexOf(":");
String key = property.substring(0, delimiterPosition);
String value = property.substring(delimiterPosition + 1);
configs.put(key, value);
if (StringUtils.isNotEmpty(properties)) {
for (String property : properties.split(";")) {
int delimiterPosition = property.indexOf(":");
String key = property.substring(0, delimiterPosition);
String value = property.substring(delimiterPosition + 1);
configs.put(key, value);
}
}
return configs;
}

11
common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java

@ -186,6 +186,17 @@ public class AwsSqsMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic());
}
@PreDestroy
private void destroy() {
if (coreAdmin != null) {

20
common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java

@ -21,12 +21,13 @@ import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
import org.thingsboard.server.queue.TbQueueAdmin;
@ -165,14 +166,25 @@ public class AwsSqsTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getUsageStatsTopic());
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgConsumer() {
public TbQueueConsumer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgConsumer() {
return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getUsageStatsTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), TransportProtos.ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic());
}
@PreDestroy

10
common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java

@ -130,6 +130,16 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
return new InMemoryTbQueueConsumer<>(coreSettings.getUsageStatsTopic());
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new InMemoryTbQueueConsumer<>(coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new InMemoryTbQueueProducer<>(coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new InMemoryTbQueueProducer<>(coreSettings.getUsageStatsTopic());

26
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -73,6 +74,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
private final TbQueueAdmin jsExecutorAdmin;
private final TbQueueAdmin transportApiAdmin;
private final TbQueueAdmin notificationAdmin;
private final TbQueueAdmin fwUpdatesAdmin;
public KafkaMonolithQueueFactory(PartitionService partitionService, TbKafkaSettings kafkaSettings,
TbServiceInfoProvider serviceInfoProvider,
@ -98,6 +100,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
this.jsExecutorAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getJsExecutorConfigs());
this.transportApiAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getTransportApiConfigs());
this.notificationAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getNotificationsConfigs());
this.fwUpdatesAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getFwUpdatesConfigs());
}
@Override
@ -273,6 +276,29 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
return consumerBuilder.build();
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder();
consumerBuilder.settings(kafkaSettings);
consumerBuilder.topic(coreSettings.getFirmwareTopic());
consumerBuilder.clientId("monolith-fw-consumer-" + serviceInfoProvider.getServiceId());
consumerBuilder.groupId("monolith-fw-consumer");
consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
consumerBuilder.admin(fwUpdatesAdmin);
consumerBuilder.statsService(consumerStatsService);
return consumerBuilder.build();
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
requestBuilder.settings(kafkaSettings);
requestBuilder.clientId("monolith-fw-producer-" + serviceInfoProvider.getServiceId());
requestBuilder.defaultTopic(coreSettings.getFirmwareTopic());
requestBuilder.admin(fwUpdatesAdmin);
return requestBuilder.build();
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToUsageStatsServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();

26
common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -70,6 +71,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
private final TbQueueAdmin jsExecutorAdmin;
private final TbQueueAdmin transportApiAdmin;
private final TbQueueAdmin notificationAdmin;
private final TbQueueAdmin fwUpdatesAdmin;
public KafkaTbCoreQueueFactory(PartitionService partitionService, TbKafkaSettings kafkaSettings,
TbServiceInfoProvider serviceInfoProvider,
@ -93,6 +95,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
this.jsExecutorAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getJsExecutorConfigs());
this.transportApiAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getTransportApiConfigs());
this.notificationAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getNotificationsConfigs());
this.fwUpdatesAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getFwUpdatesConfigs());
}
@Override
@ -241,6 +244,29 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
return consumerBuilder.build();
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder();
consumerBuilder.settings(kafkaSettings);
consumerBuilder.topic(coreSettings.getFirmwareTopic());
consumerBuilder.clientId("tb-core-fw-consumer-" + serviceInfoProvider.getServiceId());
consumerBuilder.groupId("tb-core-fw-consumer");
consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
consumerBuilder.admin(fwUpdatesAdmin);
consumerBuilder.statsService(consumerStatsService);
return consumerBuilder.build();
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
requestBuilder.settings(kafkaSettings);
requestBuilder.clientId("tb-core-fw-producer-" + serviceInfoProvider.getServiceId());
requestBuilder.defaultTopic(coreSettings.getFirmwareTopic());
requestBuilder.admin(fwUpdatesAdmin);
return requestBuilder.build();
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToUsageStatsServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java

@ -22,6 +22,7 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.*;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
@ -190,6 +191,17 @@ public class PubSubMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getUsageStatsTopic());

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -164,6 +165,17 @@ public class PubSubTbCoreQueueFactory implements TbCoreQueueFactory {
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getUsageStatsTopic());

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java

@ -24,6 +24,7 @@ import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -188,6 +189,17 @@ public class RabbitMqMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getUsageStatsTopic());

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -170,6 +171,17 @@ public class RabbitMqTbCoreQueueFactory implements TbCoreQueueFactory {
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getUsageStatsTopic());

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -187,6 +188,17 @@ public class ServiceBusMonolithQueueFactory implements TbCoreQueueFactory, TbRul
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getUsageStatsTopic());

12
common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@ -170,6 +171,17 @@ public class ServiceBusTbCoreQueueFactory implements TbCoreQueueFactory {
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToUsageStatsServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {
return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),
msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {
return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic());
}
@Override
public TbQueueProducer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgProducer() {
return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getUsageStatsTopic());

15
common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java

@ -16,6 +16,7 @@
package org.thingsboard.server.queue.provider;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
@ -85,6 +86,20 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory {
*/
TbQueueConsumer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> createToUsageStatsServiceMsgConsumer();
/**
* Used to consume messages about firmware update notifications by TB Core Service
*
* @return
*/
TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer();
/**
* Used to consume messages about firmware update notifications by TB Core Service
*
* @return
*/
TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer();
/**
* Used to consume high priority messages by TB Core Service
*

3
common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java

@ -26,6 +26,9 @@ public class TbQueueCoreSettings {
@Value("${queue.core.topic}")
private String topic;
@Value("${queue.core.firmware.topic:tb_firmware}")
private String firmwareTopic;
@Value("${queue.core.usage-stats-topic:tb_usage_stats}")
private String usageStatsTopic;

16
common/queue/src/main/proto/queue.proto

@ -363,8 +363,10 @@ message GetFirmwareResponseMsg {
ResponseStatus responseStatus = 1;
int64 firmwareIdMSB = 2;
int64 firmwareIdLSB = 3;
string contentType = 4;
string fileName = 5;
string title = 4;
string version = 5;
string contentType = 6;
string fileName = 7;
}
//Used to report session state to tb-Service and persist this state in the cache on the tb-Service level.
@ -663,3 +665,13 @@ message ToUsageStatsServiceMsg {
int64 customerIdMSB = 6;
int64 customerIdLSB = 7;
}
message ToFirmwareStateServiceMsg {
int64 ts = 1;
int64 tenantIdMSB = 2;
int64 tenantIdLSB = 3;
int64 deviceIdMSB = 4;
int64 deviceIdLSB = 5;
int64 firmwareIdMSB = 6;
int64 firmwareIdLSB = 7;
}

14
common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java

@ -207,6 +207,8 @@ public class DeviceApiController {
@RequestMapping(value = "/{deviceToken}/firmware", method = RequestMethod.GET)
public DeferredResult<ResponseEntity> getFirmware(@PathVariable("deviceToken") String deviceToken,
@RequestParam(value = "title") String title,
@RequestParam(value = "version") String version,
@RequestParam(value = "chunkSize", required = false, defaultValue = "0") int chunkSize,
@RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
@ -217,7 +219,7 @@ public class DeviceApiController {
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB()).build();
transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, chunkSize, chunk));
transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, title, version, chunkSize, chunk));
}));
return responseWriter;
}
@ -278,11 +280,15 @@ public class DeviceApiController {
private class GetFirmwareCallback implements TransportServiceCallback<TransportProtos.GetFirmwareResponseMsg> {
private final DeferredResult<ResponseEntity> responseWriter;
private final String title;
private final String version;
private final int chuckSize;
private final int chuck;
GetFirmwareCallback(DeferredResult<ResponseEntity> responseWriter, int chuckSize, int chuck) {
GetFirmwareCallback(DeferredResult<ResponseEntity> responseWriter, String title, String version, int chuckSize, int chuck) {
this.responseWriter = responseWriter;
this.title = title;
this.version = version;
this.chuckSize = chuckSize;
this.chuck = chuck;
}
@ -291,7 +297,7 @@ public class DeviceApiController {
public void onSuccess(TransportProtos.GetFirmwareResponseMsg firmwareResponseMsg) {
if (!TransportProtos.ResponseStatus.SUCCESS.equals(firmwareResponseMsg.getResponseStatus())) {
responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_FOUND));
} else {
} else if (title.equals(firmwareResponseMsg.getTitle()) && version.equals(firmwareResponseMsg.getVersion())) {
String firmwareId = new UUID(firmwareResponseMsg.getFirmwareIdMSB(), firmwareResponseMsg.getFirmwareIdLSB()).toString();
ByteArrayResource resource = new ByteArrayResource(transportContext.getFirmwareCacheReader().get(firmwareId, chuckSize, chuck));
ResponseEntity<ByteArrayResource> response = ResponseEntity.ok()
@ -301,6 +307,8 @@ public class DeviceApiController {
.contentType(parseMediaType(firmwareResponseMsg.getContentType()))
.body(resource);
responseWriter.setResult(response);
} else {
responseWriter.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
}
}

2
dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java

@ -81,6 +81,8 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao {
*/
PageData<Device> findDevicesByTenantIdAndType(UUID tenantId, String type, PageLink pageLink);
PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink);
/**
* Find device infos by tenantId, type and page link.
*

9
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -354,6 +354,15 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
return deviceDao.findDevicesByTenantIdAndType(tenantId.getId(), type, pageLink);
}
@Override
public PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink) {
log.trace("Executing findDevicesByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateString(type, "Incorrect type " + type);
validatePageLink(pageLink);
return deviceDao.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId.getId(), type, pageLink);
}
@Override
public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink) {
log.trace("Executing findDeviceInfosByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink);

58
dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java

@ -184,13 +184,7 @@ public class BaseFirmwareService implements FirmwareService {
protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) {
FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId());
if (!firmwareOld.getTitle().equals(firmware.getTitle())) {
throw new DataValidationException("Updating firmware title is prohibited!");
}
if (!firmwareOld.getVersion().equals(firmware.getVersion())) {
throw new DataValidationException("Updating firmware version is prohibited!");
}
BaseFirmwareService.validateUpdate(firmware, firmwareOld);
}
};
@ -261,35 +255,43 @@ public class BaseFirmwareService implements FirmwareService {
protected void validateUpdate(TenantId tenantId, Firmware firmware) {
Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId());
if (!firmwareOld.getTitle().equals(firmware.getTitle())) {
throw new DataValidationException("Updating firmware title is prohibited!");
}
BaseFirmwareService.validateUpdate(firmware, firmwareOld);
if (!firmwareOld.getVersion().equals(firmware.getVersion())) {
throw new DataValidationException("Updating firmware version is prohibited!");
if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) {
throw new DataValidationException("Updating firmware data is prohibited!");
}
}
};
if (firmwareOld.getFileName() != null && !firmwareOld.getFileName().equals(firmware.getFileName())) {
throw new DataValidationException("Updating firmware file name is prohibited!");
}
private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) {
if (!firmwareOld.getTitle().equals(firmware.getTitle())) {
throw new DataValidationException("Updating firmware title is prohibited!");
}
if (firmwareOld.getContentType() != null && !firmwareOld.getContentType().equals(firmware.getContentType())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
if (!firmwareOld.getVersion().equals(firmware.getVersion())) {
throw new DataValidationException("Updating firmware version is prohibited!");
}
if (firmwareOld.getChecksumAlgorithm() != null && !firmwareOld.getChecksumAlgorithm().equals(firmware.getChecksumAlgorithm())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
if (firmwareOld.getFileName() != null && !firmwareOld.getFileName().equals(firmware.getFileName())) {
throw new DataValidationException("Updating firmware file name is prohibited!");
}
if (firmwareOld.getChecksum() != null && !firmwareOld.getChecksum().equals(firmware.getChecksum())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
if (firmwareOld.getContentType() != null && !firmwareOld.getContentType().equals(firmware.getContentType())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) {
throw new DataValidationException("Updating firmware data is prohibited!");
}
if (firmwareOld.getChecksumAlgorithm() != null && !firmwareOld.getChecksumAlgorithm().equals(firmware.getChecksumAlgorithm())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
};
if (firmwareOld.getChecksum() != null && !firmwareOld.getChecksum().equals(firmware.getChecksum())) {
throw new DataValidationException("Updating firmware content type is prohibited!");
}
if (firmwareOld.getDataSize() != null && !firmwareOld.getDataSize().equals(firmware.getDataSize())) {
throw new DataValidationException("Updating firmware data size is prohibited!");
}
}
private PaginatedRemover<TenantId, FirmwareInfo> tenantFirmwareRemover =
new PaginatedRemover<>() {

1
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -483,6 +483,7 @@ public class ModelConstants {
public static final String FIRMWARE_CHECKSUM_ALGORITHM_COLUMN = "checksum_algorithm";
public static final String FIRMWARE_CHECKSUM_COLUMN = "checksum";
public static final String FIRMWARE_DATA_COLUMN = "data";
public static final String FIRMWARE_DATA_SIZE_COLUMN = "data_size";
public static final String FIRMWARE_ADDITIONAL_INFO_COLUMN = ADDITIONAL_INFO_PROPERTY;
public static final String FIRMWARE_HAS_DATA_PROPERTY = "has_data";

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java

@ -38,6 +38,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
@ -76,6 +77,9 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
@Column(name = FIRMWARE_DATA_COLUMN, columnDefinition = "BINARY")
private byte[] data;
@Column(name = FIRMWARE_DATA_SIZE_COLUMN)
private Long dataSize;
@Type(type = "json")
@Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN)
private JsonNode additionalInfo;
@ -98,6 +102,7 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
this.checksumAlgorithm = firmware.getChecksumAlgorithm();
this.checksum = firmware.getChecksum();
this.data = firmware.getData().array();
this.dataSize = firmware.getDataSize();
this.additionalInfo = firmware.getAdditionalInfo();
}
@ -122,6 +127,7 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
firmware.setContentType(contentType);
firmware.setChecksumAlgorithm(checksumAlgorithm);
firmware.setChecksum(checksum);
firmware.setDataSize(dataSize);
if (data != null) {
firmware.setData(ByteBuffer.wrap(data));
firmware.setHasData(true);

41
dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java

@ -35,6 +35,12 @@ import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_HAS_DATA_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
@ -58,6 +64,21 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
@Column(name = FIRMWARE_VERSION_COLUMN)
private String version;
@Column(name = FIRMWARE_FILE_NAME_COLUMN)
private String fileName;
@Column(name = FIRMWARE_CONTENT_TYPE_COLUMN)
private String contentType;
@Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN)
private String checksumAlgorithm;
@Column(name = FIRMWARE_CHECKSUM_COLUMN)
private String checksum;
@Column(name = FIRMWARE_DATA_SIZE_COLUMN)
private Long dataSize;
@Type(type = "json")
@Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN)
private JsonNode additionalInfo;
@ -65,7 +86,6 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
@Column(name = SEARCH_TEXT_PROPERTY)
private String searchText;
// @Column(name = FIRMWARE_HAS_DATA_PROPERTY, insertable = false, updatable = false)
@Transient
private boolean hasData;
@ -79,15 +99,27 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
this.tenantId = firmware.getTenantId().getId();
this.title = firmware.getTitle();
this.version = firmware.getVersion();
this.fileName = firmware.getFileName();
this.contentType = firmware.getContentType();
this.checksumAlgorithm = firmware.getChecksumAlgorithm();
this.checksum = firmware.getChecksum();
this.dataSize = firmware.getDataSize();
this.additionalInfo = firmware.getAdditionalInfo();
}
public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String title, String version, Object additionalInfo, boolean hasData) {
public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String title, String version,
String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize,
Object additionalInfo, boolean hasData) {
this.id = id;
this.createdTime = createdTime;
this.tenantId = tenantId;
this.title = title;
this.version = version;
this.fileName = fileName;
this.contentType = contentType;
this.checksumAlgorithm = checksumAlgorithm;
this.checksum = checksum;
this.dataSize = dataSize;
this.hasData = hasData;
this.additionalInfo = JacksonUtil.convertValue(additionalInfo, JsonNode.class);
}
@ -109,6 +141,11 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
firmware.setTenantId(new TenantId(tenantId));
firmware.setTitle(title);
firmware.setVersion(version);
firmware.setFileName(fileName);
firmware.setContentType(contentType);
firmware.setChecksumAlgorithm(checksumAlgorithm);
firmware.setChecksum(checksum);
firmware.setDataSize(dataSize);
firmware.setAdditionalInfo(additionalInfo);
firmware.setHasData(hasData);
return firmware;

9
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java

@ -94,6 +94,15 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +
"AND d.type = :type " +
"AND d.firmwareId = null " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<DeviceEntity> findByTenantIdAndTypeAndFirmwareIdIsNull(@Param("tenantId") UUID tenantId,
@Param("type") String type,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +

10
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java

@ -149,6 +149,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink) {
return DaoUtil.toPageData(
deviceRepository.findByTenantIdAndTypeAndFirmwareIdIsNull(
tenantId,
type,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink) {
return DaoUtil.toPageData(

6
dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java

@ -25,14 +25,14 @@ import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity;
import java.util.UUID;
public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> {
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " +
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " +
"f.tenantId = :tenantId " +
"AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText,
Pageable pageable);
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " +
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " +
"f.tenantId = :tenantId " +
"AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" +
"AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
@ -41,6 +41,6 @@ public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntit
@Param("searchText") String searchText,
Pageable pageable);
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id")
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id")
FirmwareInfoEntity findFirmwareInfoById(@Param("id") UUID id);
}

1
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -169,6 +169,7 @@ CREATE TABLE IF NOT EXISTS firmware (
checksum_algorithm varchar(32),
checksum varchar(1020),
data binary,
data_size bigint,
additional_info varchar,
search_text varchar(255),
CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)

1
dao/src/main/resources/sql/schema-entities.sql

@ -187,6 +187,7 @@ CREATE TABLE IF NOT EXISTS firmware (
checksum_algorithm varchar(32),
checksum varchar(1020),
data bytea,
data_size bigint,
additional_info varchar,
search_text varchar(255),
CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)

1
dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java

@ -28,6 +28,7 @@ import java.util.Arrays;
"org.thingsboard.server.dao.service.attributes.sql.*SqlTest",
"org.thingsboard.server.dao.service.event.sql.*SqlTest",
"org.thingsboard.server.dao.service.timeseries.sql.*SqlTest"
})
public class SqlDaoServiceTestSuite {

7
dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java

@ -122,6 +122,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
firmwareService.saveFirmware(firmware);
savedFirmwareInfo = firmwareService.findFirmwareInfoById(tenantId, savedFirmwareInfo.getId());
savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode());
firmwareService.saveFirmwareInfo(savedFirmwareInfo);
@ -421,6 +422,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
firmwareInfo.setTenantId(tenantId);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION + i);
firmwareInfo.setFileName(FILE_NAME);
firmwareInfo.setContentType(CONTENT_TYPE);
firmwareInfo.setChecksumAlgorithm(CHECKSUM_ALGORITHM);
firmwareInfo.setChecksum(CHECKSUM);
firmwareInfo.setDataSize((long) DATA.array().length);
firmwares.add(firmwareService.saveFirmwareInfo(firmwareInfo));
}
@ -451,6 +457,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM);
firmware.setChecksum(CHECKSUM);
firmware.setData(DATA);
firmware.setDataSize((long) DATA.array().length);
firmwareService.saveFirmware(firmware);
f.setHasData(true);
});

2
transport/coap/src/main/java/org/thingsboard/server/coap/ThingsboardCoapTransportApplication.java

@ -26,7 +26,7 @@ import java.util.Arrays;
@SpringBootConfiguration
@EnableAsync
@EnableScheduling
@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.coapserver", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue"})
@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.coapserver", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue", "org.thingsboard.server.cache"})
public class ThingsboardCoapTransportApplication {
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";

43
transport/coap/src/main/resources/tb-coap-transport.yml

@ -40,6 +40,49 @@ zk:
# Name of the directory in zookeeper 'filesystem'
zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}"
cache:
type: "${CACHE_TYPE:redis}"
redis:
# standalone or cluster
connection:
type: "${REDIS_CONNECTION_TYPE:standalone}"
standalone:
host: "${REDIS_HOST:localhost}"
port: "${REDIS_PORT:6379}"
useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:true}"
# this value may be used only if you used not default ClientConfig
clientName: "${REDIS_CLIENT_NAME:standalone}"
# this value may be used only if you used not default ClientConfig
connectTimeout: "${REDIS_CLIENT_CONNECT_TIMEOUT:30000}"
# this value may be used only if you used not default ClientConfig
readTimeout: "${REDIS_CLIENT_READ_TIMEOUT:60000}"
# this value may be used only if you used not default ClientConfig
usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:false}"
cluster:
# Comma-separated list of "host:port" pairs to bootstrap from.
nodes: "${REDIS_NODES:}"
# Maximum number of redirects to follow when executing commands across the cluster.
max-redirects: "${REDIS_MAX_REDIRECTS:12}"
useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}"
# db index
db: "${REDIS_DB:0}"
# db password
password: "${REDIS_PASSWORD:}"
# pool config
pool_config:
maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}"
maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}"
minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:16}"
testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:true}"
testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:true}"
testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}"
minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}"
evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}"
maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}"
numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}"
blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}"
# COAP server parameters
transport:
coap:

2
transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java

@ -24,7 +24,7 @@ import java.util.Arrays;
@SpringBootApplication
@EnableAsync
@ComponentScan({"org.thingsboard.server.http", "org.thingsboard.server.common", "org.thingsboard.server.transport.http", "org.thingsboard.server.queue"})
@ComponentScan({"org.thingsboard.server.http", "org.thingsboard.server.common", "org.thingsboard.server.transport.http", "org.thingsboard.server.queue", "org.thingsboard.server.cache"})
public class ThingsboardHttpTransportApplication {
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";

43
transport/http/src/main/resources/tb-http-transport.yml

@ -35,6 +35,49 @@ zk:
# Name of the directory in zookeeper 'filesystem'
zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}"
cache:
type: "${CACHE_TYPE:redis}"
redis:
# standalone or cluster
connection:
type: "${REDIS_CONNECTION_TYPE:standalone}"
standalone:
host: "${REDIS_HOST:localhost}"
port: "${REDIS_PORT:6379}"
useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:true}"
# this value may be used only if you used not default ClientConfig
clientName: "${REDIS_CLIENT_NAME:standalone}"
# this value may be used only if you used not default ClientConfig
connectTimeout: "${REDIS_CLIENT_CONNECT_TIMEOUT:30000}"
# this value may be used only if you used not default ClientConfig
readTimeout: "${REDIS_CLIENT_READ_TIMEOUT:60000}"
# this value may be used only if you used not default ClientConfig
usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:false}"
cluster:
# Comma-separated list of "host:port" pairs to bootstrap from.
nodes: "${REDIS_NODES:}"
# Maximum number of redirects to follow when executing commands across the cluster.
max-redirects: "${REDIS_MAX_REDIRECTS:12}"
useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}"
# db index
db: "${REDIS_DB:0}"
# db password
password: "${REDIS_PASSWORD:}"
# pool config
pool_config:
maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}"
maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}"
minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:16}"
testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:true}"
testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:true}"
testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}"
minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}"
evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}"
maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}"
numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}"
blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}"
# HTTP server parameters
transport:
http:

36
transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml

@ -41,41 +41,7 @@ zk:
zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}"
cache:
# caffeine or redis
type: "${CACHE_TYPE:caffeine}"
caffeine:
specs:
relations:
timeToLiveInMinutes: 1440
maxSize: 0
deviceCredentials:
timeToLiveInMinutes: 1440
maxSize: 0
devices:
timeToLiveInMinutes: 1440
maxSize: 0
sessions:
timeToLiveInMinutes: 1440
maxSize: 0
assets:
timeToLiveInMinutes: 1440
maxSize: 0
entityViews:
timeToLiveInMinutes: 1440
maxSize: 0
claimDevices:
timeToLiveInMinutes: 1
maxSize: 0
securitySettings:
timeToLiveInMinutes: 1440
maxSize: 0
tenantProfiles:
timeToLiveInMinutes: 1440
maxSize: 0
deviceProfiles:
timeToLiveInMinutes: 1440
maxSize: 0
type: "${CACHE_TYPE:redis}"
redis:
# standalone or cluster

2
transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java

@ -26,7 +26,7 @@ import java.util.Arrays;
@SpringBootConfiguration
@EnableAsync
@EnableScheduling
@ComponentScan({"org.thingsboard.server.mqtt", "org.thingsboard.server.common", "org.thingsboard.server.transport.mqtt", "org.thingsboard.server.queue"})
@ComponentScan({"org.thingsboard.server.mqtt", "org.thingsboard.server.common", "org.thingsboard.server.transport.mqtt", "org.thingsboard.server.queue", "org.thingsboard.server.cache"})
public class ThingsboardMqttTransportApplication {
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";

43
transport/mqtt/src/main/resources/tb-mqtt-transport.yml

@ -40,6 +40,49 @@ zk:
# Name of the directory in zookeeper 'filesystem'
zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}"
cache:
type: "${CACHE_TYPE:redis}"
redis:
# standalone or cluster
connection:
type: "${REDIS_CONNECTION_TYPE:standalone}"
standalone:
host: "${REDIS_HOST:localhost}"
port: "${REDIS_PORT:6379}"
useDefaultClientConfig: "${REDIS_USE_DEFAULT_CLIENT_CONFIG:true}"
# this value may be used only if you used not default ClientConfig
clientName: "${REDIS_CLIENT_NAME:standalone}"
# this value may be used only if you used not default ClientConfig
connectTimeout: "${REDIS_CLIENT_CONNECT_TIMEOUT:30000}"
# this value may be used only if you used not default ClientConfig
readTimeout: "${REDIS_CLIENT_READ_TIMEOUT:60000}"
# this value may be used only if you used not default ClientConfig
usePoolConfig: "${REDIS_CLIENT_USE_POOL_CONFIG:false}"
cluster:
# Comma-separated list of "host:port" pairs to bootstrap from.
nodes: "${REDIS_NODES:}"
# Maximum number of redirects to follow when executing commands across the cluster.
max-redirects: "${REDIS_MAX_REDIRECTS:12}"
useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}"
# db index
db: "${REDIS_DB:0}"
# db password
password: "${REDIS_PASSWORD:}"
# pool config
pool_config:
maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}"
maxIdle: "${REDIS_POOL_CONFIG_MAX_IDLE:128}"
minIdle: "${REDIS_POOL_CONFIG_MIN_IDLE:16}"
testOnBorrow: "${REDIS_POOL_CONFIG_TEST_ON_BORROW:true}"
testOnReturn: "${REDIS_POOL_CONFIG_TEST_ON_RETURN:true}"
testWhileIdle: "${REDIS_POOL_CONFIG_TEST_WHILE_IDLE:true}"
minEvictableMs: "${REDIS_POOL_CONFIG_MIN_EVICTABLE_MS:60000}"
evictionRunsMs: "${REDIS_POOL_CONFIG_EVICTION_RUNS_MS:30000}"
maxWaitMills: "${REDIS_POOL_CONFIG_MAX_WAIT_MS:60000}"
numberTestsPerEvictionRun: "${REDIS_POOL_CONFIG_NUMBER_TESTS_PER_EVICTION_RUN:3}"
blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}"
# MQTT server parameters
transport:
mqtt:

Loading…
Cancel
Save