Refactor saveAndNotifyInternal for timeseries; save latest by default
This commit is contained in:
parent
2bb65923dc
commit
6c0bca2bae
@ -679,7 +679,6 @@ public class TelemetryController extends BaseController {
|
|||||||
.entityId(entityId)
|
.entityId(entityId)
|
||||||
.entries(entries)
|
.entries(entries)
|
||||||
.ttl(tenantTtl)
|
.ttl(tenantTtl)
|
||||||
.saveLatest(true)
|
|
||||||
.callback(new FutureCallback<Void>() {
|
.callback(new FutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void tmp) {
|
public void onSuccess(@Nullable Void tmp) {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.rule.engine.api.MailService;
|
import org.thingsboard.rule.engine.api.MailService;
|
||||||
|
import org.thingsboard.rule.engine.api.TimeseriesSaveRequest;
|
||||||
import org.thingsboard.server.common.data.ApiFeature;
|
import org.thingsboard.server.common.data.ApiFeature;
|
||||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||||
import org.thingsboard.server.common.data.ApiUsageRecordState;
|
import org.thingsboard.server.common.data.ApiUsageRecordState;
|
||||||
@ -91,9 +92,9 @@ import java.util.stream.Collectors;
|
|||||||
public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService<EntityId> implements TbApiUsageStateService {
|
public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService<EntityId> implements TbApiUsageStateService {
|
||||||
|
|
||||||
public static final String HOURLY = "Hourly";
|
public static final String HOURLY = "Hourly";
|
||||||
public static final FutureCallback<Integer> VOID_CALLBACK = new FutureCallback<Integer>() {
|
public static final FutureCallback<Void> VOID_CALLBACK = new FutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Integer result) {
|
public void onSuccess(@Nullable Void result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -214,7 +215,12 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
|
|||||||
updateLock.unlock();
|
updateLock.unlock();
|
||||||
}
|
}
|
||||||
log.trace("[{}][{}] Saving new stats: {}", tenantId, ownerId, updatedEntries);
|
log.trace("[{}][{}] Saving new stats: {}", tenantId, ownerId, updatedEntries);
|
||||||
tsWsService.saveAndNotifyInternal(tenantId, usageState.getApiUsageState().getId(), updatedEntries, VOID_CALLBACK);
|
tsWsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.entityId(usageState.getApiUsageState().getId())
|
||||||
|
.entries(updatedEntries)
|
||||||
|
.callback(VOID_CALLBACK)
|
||||||
|
.build());
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
persistAndNotify(usageState, result);
|
persistAndNotify(usageState, result);
|
||||||
}
|
}
|
||||||
@ -321,7 +327,12 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!profileThresholds.isEmpty()) {
|
if (!profileThresholds.isEmpty()) {
|
||||||
tsWsService.saveAndNotifyInternal(tenantId, id, profileThresholds, VOID_CALLBACK);
|
tsWsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.entityId(id)
|
||||||
|
.entries(profileThresholds)
|
||||||
|
.callback(VOID_CALLBACK)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +359,12 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
|
|||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
List<TsKvEntry> stateTelemetry = new ArrayList<>();
|
List<TsKvEntry> stateTelemetry = new ArrayList<>();
|
||||||
result.forEach((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name()))));
|
result.forEach((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name()))));
|
||||||
tsWsService.saveAndNotifyInternal(state.getTenantId(), state.getApiUsageState().getId(), stateTelemetry, VOID_CALLBACK);
|
tsWsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(state.getTenantId())
|
||||||
|
.entityId(state.getApiUsageState().getId())
|
||||||
|
.entries(stateTelemetry)
|
||||||
|
.callback(VOID_CALLBACK)
|
||||||
|
.build());
|
||||||
|
|
||||||
if (state.getEntityType() == EntityType.TENANT && !state.getEntityId().equals(TenantId.SYS_TENANT_ID)) {
|
if (state.getEntityType() == EntityType.TENANT && !state.getEntityId().equals(TenantId.SYS_TENANT_ID)) {
|
||||||
String email = tenantService.findTenantById(state.getTenantId()).getEmail();
|
String email = tenantService.findTenantById(state.getTenantId()).getEmail();
|
||||||
@ -436,7 +452,12 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
|
|||||||
.map(key -> new BasicTsKvEntry(state.getCurrentCycleTs(), new LongDataEntry(key.getApiCountKey(), 0L)))
|
.map(key -> new BasicTsKvEntry(state.getCurrentCycleTs(), new LongDataEntry(key.getApiCountKey(), 0L)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
tsWsService.saveAndNotifyInternal(state.getTenantId(), state.getApiUsageState().getId(), counts, VOID_CALLBACK);
|
tsWsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(state.getTenantId())
|
||||||
|
.entityId(state.getApiUsageState().getId())
|
||||||
|
.entries(counts)
|
||||||
|
.callback(VOID_CALLBACK)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseApiUsageState getOrFetchState(TenantId tenantId, EntityId ownerId) {
|
BaseApiUsageState getOrFetchState(TenantId tenantId, EntityId ownerId) {
|
||||||
|
|||||||
@ -69,7 +69,6 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -507,8 +506,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
|
|||||||
tsSubService.save(TimeseriesSaveRequest.builder()
|
tsSubService.save(TimeseriesSaveRequest.builder()
|
||||||
.tenantId(tenantId)
|
.tenantId(tenantId)
|
||||||
.entityId(edgeId)
|
.entityId(edgeId)
|
||||||
.entries(Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))))
|
.entry(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value)))
|
||||||
.saveLatest(true)
|
|
||||||
.callback(new AttributeSaveCallback(tenantId, edgeId, key, value))
|
.callback(new AttributeSaveCallback(tenantId, edgeId, key, value))
|
||||||
.build());
|
.build());
|
||||||
} else {
|
} else {
|
||||||
@ -522,8 +520,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
|
|||||||
tsSubService.save(TimeseriesSaveRequest.builder()
|
tsSubService.save(TimeseriesSaveRequest.builder()
|
||||||
.tenantId(tenantId)
|
.tenantId(tenantId)
|
||||||
.entityId(edgeId)
|
.entityId(edgeId)
|
||||||
.entries(Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))))
|
.entry(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value)))
|
||||||
.saveLatest(true)
|
|
||||||
.callback(new AttributeSaveCallback(tenantId, edgeId, key, value))
|
.callback(new AttributeSaveCallback(tenantId, edgeId, key, value))
|
||||||
.build());
|
.build());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -55,7 +55,6 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
|
|||||||
import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory;
|
import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -266,7 +265,6 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService {
|
|||||||
.tenantId(tenantId)
|
.tenantId(tenantId)
|
||||||
.entityId(deviceId)
|
.entityId(deviceId)
|
||||||
.entries(telemetry)
|
.entries(telemetry)
|
||||||
.saveLatest(true)
|
|
||||||
.callback(new FutureCallback<Void>() {
|
.callback(new FutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void tmp) {
|
public void onSuccess(@Nullable Void tmp) {
|
||||||
@ -292,9 +290,8 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService {
|
|||||||
telemetryService.save(TimeseriesSaveRequest.builder()
|
telemetryService.save(TimeseriesSaveRequest.builder()
|
||||||
.tenantId(tenantId)
|
.tenantId(tenantId)
|
||||||
.entityId(deviceId)
|
.entityId(deviceId)
|
||||||
.entries(Collections.singletonList(status))
|
.entry(status)
|
||||||
.saveLatest(true)
|
.callback(new FutureCallback<>() {
|
||||||
.callback(new FutureCallback<Void>() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void tmp) {
|
public void onSuccess(@Nullable Void tmp) {
|
||||||
log.trace("[{}] Success save telemetry with target {} for device!", deviceId, otaPackage);
|
log.trace("[{}] Success save telemetry with target {} for device!", deviceId, otaPackage);
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.common.util.ThingsBoardExecutors;
|
import org.thingsboard.common.util.ThingsBoardExecutors;
|
||||||
|
import org.thingsboard.rule.engine.api.TimeseriesSaveRequest;
|
||||||
import org.thingsboard.server.cluster.TbClusterService;
|
import org.thingsboard.server.cluster.TbClusterService;
|
||||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||||
import org.thingsboard.server.common.data.AttributeScope;
|
import org.thingsboard.server.common.data.AttributeScope;
|
||||||
@ -866,10 +867,13 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
|
|||||||
|
|
||||||
private void save(DeviceId deviceId, String key, long value) {
|
private void save(DeviceId deviceId, String key, long value) {
|
||||||
if (persistToTelemetry) {
|
if (persistToTelemetry) {
|
||||||
tsSubService.saveAndNotifyInternal(
|
tsSubService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
TenantId.SYS_TENANT_ID, deviceId,
|
.tenantId(TenantId.SYS_TENANT_ID)
|
||||||
Collections.singletonList(new BasicTsKvEntry(getCurrentTimeMillis(), new LongDataEntry(key, value))),
|
.entityId(deviceId)
|
||||||
telemetryTtl, new TelemetrySaveCallback<>(deviceId, key, value));
|
.entry(new BasicTsKvEntry(getCurrentTimeMillis(), new LongDataEntry(key, value)))
|
||||||
|
.ttl(telemetryTtl)
|
||||||
|
.callback(new TelemetrySaveCallback<>(deviceId, key, value))
|
||||||
|
.build());
|
||||||
} else {
|
} else {
|
||||||
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
|
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
|
||||||
}
|
}
|
||||||
@ -877,10 +881,13 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
|
|||||||
|
|
||||||
private void save(DeviceId deviceId, String key, boolean value) {
|
private void save(DeviceId deviceId, String key, boolean value) {
|
||||||
if (persistToTelemetry) {
|
if (persistToTelemetry) {
|
||||||
tsSubService.saveAndNotifyInternal(
|
tsSubService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
TenantId.SYS_TENANT_ID, deviceId,
|
.tenantId(TenantId.SYS_TENANT_ID)
|
||||||
Collections.singletonList(new BasicTsKvEntry(getCurrentTimeMillis(), new BooleanDataEntry(key, value))),
|
.entityId(deviceId)
|
||||||
telemetryTtl, new TelemetrySaveCallback<>(deviceId, key, value));
|
.entry(new BasicTsKvEntry(getCurrentTimeMillis(), new BooleanDataEntry(key, value)))
|
||||||
|
.ttl(telemetryTtl)
|
||||||
|
.callback(new TelemetrySaveCallback<>(deviceId, key, value))
|
||||||
|
.build());
|
||||||
} else {
|
} else {
|
||||||
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
|
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.thingsboard.rule.engine.api.TimeseriesSaveRequest;
|
||||||
import org.thingsboard.server.common.data.id.QueueStatsId;
|
import org.thingsboard.server.common.data.id.QueueStatsId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
|
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
|
||||||
@ -37,7 +38,6 @@ import org.thingsboard.server.queue.util.TbRuleEngineComponent;
|
|||||||
import org.thingsboard.server.service.queue.TbRuleEngineConsumerStats;
|
import org.thingsboard.server.service.queue.TbRuleEngineConsumerStats;
|
||||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@ -53,9 +53,9 @@ import java.util.stream.Collectors;
|
|||||||
public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsService {
|
public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsService {
|
||||||
|
|
||||||
public static final String RULE_ENGINE_EXCEPTION = "ruleEngineException";
|
public static final String RULE_ENGINE_EXCEPTION = "ruleEngineException";
|
||||||
public static final FutureCallback<Integer> CALLBACK = new FutureCallback<Integer>() {
|
public static final FutureCallback<Void> CALLBACK = new FutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Integer result) {
|
public void onSuccess(@Nullable Void result) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,13 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS
|
|||||||
if (!tsList.isEmpty()) {
|
if (!tsList.isEmpty()) {
|
||||||
long ttl = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getQueueStatsTtlDays);
|
long ttl = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getQueueStatsTtlDays);
|
||||||
ttl = TimeUnit.DAYS.toSeconds(ttl);
|
ttl = TimeUnit.DAYS.toSeconds(ttl);
|
||||||
tsService.saveAndNotifyInternal(tenantId, queueStatsId, tsList, ttl, CALLBACK);
|
tsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.entityId(queueStatsId)
|
||||||
|
.entries(tsList)
|
||||||
|
.ttl(ttl)
|
||||||
|
.callback(CALLBACK)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -103,7 +109,13 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS
|
|||||||
TsKvEntry tsKv = new BasicTsKvEntry(e.getTs(), new JsonDataEntry(RULE_ENGINE_EXCEPTION, e.toJsonString(maxErrorMessageLength)));
|
TsKvEntry tsKv = new BasicTsKvEntry(e.getTs(), new JsonDataEntry(RULE_ENGINE_EXCEPTION, e.toJsonString(maxErrorMessageLength)));
|
||||||
long ttl = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getRuleEngineExceptionsTtlDays);
|
long ttl = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getRuleEngineExceptionsTtlDays);
|
||||||
ttl = TimeUnit.DAYS.toSeconds(ttl);
|
ttl = TimeUnit.DAYS.toSeconds(ttl);
|
||||||
tsService.saveAndNotifyInternal(tenantId, getQueueStatsId(tenantId, queueName), Collections.singletonList(tsKv), ttl, CALLBACK);
|
tsService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.entityId(getQueueStatsId(tenantId, queueName))
|
||||||
|
.entry(tsKv)
|
||||||
|
.ttl(ttl)
|
||||||
|
.callback(CALLBACK)
|
||||||
|
.build());
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
if (!"Asset is referencing to non-existent tenant!".equalsIgnoreCase(e2.getMessage())) {
|
if (!"Asset is referencing to non-existent tenant!".equalsIgnoreCase(e2.getMessage())) {
|
||||||
log.debug("[{}] Failed to store the statistics", tenantId, e2);
|
log.debug("[{}] Failed to store the statistics", tenantId, e2);
|
||||||
|
|||||||
@ -213,8 +213,7 @@ public abstract class AbstractBulkImportService<E extends HasId<? extends Entity
|
|||||||
.entityId(entityId)
|
.entityId(entityId)
|
||||||
.entries(timeseries)
|
.entries(timeseries)
|
||||||
.ttl(tenantTtl)
|
.ttl(tenantTtl)
|
||||||
.saveLatest(true)
|
.callback(new FutureCallback<>() {
|
||||||
.callback(new FutureCallback<Void>() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void tmp) {
|
public void onSuccess(@Nullable Void tmp) {
|
||||||
entityActionService.logEntityAction(user, (UUIDBased & EntityId) entityId, null, null,
|
entityActionService.logEntityAction(user, (UUIDBased & EntityId) entityId, null, null,
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.thingsboard.common.util.JacksonUtil;
|
|||||||
import org.thingsboard.common.util.ThingsBoardExecutors;
|
import org.thingsboard.common.util.ThingsBoardExecutors;
|
||||||
import org.thingsboard.rule.engine.api.MailService;
|
import org.thingsboard.rule.engine.api.MailService;
|
||||||
import org.thingsboard.rule.engine.api.SmsService;
|
import org.thingsboard.rule.engine.api.SmsService;
|
||||||
|
import org.thingsboard.rule.engine.api.TimeseriesSaveRequest;
|
||||||
import org.thingsboard.server.common.data.AdminSettings;
|
import org.thingsboard.server.common.data.AdminSettings;
|
||||||
import org.thingsboard.server.common.data.ApiUsageState;
|
import org.thingsboard.server.common.data.ApiUsageState;
|
||||||
import org.thingsboard.server.common.data.FeaturesInfo;
|
import org.thingsboard.server.common.data.FeaturesInfo;
|
||||||
@ -71,9 +72,9 @@ import static org.thingsboard.common.util.SystemUtil.getTotalMemory;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class DefaultSystemInfoService extends TbApplicationEventListener<PartitionChangeEvent> implements SystemInfoService {
|
public class DefaultSystemInfoService extends TbApplicationEventListener<PartitionChangeEvent> implements SystemInfoService {
|
||||||
|
|
||||||
public static final FutureCallback<Integer> CALLBACK = new FutureCallback<>() {
|
public static final FutureCallback<Void> CALLBACK = new FutureCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Integer result) {
|
public void onSuccess(@Nullable Void result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -200,7 +201,13 @@ public class DefaultSystemInfoService extends TbApplicationEventListener<Partiti
|
|||||||
|
|
||||||
private void doSave(List<TsKvEntry> telemetry) {
|
private void doSave(List<TsKvEntry> telemetry) {
|
||||||
ApiUsageState apiUsageState = apiUsageStateClient.getApiUsageState(TenantId.SYS_TENANT_ID);
|
ApiUsageState apiUsageState = apiUsageStateClient.getApiUsageState(TenantId.SYS_TENANT_ID);
|
||||||
telemetryService.saveAndNotifyInternal(TenantId.SYS_TENANT_ID, apiUsageState.getId(), telemetry, systemInfoTtlSeconds, CALLBACK);
|
telemetryService.saveInternal(TimeseriesSaveRequest.builder()
|
||||||
|
.tenantId(TenantId.SYS_TENANT_ID)
|
||||||
|
.entityId(apiUsageState.getId())
|
||||||
|
.entries(telemetry)
|
||||||
|
.ttl(systemInfoTtlSeconds)
|
||||||
|
.callback(CALLBACK)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SystemInfoData> getSystemData(ServiceInfo serviceInfo) {
|
private List<SystemInfoData> getSystemData(ServiceInfo serviceInfo) {
|
||||||
|
|||||||
@ -116,6 +116,22 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
|
|||||||
super.shutdownExecutor();
|
super.shutdownExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(TimeseriesSaveRequest request) {
|
||||||
|
TenantId tenantId = request.getTenantId();
|
||||||
|
EntityId entityId = request.getEntityId();
|
||||||
|
checkInternalEntity(entityId);
|
||||||
|
boolean sysTenant = TenantId.SYS_TENANT_ID.equals(tenantId) || tenantId == null;
|
||||||
|
if (sysTenant || apiUsageStateService.getApiUsageState(tenantId).isDbStorageEnabled()) {
|
||||||
|
KvUtils.validate(request.getEntries(), valueNoXssValidation);
|
||||||
|
FutureCallback<Integer> callback = getApiUsageCallback(tenantId, request.getCustomerId(), sysTenant, request.getCallback());
|
||||||
|
ListenableFuture<Integer> future = saveInternal(request);
|
||||||
|
Futures.addCallback(future, callback, tsCallBackExecutor);
|
||||||
|
} else {
|
||||||
|
request.getCallback().onFailure(new RuntimeException("DB storage writes are disabled due to API limits!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Void> saveAndNotify(TimeseriesSaveRequest request) {
|
public ListenableFuture<Void> saveAndNotify(TimeseriesSaveRequest request) {
|
||||||
SettableFuture<Void> future = SettableFuture.create();
|
SettableFuture<Void> future = SettableFuture.create();
|
||||||
@ -125,58 +141,22 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(TimeseriesSaveRequest request) {
|
public ListenableFuture<Integer> saveInternal(TimeseriesSaveRequest request) {
|
||||||
TenantId tenantId = request.getTenantId();
|
TenantId tenantId = request.getTenantId();
|
||||||
EntityId entityId = request.getEntityId();
|
EntityId entityId = request.getEntityId();
|
||||||
checkInternalEntity(entityId);
|
ListenableFuture<Integer> saveFuture;
|
||||||
boolean sysTenant = TenantId.SYS_TENANT_ID.equals(tenantId) || tenantId == null;
|
if (request.isSaveLatest()) {
|
||||||
if (sysTenant || apiUsageStateService.getApiUsageState(tenantId).isDbStorageEnabled()) {
|
saveFuture = tsService.save(tenantId, entityId, request.getEntries(), request.getTtl());
|
||||||
KvUtils.validate(request.getEntries(), valueNoXssValidation);
|
|
||||||
FutureCallback<Integer> callback = getCallback(tenantId, request.getCustomerId(), sysTenant, request.getCallback());
|
|
||||||
if (request.isSaveLatest()) {
|
|
||||||
saveAndNotifyInternal(tenantId, entityId, request.getEntries(), request.getTtl(), callback);
|
|
||||||
} else {
|
|
||||||
saveWithoutLatestAndNotifyInternal(tenantId, entityId, request.getEntries(), request.getTtl(), callback);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
request.getCallback().onFailure(new RuntimeException("DB storage writes are disabled due to API limits!"));
|
saveFuture = tsService.saveWithoutLatest(tenantId, entityId, request.getEntries(), request.getTtl());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private FutureCallback<Integer> getCallback(TenantId tenantId, CustomerId customerId, boolean sysTenant, FutureCallback<Void> callback) {
|
addMainCallback(saveFuture, request.getCallback());
|
||||||
return new FutureCallback<>() {
|
addWsCallback(saveFuture, success -> onTimeSeriesUpdate(tenantId, entityId, request.getEntries()));
|
||||||
@Override
|
if (request.isSaveLatest()) {
|
||||||
public void onSuccess(Integer result) {
|
addEntityViewCallback(tenantId, entityId, request.getEntries());
|
||||||
if (!sysTenant && result != null && result > 0) {
|
}
|
||||||
apiUsageClient.report(tenantId, customerId, ApiUsageRecordKey.STORAGE_DP_COUNT, result);
|
return saveFuture;
|
||||||
}
|
|
||||||
callback.onSuccess(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, FutureCallback<Integer> callback) {
|
|
||||||
saveAndNotifyInternal(tenantId, entityId, ts, 0L, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Integer> callback) {
|
|
||||||
ListenableFuture<Integer> saveFuture = tsService.save(tenantId, entityId, ts, ttl);
|
|
||||||
addMainCallback(saveFuture, callback);
|
|
||||||
addWsCallback(saveFuture, success -> onTimeSeriesUpdate(tenantId, entityId, ts));
|
|
||||||
addEntityViewCallback(tenantId, entityId, ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveWithoutLatestAndNotifyInternal(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Integer> callback) {
|
|
||||||
ListenableFuture<Integer> saveFuture = tsService.saveWithoutLatest(tenantId, entityId, ts, ttl);
|
|
||||||
addMainCallback(saveFuture, callback);
|
|
||||||
addWsCallback(saveFuture, success -> onTimeSeriesUpdate(tenantId, entityId, ts));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEntityViewCallback(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts) {
|
private void addEntityViewCallback(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts) {
|
||||||
@ -452,11 +432,11 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
|
|||||||
}, tsCallBackExecutor);
|
}, tsCallBackExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <S> void addMainCallback(ListenableFuture<S> saveFuture, final FutureCallback<S> callback) {
|
private <S> void addMainCallback(ListenableFuture<S> saveFuture, final FutureCallback<Void> callback) {
|
||||||
Futures.addCallback(saveFuture, new FutureCallback<S>() {
|
Futures.addCallback(saveFuture, new FutureCallback<S>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable S result) {
|
public void onSuccess(@Nullable S result) {
|
||||||
callback.onSuccess(result);
|
callback.onSuccess(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -472,6 +452,23 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FutureCallback<Integer> getApiUsageCallback(TenantId tenantId, CustomerId customerId, boolean sysTenant, FutureCallback<Void> callback) {
|
||||||
|
return new FutureCallback<>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Integer result) {
|
||||||
|
if (!sysTenant && result != null && result > 0) {
|
||||||
|
apiUsageClient.report(tenantId, customerId, ApiUsageRecordKey.STORAGE_DP_COUNT, result);
|
||||||
|
}
|
||||||
|
callback.onSuccess(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static class VoidFutureCallback implements FutureCallback<Void> {
|
private static class VoidFutureCallback implements FutureCallback<Void> {
|
||||||
private final SettableFuture<Void> future;
|
private final SettableFuture<Void> future;
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,9 @@
|
|||||||
package org.thingsboard.server.service.telemetry;
|
package org.thingsboard.server.service.telemetry;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
|
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
|
||||||
|
import org.thingsboard.rule.engine.api.TimeseriesSaveRequest;
|
||||||
import org.thingsboard.server.common.data.AttributeScope;
|
import org.thingsboard.server.common.data.AttributeScope;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
@ -30,9 +32,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface InternalTelemetryService extends RuleEngineTelemetryService {
|
public interface InternalTelemetryService extends RuleEngineTelemetryService {
|
||||||
|
|
||||||
void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, FutureCallback<Integer> callback);
|
ListenableFuture<Integer> saveInternal(TimeseriesSaveRequest request);
|
||||||
|
|
||||||
void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Integer> callback);
|
|
||||||
|
|
||||||
@Deprecated(since = "3.7.0")
|
@Deprecated(since = "3.7.0")
|
||||||
void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, boolean notifyDevice, FutureCallback<Void> callback);
|
void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, boolean notifyDevice, FutureCallback<Void> callback);
|
||||||
|
|||||||
@ -807,11 +807,8 @@ public class WebsocketApiTest extends AbstractControllerTest {
|
|||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
tsService.save(TimeseriesSaveRequest.builder()
|
tsService.save(TimeseriesSaveRequest.builder()
|
||||||
.tenantId(device.getTenantId())
|
.tenantId(device.getTenantId())
|
||||||
.customerId(null)
|
|
||||||
.entityId(device.getId())
|
.entityId(device.getId())
|
||||||
.entries(tsData)
|
.entries(tsData)
|
||||||
.ttl(0)
|
|
||||||
.saveLatest(true)
|
|
||||||
.callback(new FutureCallback<Void>() {
|
.callback(new FutureCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable Void result) {
|
public void onSuccess(@Nullable Void result) {
|
||||||
|
|||||||
@ -18,7 +18,8 @@ package org.thingsboard.rule.engine.api;
|
|||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
@ -26,15 +27,17 @@ import org.thingsboard.server.common.data.kv.TsKvEntry;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Getter
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class TimeseriesSaveRequest {
|
public class TimeseriesSaveRequest {
|
||||||
|
|
||||||
private final TenantId tenantId;
|
private final TenantId tenantId;
|
||||||
private final CustomerId customerId;
|
private final CustomerId customerId;
|
||||||
private final EntityId entityId;
|
private final EntityId entityId;
|
||||||
private final List<TsKvEntry> entries;
|
private final List<TsKvEntry> entries;
|
||||||
private final long ttl;
|
private final long ttl;
|
||||||
private final boolean saveLatest;
|
private final boolean saveLatest;
|
||||||
|
@Setter
|
||||||
private FutureCallback<Void> callback;
|
private FutureCallback<Void> callback;
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
@ -49,7 +52,7 @@ public class TimeseriesSaveRequest {
|
|||||||
private List<TsKvEntry> entries;
|
private List<TsKvEntry> entries;
|
||||||
private long ttl;
|
private long ttl;
|
||||||
private FutureCallback<Void> callback;
|
private FutureCallback<Void> callback;
|
||||||
private boolean saveLatest;
|
private boolean saveLatest = true;
|
||||||
|
|
||||||
Builder() {}
|
Builder() {}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,6 @@ import org.thingsboard.server.common.msg.TbMsg;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@ -145,8 +144,7 @@ public class TbMathNode implements TbNode {
|
|||||||
return ctx.getTelemetryService().saveAndNotify(TimeseriesSaveRequest.builder()
|
return ctx.getTelemetryService().saveAndNotify(TimeseriesSaveRequest.builder()
|
||||||
.tenantId(ctx.getTenantId())
|
.tenantId(ctx.getTenantId())
|
||||||
.entityId(msg.getOriginator())
|
.entityId(msg.getOriginator())
|
||||||
.entries(Collections.singletonList(basicTsKvEntry))
|
.entry(basicTsKvEntry)
|
||||||
.saveLatest(true)
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user