Browse Source

added check for single value size

pull/12830/head
IrynaMatveieva 1 year ago
parent
commit
c404dd2cf5
  1. 2
      application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
  2. 2
      application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java
  3. 17
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/BaseCalculatedFieldState.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java
  5. 4
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldState.java
  6. 4
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldStateTest.java
  7. 6
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldStateTest.java

2
application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java

@ -242,7 +242,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
justRestored = true;
}
if (state.isSizeOk()) {
if (state.updateState(newArgValues) || justRestored) {
if (state.updateState(newArgValues, ctx) || justRestored) {
cfIdList = new ArrayList<>(cfIdList);
cfIdList.add(ctx.getCfId());
processStateIfReady(ctx, cfIdList, state, tbMsgId, tbMsgType, callback);

2
application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java

@ -136,7 +136,7 @@ public class DefaultCalculatedFieldProcessingService implements CalculatedFieldP
throw new RuntimeException("Error getting future result for key: " + entry.getKey(), e);
}
}
)));
)), ctx);
return result;
}, calculatedFieldCallbackExecutor);
}

17
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/BaseCalculatedFieldState.java

@ -25,6 +25,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.thingsboard.server.utils.CalculatedFieldUtils.toSingleValueArgumentProto;
@Data
@AllArgsConstructor
public abstract class BaseCalculatedFieldState implements CalculatedFieldState {
@ -43,7 +45,7 @@ public abstract class BaseCalculatedFieldState implements CalculatedFieldState {
}
@Override
public boolean updateState(Map<String, ArgumentEntry> argumentValues) {
public boolean updateState(Map<String, ArgumentEntry> argumentValues, CalculatedFieldCtx ctx) {
if (arguments == null) {
arguments = new HashMap<>();
}
@ -53,6 +55,9 @@ public abstract class BaseCalculatedFieldState implements CalculatedFieldState {
for (Map.Entry<String, ArgumentEntry> entry : argumentValues.entrySet()) {
String key = entry.getKey();
ArgumentEntry newEntry = entry.getValue();
checkArgumentSize(key, newEntry, ctx);
ArgumentEntry existingEntry = arguments.get(key);
if (existingEntry == null || newEntry.isForceResetPrevious()) {
@ -81,6 +86,16 @@ public abstract class BaseCalculatedFieldState implements CalculatedFieldState {
}
}
@Override
public void checkArgumentSize(String name, ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof TsRollingArgumentEntry) {
return;
}
if (ctx.getMaxSingleValueArgumentSize() > 0 && toSingleValueArgumentProto(name, (SingleValueArgumentEntry) entry).getSerializedSize() > ctx.getMaxSingleValueArgumentSize()) {
throw new IllegalArgumentException("Single value size exceeds the maximum allowed limit. The argument will not be used for calculation.");
}
}
protected abstract void validateNewEntry(ArgumentEntry newEntry);
}

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

@ -71,6 +71,7 @@ public class CalculatedFieldCtx {
private long maxDataPointsPerRollingArg;
private long maxStateSize;
private long maxSingleValueArgumentSize;
public CalculatedFieldCtx(CalculatedField calculatedField, TbelInvokeService tbelInvokeService, ApiLimitService apiLimitService) {
this.calculatedField = calculatedField;
@ -104,6 +105,7 @@ public class CalculatedFieldCtx {
this.maxDataPointsPerRollingArg = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getMaxDataPointsPerRollingArg);
this.maxStateSize = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getMaxStateSizeInKBytes) * 1024;
this.maxSingleValueArgumentSize = apiLimitService.getLimit(tenantId, DefaultTenantProfileConfiguration::getMaxSingleValueArgumentSizeInKBytes) * 1024;
}
public void init() {

4
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldState.java

@ -44,7 +44,7 @@ public interface CalculatedFieldState {
void setRequiredArguments(List<String> requiredArguments);
boolean updateState(Map<String, ArgumentEntry> argumentValues);
boolean updateState(Map<String, ArgumentEntry> argumentValues, CalculatedFieldCtx ctx);
ListenableFuture<CalculatedFieldResult> performCalculation(CalculatedFieldCtx ctx);
@ -60,4 +60,6 @@ public interface CalculatedFieldState {
void checkStateSize(CalculatedFieldEntityCtxId ctxId, long maxStateSize);
void checkArgumentSize(String name, ArgumentEntry entry, CalculatedFieldCtx ctx);
}

4
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldStateTest.java

@ -90,7 +90,7 @@ public class ScriptCalculatedFieldStateTest {
state.arguments = new HashMap<>(Map.of("assetHumidity", assetHumidityArgEntry));
Map<String, ArgumentEntry> newArgs = Map.of("deviceTemperature", deviceTemperatureArgEntry);
boolean stateUpdated = state.updateState(newArgs);
boolean stateUpdated = state.updateState(newArgs, ctx);
assertThat(stateUpdated).isTrue();
assertThat(state.getArguments()).containsExactlyInAnyOrderEntriesOf(
@ -107,7 +107,7 @@ public class ScriptCalculatedFieldStateTest {
SingleValueArgumentEntry newArgEntry = new SingleValueArgumentEntry(ts, new LongDataEntry("assetHumidity", 41L), 349L);
Map<String, ArgumentEntry> newArgs = Map.of("assetHumidity", newArgEntry);
boolean stateUpdated = state.updateState(newArgs);
boolean stateUpdated = state.updateState(newArgs, ctx);
assertThat(stateUpdated).isTrue();
assertThat(state.getArguments()).containsExactlyInAnyOrderEntriesOf(

6
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldStateTest.java

@ -88,7 +88,7 @@ public class SimpleCalculatedFieldStateTest {
));
Map<String, ArgumentEntry> newArgs = Map.of("key3", key3ArgEntry);
boolean stateUpdated = state.updateState(newArgs);
boolean stateUpdated = state.updateState(newArgs, ctx);
assertThat(stateUpdated).isTrue();
assertThat(state.getArguments()).containsExactlyInAnyOrderEntriesOf(
@ -106,7 +106,7 @@ public class SimpleCalculatedFieldStateTest {
SingleValueArgumentEntry newArgEntry = new SingleValueArgumentEntry(System.currentTimeMillis(), new LongDataEntry("key1", 18L), 190L);
Map<String, ArgumentEntry> newArgs = Map.of("key1", newArgEntry);
boolean stateUpdated = state.updateState(newArgs);
boolean stateUpdated = state.updateState(newArgs, ctx);
assertThat(stateUpdated).isTrue();
assertThat(state.getArguments()).containsExactlyInAnyOrderEntriesOf(Map.of("key1", newArgEntry));
@ -120,7 +120,7 @@ public class SimpleCalculatedFieldStateTest {
));
Map<String, ArgumentEntry> newArgs = Map.of("key3", new TsRollingArgumentEntry(10, 30000L));
assertThatThrownBy(() -> state.updateState(newArgs))
assertThatThrownBy(() -> state.updateState(newArgs, ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Rolling argument entry is not supported for simple calculated fields.");
}

Loading…
Cancel
Save