Make script compilation errors unrecoverable during rule node initialization
This commit is contained in:
parent
12863e5274
commit
69964a2413
@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.thingsboard.rule.engine.api.ScriptEngine;
|
||||
import org.thingsboard.script.api.ScriptInvokeService;
|
||||
import org.thingsboard.script.api.ScriptType;
|
||||
import org.thingsboard.script.api.TbScriptException;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.msg.TbMsg;
|
||||
@ -32,7 +33,6 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public abstract class RuleNodeScriptEngine<T extends ScriptInvokeService, R> implements ScriptEngine {
|
||||
|
||||
@ -51,7 +51,10 @@ public abstract class RuleNodeScriptEngine<T extends ScriptInvokeService, R> imp
|
||||
if (e instanceof ExecutionException) {
|
||||
t = e.getCause();
|
||||
}
|
||||
throw new IllegalArgumentException("Can't compile script: " + t.getMessage(), t);
|
||||
if (t instanceof TbScriptException scriptException) {
|
||||
throw scriptException;
|
||||
}
|
||||
throw new RuntimeException("Unexpected error when creating script engine: " + t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +84,6 @@ public abstract class RuleNodeScriptEngine<T extends ScriptInvokeService, R> imp
|
||||
return Futures.transformAsync(executeScriptAsync(msg), this::executeToStringTransform, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Boolean> executeFilterAsync(TbMsg msg) {
|
||||
return Futures.transformAsync(executeScriptAsync(msg),
|
||||
|
||||
@ -19,8 +19,8 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.common.util.RecoveryAware;
|
||||
import org.thingsboard.server.common.msg.MsgType;
|
||||
import org.thingsboard.server.common.msg.TbActorError;
|
||||
import org.thingsboard.server.common.msg.TbActorMsg;
|
||||
import org.thingsboard.server.common.msg.TbActorStopReason;
|
||||
|
||||
@ -35,6 +35,7 @@ import java.util.function.Supplier;
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public final class TbActorMailbox implements TbActorCtx {
|
||||
|
||||
private static final boolean HIGH_PRIORITY = true;
|
||||
private static final boolean NORMAL_PRIORITY = false;
|
||||
|
||||
@ -100,7 +101,7 @@ public final class TbActorMailbox implements TbActorCtx {
|
||||
if (t instanceof TbActorException && t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
return t instanceof TbActorError && ((TbActorError) t).isUnrecoverable();
|
||||
return t instanceof RecoveryAware recoveryAware && recoveryAware.isUnrecoverable();
|
||||
}
|
||||
|
||||
private void enqueue(TbActorMsg msg, boolean highPriority) {
|
||||
|
||||
@ -16,13 +16,24 @@
|
||||
package org.thingsboard.script.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.thingsboard.common.util.RecoveryAware;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TbScriptException extends RuntimeException {
|
||||
public class TbScriptException extends RuntimeException implements RecoveryAware {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -1958193538782818284L;
|
||||
|
||||
public static enum ErrorCode {COMPILATION, TIMEOUT, RUNTIME, OTHER}
|
||||
public enum ErrorCode {
|
||||
|
||||
COMPILATION,
|
||||
TIMEOUT,
|
||||
RUNTIME,
|
||||
OTHER
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final UUID scriptId;
|
||||
@ -37,4 +48,10 @@ public class TbScriptException extends RuntimeException {
|
||||
this.errorCode = errorCode;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnrecoverable() {
|
||||
return errorCode == ErrorCode.COMPILATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import delight.nashornsandbox.NashornSandbox;
|
||||
import delight.nashornsandbox.NashornSandboxes;
|
||||
import delight.nashornsandbox.exceptions.ScriptCPUAbuseException;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.Getter;
|
||||
@ -153,8 +154,12 @@ public class NashornJsInvokeService extends AbstractJsInvokeService {
|
||||
}
|
||||
scriptInfoMap.put(scriptId, scriptInfo);
|
||||
return scriptId;
|
||||
} catch (Exception e) {
|
||||
} catch (ScriptException e) {
|
||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, jsScript, e);
|
||||
} catch (ScriptCPUAbuseException e) {
|
||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.TIMEOUT, jsScript, e);
|
||||
} catch (Exception e) {
|
||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, jsScript, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import jakarta.annotation.PreDestroy;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mvel2.CompileException;
|
||||
import org.mvel2.ExecutionContext;
|
||||
import org.mvel2.MVEL;
|
||||
import org.mvel2.ParserContext;
|
||||
@ -52,11 +53,11 @@ import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -66,9 +67,9 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
@Service
|
||||
public class DefaultTbelInvokeService extends AbstractScriptInvokeService implements TbelInvokeService {
|
||||
|
||||
protected final Map<UUID, String> scriptIdToHash = new ConcurrentHashMap<>();
|
||||
protected final Map<String, TbelScript> scriptMap = new ConcurrentHashMap<>();
|
||||
protected Cache<String, Serializable> compiledScriptsCache;
|
||||
private final ConcurrentMap<UUID, String> scriptIdToHash = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, TbelScript> scriptMap = new ConcurrentHashMap<>();
|
||||
private Cache<String, Serializable> compiledScriptsCache;
|
||||
|
||||
private SandboxedParserConfiguration parserConfig;
|
||||
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
|
||||
@ -204,8 +205,10 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
|
||||
lock.unlock();
|
||||
}
|
||||
return scriptId;
|
||||
} catch (Exception e) {
|
||||
} catch (CompileException e) {
|
||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, e);
|
||||
} catch (Exception e) {
|
||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, scriptBody, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -246,7 +249,7 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
|
||||
}
|
||||
}
|
||||
|
||||
private Serializable compileScript(String scriptBody) {
|
||||
private static Serializable compileScript(String scriptBody) throws CompileException {
|
||||
return MVEL.compileExpression(scriptBody, new ParserContext());
|
||||
}
|
||||
|
||||
@ -269,4 +272,5 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
|
||||
protected StatsType getStatsType() {
|
||||
return StatsType.TBEL_INVOKE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.common.msg;
|
||||
package org.thingsboard.common.util;
|
||||
|
||||
public interface TbActorError {
|
||||
public interface RecoveryAware {
|
||||
|
||||
boolean isUnrecoverable();
|
||||
|
||||
@ -16,12 +16,9 @@
|
||||
package org.thingsboard.rule.engine.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.thingsboard.server.common.msg.TbActorError;
|
||||
import org.thingsboard.common.util.RecoveryAware;
|
||||
|
||||
/**
|
||||
* Created by ashvayka on 19.01.18.
|
||||
*/
|
||||
public class TbNodeException extends Exception implements TbActorError {
|
||||
public class TbNodeException extends Exception implements RecoveryAware {
|
||||
|
||||
@Getter
|
||||
private final boolean unrecoverable;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user