diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java b/application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java index bc3365451d..db8247bb93 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.apiusage; import lombok.Data; import lombok.Getter; +import lombok.Setter; import org.thingsboard.server.common.data.ApiFeature; import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.ApiUsageState; @@ -29,7 +30,6 @@ import org.thingsboard.server.common.msg.tools.SchedulerUtils; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; public abstract class BaseApiUsageState { private final Map currentCycleValues = new ConcurrentHashMap<>(); @@ -37,7 +37,6 @@ public abstract class BaseApiUsageState { private final Map> lastGaugesByServiceId = new HashMap<>(); private final Map gaugesReportCycles = new HashMap<>(); - private static long gaugeReportInterval = TimeUnit.MINUTES.toMillis(3); @Getter private final ApiUsageState apiUsageState; @@ -48,6 +47,9 @@ public abstract class BaseApiUsageState { @Getter private volatile long currentHourTs; + @Setter + private long gaugeReportInterval; + public BaseApiUsageState(ApiUsageState apiUsageState) { this.apiUsageState = apiUsageState; this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth(); diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 7f5e3ad4ad..0b3a4b8acd 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -48,12 +48,12 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.trigger.ApiUsageLimitTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.tools.SchedulerUtils; -import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.ApiUsageLimitTrigger; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; @@ -129,6 +129,9 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService @Value("${usage.stats.check.cycle:60000}") private long nextCycleCheckInterval; + @Value("${usage.stats.gauge_report_interval:180000}") + private long gaugeReportInterval; + private final Lock updateLock = new ReentrantLock(); @PostConstruct @@ -476,6 +479,7 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService } } } + state.setGaugeReportInterval(gaugeReportInterval); log.debug("[{}] Initialized state: {}", ownerId, storedState); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, ownerId); if (tpi.isMyPartition()) { diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 3594b01990..005cc6ac4c 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -26,6 +26,7 @@ import com.google.common.util.concurrent.MoreExecutors; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; @@ -437,7 +438,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService> devicesActivity = new HashMap<>(); + Map> devicesActivity = new HashMap<>(); partitionedEntities.forEach((tpi, deviceIds) -> { log.debug("Calculating state updates. tpi {} for {} devices", tpi.getFullTopicName(), deviceIds.size()); for (DeviceId deviceId : deviceIds) { @@ -453,14 +454,18 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService new HashMap<>()) - .computeIfAbsent(stateData.getState().isActive(), k -> new AtomicInteger()) - .incrementAndGet(); + Pair tenantDevicesActivity = devicesActivity.computeIfAbsent(stateData.getTenantId(), + tenantId -> Pair.of(new AtomicInteger(), new AtomicInteger())); + if (stateData.getState().isActive()) { + tenantDevicesActivity.getLeft().incrementAndGet(); + } else { + tenantDevicesActivity.getRight().incrementAndGet(); + } } }); - devicesActivity.forEach((tenantId, countByActivityStatus) -> { - int active = Optional.ofNullable(countByActivityStatus.get(true)).map(AtomicInteger::get).orElse(0); - int inactive = Optional.ofNullable(countByActivityStatus.get(false)).map(AtomicInteger::get).orElse(0); + devicesActivity.forEach((tenantId, tenantDevicesActivity) -> { + int active = tenantDevicesActivity.getLeft().get(); + int inactive = tenantDevicesActivity.getRight().get(); apiUsageReportClient.report(tenantId, null, ApiUsageRecordKey.ACTIVE_DEVICES, active); apiUsageReportClient.report(tenantId, null, ApiUsageRecordKey.INACTIVE_DEVICES, inactive); if (active > 0) { diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index f745e03ffc..98e6a769e0 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -140,6 +140,7 @@ usage: interval: "${USAGE_STATS_REPORT_INTERVAL:10}" check: cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" + gauge_report_interval: "${USAGE_STATS_GAUGE_REPORT_INTERVAL:180000}" # UI parameters ui: diff --git a/application/src/test/java/org/thingsboard/server/service/stats/DevicesStatisticsTest.java b/application/src/test/java/org/thingsboard/server/service/stats/DevicesStatisticsTest.java index c87bd22e3a..d31d6639ac 100644 --- a/application/src/test/java/org/thingsboard/server/service/stats/DevicesStatisticsTest.java +++ b/application/src/test/java/org/thingsboard/server/service/stats/DevicesStatisticsTest.java @@ -27,7 +27,6 @@ import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.timeseries.TimeseriesService; -import org.thingsboard.server.service.apiusage.BaseApiUsageState; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import java.util.ArrayList; @@ -43,6 +42,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. "usage.stats.report.enabled=true", "transport.http.enabled=true", "usage.stats.report.interval=2", + "usage.stats.gauge_report_interval=1", "state.defaultStateCheckIntervalInSec=3", "state.defaultInactivityTimeoutInSec=10" @@ -64,8 +64,6 @@ public class DevicesStatisticsTest extends AbstractControllerTest { @Test public void testDevicesActivityStats() throws Exception { - setStaticFieldValue(BaseApiUsageState.class, "gaugeReportInterval", 1); - int activeDevicesCount = 5; List activeDevices = new ArrayList<>(); for (int i = 1; i <= activeDevicesCount; i++) { diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 61ccfa6a19..b81596417c 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -174,8 +174,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics. diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index d28f254015..d4b3ba07af 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -277,8 +277,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics. diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index ebabc04fa7..cf11bd1c6a 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -262,8 +262,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics. diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 82459ff3ab..da56ad37d9 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -344,8 +344,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics. diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 2c1944dd1d..1c09585163 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -292,8 +292,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics. diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index dc5e416bfc..92791400ab 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -242,8 +242,6 @@ usage: enabled: "${USAGE_STATS_REPORT_ENABLED:true}" enabled_per_customer: "${USAGE_STATS_REPORT_PER_CUSTOMER_ENABLED:false}" interval: "${USAGE_STATS_REPORT_INTERVAL:10}" - check: - cycle: "${USAGE_STATS_CHECK_CYCLE:60000}" metrics: # Enable/disable actuator metrics.