org.jetlinks.rule.engine.defaults.AbstractOutput Maven / Gradle / Ivy
The newest version!
package org.jetlinks.rule.engine.defaults;
import org.apache.commons.collections.CollectionUtils;
import org.jetlinks.core.trace.TraceHolder;
import org.jetlinks.core.utils.Reactors;
import org.jetlinks.rule.engine.api.RuleConstants;
import org.jetlinks.rule.engine.api.RuleData;
import org.jetlinks.rule.engine.api.scheduler.ScheduleJob;
import org.jetlinks.rule.engine.api.task.ConditionEvaluator;
import org.jetlinks.rule.engine.api.task.Output;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public abstract class AbstractOutput implements Output {
protected final String instanceId;
private final List outputs;
private final ConditionEvaluator evaluator;
private Function> writer;
public AbstractOutput(String instanceId,
List outputs,
ConditionEvaluator evaluator) {
this.instanceId = instanceId;
this.outputs = outputs;
this.evaluator = evaluator;
prepare();
}
//预处理规则数据输出逻辑
private void prepare() {
//没有输出
if (CollectionUtils.isEmpty(outputs)) {
writer = data -> Reactors.ALWAYS_TRUE;
} else {
List>> writers = new ArrayList<>(outputs.size());
for (ScheduleJob.Output output : outputs) {
String address = createOutputAddress(output.getOutput());
Function> writer;
//配置了输出条件
if (output.getCondition() != null) {
Function> condition = evaluator.prepare(output.getCondition());
writer = data -> condition
.apply(data)
.flatMap(passed -> {
//条件判断返回true才认为成功
if (passed) {
return doWrite(address, data);
}
return Reactors.ALWAYS_FALSE;
});
} else {
writer = (data) -> doWrite(address, data);
}
writers.add(writer);
}
Flux>> flux = Flux.fromIterable(writers);
this.writer = data -> TraceHolder
.writeContextTo(data, RuleData::setHeader)
.flatMap(ruleData -> flux
.flatMap(writer -> writer
.apply(ruleData)
.onErrorResume(err -> Reactors.ALWAYS_FALSE))
.reduce(Boolean::logicalAnd));
}
}
@Override
public final Mono write(RuleData data) {
return writer.apply(data);
}
@Override
public final Mono write(Publisher dataStream) {
return Flux
.from(dataStream)
.flatMap(this::write)
.reduce(Boolean::logicalAnd);
}
@Override
public final Mono write(String nodeId, Publisher data) {
return doWrite(createOutputAddress(nodeId), data)
.then();
}
protected abstract Mono doWrite(String address, Publisher data);
protected abstract Mono doWrite(String address, RuleData data);
@Override
public final Mono write(String nodeId, RuleData data) {
return doWrite(createOutputAddress(nodeId), data)
.then();
}
protected String createOutputAddress(String nodeId) {
return RuleConstants.Topics.input(instanceId, nodeId);
}
}