Improve config of 'originator fields' node. Add UI config for 'originator fields' and 'check relation' nodes.
This commit is contained in:
parent
7a687f373c
commit
9ea4fcce6f
@ -15,10 +15,18 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by ashvayka on 01.06.18.
|
||||
*/
|
||||
@ -26,13 +34,54 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
@AllArgsConstructor
|
||||
public class EntityFieldsData {
|
||||
|
||||
public static final String DEFAULT = "default";
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private final EntityId entityId;
|
||||
private final String name;
|
||||
private final String type;
|
||||
|
||||
public EntityFieldsData(EntityId entityId, String name) {
|
||||
this(entityId, name, DEFAULT);
|
||||
static {
|
||||
SimpleModule entityFieldsModule = new SimpleModule("EntityFieldsModule", new Version(1, 0, 0, null, null, null));
|
||||
entityFieldsModule.addSerializer(EntityId.class, new EntityIdFieldSerializer());
|
||||
mapper.disable(MapperFeature.USE_ANNOTATIONS);
|
||||
mapper.registerModule(entityFieldsModule);
|
||||
}
|
||||
|
||||
private ObjectNode fieldsData;
|
||||
|
||||
public EntityFieldsData(BaseData data) {
|
||||
fieldsData = mapper.valueToTree(data);
|
||||
}
|
||||
|
||||
public String getFieldValue(String field) {
|
||||
String[] fieldsTree = field.split("\\.");
|
||||
JsonNode current = fieldsData;
|
||||
for (String key : fieldsTree) {
|
||||
if (current.has(key)) {
|
||||
current = current.get(key);
|
||||
} else {
|
||||
current = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current != null) {
|
||||
if (current.isValueNode()) {
|
||||
return current.asText();
|
||||
} else {
|
||||
try {
|
||||
return mapper.writeValueAsString(current);
|
||||
} catch (JsonProcessingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntityIdFieldSerializer extends JsonSerializer<EntityId> {
|
||||
|
||||
@Override
|
||||
public void serialize(EntityId value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
gen.writeObject(value.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,9 @@ import static org.thingsboard.rule.engine.api.util.DonAsynchron.withCallback;
|
||||
configClazz = TbCheckRelationNodeConfiguration.class,
|
||||
relationTypes = {"True", "False"},
|
||||
nodeDescription = "Checks the relation from the selected entity to originator of the message by type and direction",
|
||||
nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.")
|
||||
nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
|
||||
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
configDirective = "tbFilterNodeCheckRelationConfig")
|
||||
public class TbCheckRelationNode implements TbNode {
|
||||
|
||||
private TbCheckRelationNodeConfiguration config;
|
||||
|
||||
@ -18,21 +18,21 @@ package org.thingsboard.rule.engine.metadata;
|
||||
import lombok.Data;
|
||||
import org.thingsboard.rule.engine.api.NodeConfiguration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class TbGetOriginatorFieldsConfiguration implements NodeConfiguration<TbGetOriginatorFieldsConfiguration> {
|
||||
|
||||
private boolean fetchName;
|
||||
private String nameMetadataKey;
|
||||
private boolean fetchType;
|
||||
private String typeMetadataKey;
|
||||
private Map<String, String> fieldsMapping;
|
||||
|
||||
@Override
|
||||
public TbGetOriginatorFieldsConfiguration defaultConfiguration() {
|
||||
TbGetOriginatorFieldsConfiguration configuration = new TbGetOriginatorFieldsConfiguration();
|
||||
configuration.setFetchName(true);
|
||||
configuration.setNameMetadataKey("entityName");
|
||||
configuration.setFetchType(true);
|
||||
configuration.setTypeMetadataKey("entityType");
|
||||
Map<String, String> fieldsMapping = new HashMap<>();
|
||||
fieldsMapping.put("name", "originatorName");
|
||||
fieldsMapping.put("type", "originatorType");
|
||||
configuration.setFieldsMapping(fieldsMapping);
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,11 +18,7 @@ package org.thingsboard.rule.engine.metadata;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.thingsboard.rule.engine.api.RuleNode;
|
||||
import org.thingsboard.rule.engine.api.TbContext;
|
||||
import org.thingsboard.rule.engine.api.TbNode;
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
|
||||
import org.thingsboard.rule.engine.api.TbNodeException;
|
||||
import org.thingsboard.rule.engine.api.*;
|
||||
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
|
||||
import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
@ -37,10 +33,12 @@ import static org.thingsboard.rule.engine.api.util.DonAsynchron.withCallback;
|
||||
*/
|
||||
@Slf4j
|
||||
@RuleNode(type = ComponentType.ENRICHMENT,
|
||||
name = "entity fields",
|
||||
name = "originator fields",
|
||||
configClazz = TbGetOriginatorFieldsConfiguration.class,
|
||||
nodeDescription = "Add Message Originator Name and Type into Message Metadata",
|
||||
nodeDetails = "If originator is Asset, Device or Alarm, both name and type are added. In all other cases type will always be \"default\"")
|
||||
nodeDescription = "Add Message Originator fields values into Message Metadata",
|
||||
nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored.",
|
||||
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
configDirective = "tbEnrichmentNodeOriginatorFieldsConfig")
|
||||
public class TbGetOriginatorFieldsNode implements TbNode {
|
||||
|
||||
private TbGetOriginatorFieldsConfiguration config;
|
||||
@ -61,17 +59,17 @@ public class TbGetOriginatorFieldsNode implements TbNode {
|
||||
}
|
||||
|
||||
private ListenableFuture<Void> putEntityFields(TbContext ctx, EntityId entityId, TbMsg msg) {
|
||||
if (!config.isFetchName() && !config.isFetchType()) {
|
||||
if (config.getFieldsMapping().isEmpty()) {
|
||||
return Futures.immediateFuture(null);
|
||||
} else {
|
||||
return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId),
|
||||
data -> {
|
||||
if (config.isFetchName()) {
|
||||
msg.getMetaData().putValue(config.getNameMetadataKey(), data.getName());
|
||||
}
|
||||
if (config.isFetchType()) {
|
||||
msg.getMetaData().putValue(config.getTypeMetadataKey(), data.getType());
|
||||
}
|
||||
config.getFieldsMapping().forEach((field, metaKey) -> {
|
||||
String val = data.getFieldValue(field);
|
||||
if (val != null) {
|
||||
msg.getMetaData().putValue(metaKey, val);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
@ -38,25 +38,25 @@ public class EntitiesFieldsAsyncLoader {
|
||||
switch (original.getEntityType()) {
|
||||
case TENANT:
|
||||
return getAsync(ctx.getTenantService().findTenantByIdAsync((TenantId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case CUSTOMER:
|
||||
return getAsync(ctx.getCustomerService().findCustomerByIdAsync((CustomerId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case USER:
|
||||
return getAsync(ctx.getUserService().findUserByIdAsync((UserId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case ASSET:
|
||||
return getAsync(ctx.getAssetService().findAssetByIdAsync((AssetId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName(), t.getType()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case DEVICE:
|
||||
return getAsync(ctx.getDeviceService().findDeviceByIdAsync((DeviceId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName(), t.getType()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case ALARM:
|
||||
return getAsync(ctx.getAlarmService().findAlarmByIdAsync((AlarmId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName(), t.getType()));
|
||||
t -> new EntityFieldsData(t));
|
||||
case RULE_CHAIN:
|
||||
return getAsync(ctx.getRuleChainService().findRuleChainByIdAsync((RuleChainId) original),
|
||||
t -> new EntityFieldsData(t.getId(), t.getName()));
|
||||
t -> new EntityFieldsData(t));
|
||||
default:
|
||||
return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original));
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user