Browse Source

Merge pull request #14794 from thingsboard/cfs/handling-tenant-profile-update

Handling update of minAllowedScheduledUpdateIntervalInSecForCF and duplicationIntervalInSecForCF in running CFs + updated default values in profile configuration
pull/14815/head
Viacheslav Klimov 5 months ago
committed by GitHub
parent
commit
037d9d3500
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      application/src/main/data/upgrade/basic/schema_update.sql
  2. 4
      application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java
  3. 10
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java
  4. 29
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/HasEntityLimit.java
  5. 8
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesAggregationCalculatedFieldState.java
  6. 18
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesArgumentEntry.java
  7. 10
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/propagation/PropagationArgumentEntry.java
  8. 8
      common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
  9. 4
      ui-ngx/src/app/shared/models/tenant.model.ts

4
application/src/main/data/upgrade/basic/schema_update.sql

@ -21,8 +21,8 @@ SET profile_data = jsonb_set(
profile_data,
'{configuration}',
jsonb_build_object(
'minAllowedScheduledUpdateIntervalInSecForCF', 60,
'maxRelationLevelPerCfArgument', 10,
'minAllowedScheduledUpdateIntervalInSecForCF', 10,
'maxRelationLevelPerCfArgument', 2,
'maxRelatedEntitiesToReturnPerCfArgument', 100,
'minAllowedDeduplicationIntervalInSecForCF', 10,
'minAllowedAggregationIntervalInSecForCF', 60,

4
application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java

@ -161,8 +161,8 @@ public class TenantProfileController extends BaseController {
" \"warnThreshold\": 0,\n" +
" \"maxCalculatedFieldsPerEntity\": 5,\n" +
" \"maxArgumentsPerCF\": 10,\n" +
" \"minAllowedScheduledUpdateIntervalInSecForCF\": 60,\n" +
" \"maxRelationLevelPerCfArgument\": 10,\n" +
" \"minAllowedScheduledUpdateIntervalInSecForCF\": 10,\n" +
" \"maxRelationLevelPerCfArgument\": 2,\n" +
" \"maxRelatedEntitiesToReturnPerCfArgument\": 100,\n" +
" \"maxDataPointsPerRollingArg\": 1000,\n" +
" \"maxStateSizeInKBytes\": 32,\n" +

10
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java

@ -129,6 +129,8 @@ public class CalculatedFieldCtx implements Closeable {
private long cfCheckReevaluationIntervalMillis;
private long alarmReevaluationIntervalMillis;
private long maxRelatedEntitiesPerCfArgument;
private long minScheduledUpdateIntervalMillis;
private long minDeduplicationIntervalMillis;
private Argument propagationArgument;
private boolean applyExpressionForResolvedArguments;
@ -312,6 +314,8 @@ public class CalculatedFieldCtx implements Closeable {
this.cfCheckReevaluationIntervalMillis = TimeUnit.SECONDS.toMillis(config.getCfReevaluationCheckInterval());
this.alarmReevaluationIntervalMillis = TimeUnit.SECONDS.toMillis(config.getAlarmsReevaluationInterval());
this.maxRelatedEntitiesPerCfArgument = config.getMaxRelatedEntitiesToReturnPerCfArgument();
this.minScheduledUpdateIntervalMillis = TimeUnit.SECONDS.toMillis(config.getMinAllowedScheduledUpdateIntervalInSecForCF());
this.minDeduplicationIntervalMillis = TimeUnit.SECONDS.toMillis(config.getMinAllowedDeduplicationIntervalInSecForCF());
});
}
@ -763,9 +767,7 @@ public class CalculatedFieldCtx implements Closeable {
}
public boolean hasRelatedEntities() {
return CalculatedFieldType.GEOFENCING == cfType
|| CalculatedFieldType.PROPAGATION == cfType
|| CalculatedFieldType.RELATED_ENTITIES_AGGREGATION == cfType;
return cfHasRelationPathQuerySource;
}
public boolean shouldFetchRelatedEntities(CalculatedFieldState state) {
@ -781,7 +783,7 @@ public class CalculatedFieldCtx implements Closeable {
if (scheduledRefreshSupported.getLastScheduledRefreshTs() == DEFAULT_LAST_UPDATE_TS) {
return true;
}
return scheduledRefreshSupported.getLastScheduledRefreshTs() < System.currentTimeMillis() - scheduledUpdateIntervalMillis;
return scheduledRefreshSupported.getLastScheduledRefreshTs() < System.currentTimeMillis() - Math.max(scheduledUpdateIntervalMillis, minScheduledUpdateIntervalMillis);
}
@Override

29
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/HasEntityLimit.java

@ -0,0 +1,29 @@
/**
* Copyright © 2016-2026 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.cf.ctx.state;
public interface HasEntityLimit {
default void checkEntityLimit(int currentEntitiesCount, CalculatedFieldCtx ctx) {
if (currentEntitiesCount >= ctx.getMaxRelatedEntitiesPerCfArgument()) {
throw new IllegalArgumentException(
"Exceeded the maximum allowed related entities per argument '"
+ ctx.getMaxRelatedEntitiesPerCfArgument() + "'. Increase the limit in the tenant profile configuration."
);
}
}
}

8
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesAggregationCalculatedFieldState.java

@ -183,7 +183,7 @@ public class RelatedEntitiesAggregationCalculatedFieldState extends BaseCalculat
}
public void scheduleReevaluation() {
ScheduledFuture<?> future = ctx.scheduleReevaluation(deduplicationIntervalMs, actorCtx);
ScheduledFuture<?> future = ctx.scheduleReevaluation(getEnforcedDeduplicationIntervalMillis(), actorCtx);
if (future != null) {
reevaluationFuture = future;
}
@ -209,11 +209,15 @@ public class RelatedEntitiesAggregationCalculatedFieldState extends BaseCalculat
}
private boolean shouldRecalculate() {
boolean intervalPassed = lastMetricsEvalTs <= System.currentTimeMillis() - deduplicationIntervalMs;
boolean intervalPassed = lastMetricsEvalTs <= System.currentTimeMillis() - getEnforcedDeduplicationIntervalMillis();
boolean argsUpdatedDuringInterval = lastArgsRefreshTs > lastMetricsEvalTs;
return intervalPassed && argsUpdatedDuringInterval;
}
private long getEnforcedDeduplicationIntervalMillis() {
return Math.max(deduplicationIntervalMs, ctx.getMinDeduplicationIntervalMillis());
}
private Map<EntityId, Map<String, ArgumentEntry>> prepareInputs() {
Map<EntityId, Map<String, ArgumentEntry>> inputs = new HashMap<>();
for (Map.Entry<String, ArgumentEntry> argEntry : arguments.entrySet()) {

18
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesArgumentEntry.java

@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.HasEntityLimit;
import org.thingsboard.server.service.cf.ctx.state.HasLatestTs;
import org.thingsboard.server.service.cf.ctx.state.SingleValueArgumentEntry;
@ -34,7 +35,7 @@ import static org.thingsboard.server.service.cf.ctx.state.BaseCalculatedFieldSta
@Data
@AllArgsConstructor
public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs {
public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs, HasEntityLimit {
private final Map<EntityId, ArgumentEntry> entityInputs;
@ -66,18 +67,18 @@ public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs
@Override
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof RelatedEntitiesArgumentEntry relatedEntitiesArgumentEntry) {
checkRelatedEntitiesNumber(ctx);
checkEntityLimit(entityInputs.size(), ctx);
entityInputs.putAll(relatedEntitiesArgumentEntry.entityInputs);
} else if (entry instanceof SingleValueArgumentEntry singleValueArgumentEntry) {
if (entry.isForceResetPrevious()) {
checkRelatedEntitiesNumber(ctx);
checkEntityLimit(entityInputs.size(), ctx);
entityInputs.put(singleValueArgumentEntry.getEntityId(), singleValueArgumentEntry);
} else {
ArgumentEntry argumentEntry = entityInputs.get(singleValueArgumentEntry.getEntityId());
if (argumentEntry != null) {
argumentEntry.updateEntry(singleValueArgumentEntry, ctx);
} else {
checkRelatedEntitiesNumber(ctx);
checkEntityLimit(entityInputs.size(), ctx);
entityInputs.put(singleValueArgumentEntry.getEntityId(), singleValueArgumentEntry);
}
}
@ -87,15 +88,6 @@ public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs
return true;
}
private void checkRelatedEntitiesNumber(CalculatedFieldCtx ctx) {
if (entityInputs.size() >= ctx.getMaxRelatedEntitiesPerCfArgument()) {
throw new IllegalArgumentException(
"Exceeded the maximum allowed related entities per argument '"
+ ctx.getMaxRelatedEntitiesPerCfArgument() + "'. Increase the limit in the tenant profile configuration."
);
}
}
@Override
public boolean isEmpty() {
return entityInputs.isEmpty();

10
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/propagation/PropagationArgumentEntry.java

@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.HasEntityLimit;
import java.util.ArrayList;
import java.util.Collection;
@ -30,7 +31,7 @@ import java.util.List;
import java.util.Set;
@Data
public class PropagationArgumentEntry implements ArgumentEntry {
public class PropagationArgumentEntry implements ArgumentEntry, HasEntityLimit {
private Set<EntityId> entityIds;
private transient List<EntityId> added;
@ -93,12 +94,7 @@ public class PropagationArgumentEntry implements ArgumentEntry {
private boolean checkAdded(Collection<EntityId> updatedIds, CalculatedFieldCtx ctx) {
for (EntityId id : updatedIds) {
if (entityIds.size() >= ctx.getMaxRelatedEntitiesPerCfArgument()) {
throw new IllegalArgumentException(
"Exceeded the maximum allowed related entities per argument '"
+ ctx.getMaxRelatedEntitiesPerCfArgument() + "'. Increase the limit in the tenant profile configuration."
);
}
checkEntityLimit(entityIds.size(), ctx);
if (entityIds.add(id)) {
if (added == null) {
added = new ArrayList<>();

8
common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java

@ -172,12 +172,12 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
private long maxCalculatedFieldsPerEntity = 5;
@Schema(example = "10")
private long maxArgumentsPerCF = 10;
@Schema(example = "60")
private int minAllowedScheduledUpdateIntervalInSecForCF = 60;
@Builder.Default
@Schema(example = "10")
private int minAllowedScheduledUpdateIntervalInSecForCF = 10;
@Builder.Default
@Schema(example = "2")
@Positive
private int maxRelationLevelPerCfArgument = 10;
private int maxRelationLevelPerCfArgument = 2;
@Builder.Default
@Schema(example = "100")
@Positive

4
ui-ngx/src/app/shared/models/tenant.model.ts

@ -179,11 +179,11 @@ export function createTenantProfileConfiguration(type: TenantProfileType): Tenan
maxCalculatedFieldsPerEntity: 5,
maxArgumentsPerCF: 10,
maxDataPointsPerRollingArg: 1000,
maxRelationLevelPerCfArgument: 10,
maxRelationLevelPerCfArgument: 2,
minAllowedDeduplicationIntervalInSecForCF: 10,
minAllowedAggregationIntervalInSecForCF: 60,
maxRelatedEntitiesToReturnPerCfArgument: 100,
minAllowedScheduledUpdateIntervalInSecForCF: 0,
minAllowedScheduledUpdateIntervalInSecForCF: 10,
intermediateAggregationIntervalInSecForCF: 300,
cfReevaluationCheckInterval: 60,
alarmsReevaluationInterval: 60,

Loading…
Cancel
Save