WIP: arguments

This commit is contained in:
Andrii Shvaika 2025-02-11 19:10:55 +02:00
parent d75bc3ac28
commit 4048afecc3
6 changed files with 130 additions and 4 deletions

View File

@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.ScriptType;

View File

@ -21,12 +21,18 @@ import com.google.common.util.concurrent.MoreExecutors;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.mvel2.execution.ExecutionArrayList;
import org.thingsboard.script.api.tbel.TbCfArg;
import org.thingsboard.script.api.tbel.TbCfSingleValueArg;
import org.thingsboard.script.api.tbel.TbCfTsRollingArg;
import org.thingsboard.server.common.data.cf.CalculatedFieldType;
import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.Output;
import org.thingsboard.server.common.data.kv.BasicKvEntry;
import org.thingsboard.server.service.cf.CalculatedFieldResult;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -62,8 +68,9 @@ public class ScriptCalculatedFieldState extends BaseCalculatedFieldState {
}
});
Object[] args = ctx.getArgNames().stream()
.map(key -> arguments.get(key).getValue())
.map(this::toTbelArgument)
.toArray();
ListenableFuture<Map<String, Object>> resultFuture = ctx.getCalculatedFieldScriptEngine().executeToMapAsync(args);
Output output = ctx.getOutput();
return Futures.transform(resultFuture,
@ -72,4 +79,20 @@ public class ScriptCalculatedFieldState extends BaseCalculatedFieldState {
);
}
private TbCfArg toTbelArgument(String key) {
ArgumentEntry argEntry = arguments.get(key);
if (argEntry instanceof SingleValueArgumentEntry svArg) {
return new TbCfSingleValueArg(svArg.getTs(), argEntry.getValue());
} else if (argEntry instanceof TsRollingArgumentEntry rollingArg) {
var tsRecords = rollingArg.getTsRecords();
List<TbCfSingleValueArg> values = new ArrayList<>(tsRecords.size());
for(var e : tsRecords.entrySet()){
values.add(new TbCfSingleValueArg(e.getKey(), e.getValue().getValue()));
}
return new TbCfTsRollingArg(values);
} else {
throw new RuntimeException("Argument is not supported for TBEL execution!");
}
}
}

View File

@ -32,6 +32,7 @@ import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.SandboxedParserConfiguration;
import org.mvel2.ScriptMemoryOverflowException;
import org.mvel2.integration.PropertyHandlerFactory;
import org.mvel2.optimizers.OptimizerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -130,9 +131,11 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
parserConfig = ParserContext.enableSandboxedMode();
parserConfig.addImport("JSON", TbJson.class);
parserConfig.registerDataType("Date", TbDate.class, date -> 8L);
parserConfig.registerDataType("Random", Random.class, date -> 8L);
parserConfig.registerDataType("Calendar", Calendar.class, date -> 8L);
parserConfig.registerDataType("Date", TbDate.class, val -> 8L);
parserConfig.registerDataType("Random", Random.class, val -> 8L);
parserConfig.registerDataType("Calendar", Calendar.class, val -> 8L);
parserConfig.registerDataType("TbCfSingleValueArg", TbCfSingleValueArg.class, TbCfSingleValueArg::memorySize);
parserConfig.registerDataType("TbCfTsRollingArg", TbCfTsRollingArg.class, TbCfTsRollingArg::memorySize);
TbUtils.register(parserConfig);
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(threadPoolSize, "tbel-executor"));
try {

View File

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2024 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.script.api.tbel;
public interface TbCfArg {
long memorySize();
}

View File

@ -0,0 +1,30 @@
/**
* Copyright © 2016-2024 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.script.api.tbel;
import lombok.Data;
@Data
public class TbCfSingleValueArg implements TbCfArg {
private final long ts;
private final Object value;
@Override
public long memorySize() {
return 8L; // TODO;
}
}

View File

@ -0,0 +1,47 @@
/**
* Copyright © 2016-2024 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.script.api.tbel;
import lombok.Getter;
import java.util.List;
public class TbCfTsRollingArg implements TbCfArg {
@Getter
private final List<TbCfSingleValueArg> values;
public TbCfTsRollingArg(List<TbCfSingleValueArg> values) {
this.values = values;
}
@Override
public long memorySize() {
return values.size() * 8L; //TODO;
}
public double max() {
double max = Double.MIN_VALUE;
for (TbCfSingleValueArg arg : values) {
double val = Double.valueOf(arg.getValue().toString());
if (max < val) {
max = val;
}
}
return max;
}
}