fix rule node descriptions & fix validation messages & updated tests

This commit is contained in:
ShvaykaD 2023-05-22 15:57:26 +03:00
parent 2a51125358
commit d67313cf8c
14 changed files with 87 additions and 80 deletions

View File

@ -48,10 +48,10 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
name = "calculate delta", relationTypes = {"Success", "Failure", "Other"},
configClazz = CalculateDeltaNodeConfiguration.class,
nodeDescription = "Calculates and adds 'delta' value into message based on the incoming and previous value",
nodeDetails = "Calculates delta and period based on the previous time-series reading and current data. " +
"Delta calculation is done in scope of the message originator, e.g. device, asset or customer. " +
"If there is input key, the output relation will be 'Success' unless delta is negative and corresponding configuration parameter is set. " +
"If there is no input value key in the incoming message, the output relation will be 'Other'.",
nodeDetails = "Calculates delta and period based on the previous timeseries reading and current data. " +
"Delta calculation is done in scope of the message originator, e.g. device, asset or customer.<br><br>" +
"If there is input key, the output relation will be <code>Success</code> unless delta is negative and corresponding configuration parameter is set. <br>" +
"If there is no input value key in the incoming message, the output relation will be <code>Other</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeCalculateDeltaConfig")
public class CalculateDeltaNode implements TbNode {

View File

@ -30,10 +30,13 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
@Slf4j
public abstract class TbAbstractGetEntityDataNode<T extends EntityId> extends TbAbstractGetMappedDataNode<T, TbGetEntityDataNodeConfiguration> {
protected final static String DATA_TO_FETCH_PROPERTY_NAME = "dataToFetch";
protected static final String OLD_DATA_TO_FETCH_PROPERTY_NAME = "telemetry";
protected final static String DATA_MAPPING_PROPERTY_NAME = "dataMapping";
protected static final String OLD_DATA_MAPPING_PROPERTY_NAME = "attrMapping";
private final static String DATA_TO_FETCH_PROPERTY_NAME = "dataToFetch";
private static final String OLD_DATA_TO_FETCH_PROPERTY_NAME = "telemetry";
private final static String DATA_MAPPING_PROPERTY_NAME = "dataMapping";
private static final String OLD_DATA_MAPPING_PROPERTY_NAME = "attrMapping";
private static final String DATA_TO_FETCH_VALIDATION_MSG = "DataToFetch property has invalid value: %s." +
" Only ATTRIBUTES and LATEST_TELEMETRY values supported!";
@Override
public void onMsg(TbContext ctx, TbMsg msg) {
@ -45,7 +48,11 @@ public abstract class TbAbstractGetEntityDataNode<T extends EntityId> extends Tb
protected abstract ListenableFuture<T> findEntityAsync(TbContext ctx, EntityId originator);
protected abstract void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException;
protected void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException {
if (dataToFetch == null || dataToFetch.equals(DataToFetch.FIELDS)) {
throw new TbNodeException(String.format(DATA_TO_FETCH_VALIDATION_MSG, dataToFetch));
}
}
protected void processDataAndTell(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) {
DataToFetch dataToFetch = config.getDataToFetch();

View File

@ -37,11 +37,10 @@ import java.util.concurrent.ExecutionException;
type = ComponentType.ENRICHMENT,
name = "fetch device credentials",
configClazz = TbFetchDeviceCredentialsNodeConfiguration.class,
nodeDescription = "Enrich the message body or metadata with the device credentials",
nodeDetails = "Adds <b>credentialsType</b> and <b>credentials</b> properties to the message metadata if the " +
"configuration parameter <b>fetchToMetadata</b> is set to <code>true</code>, otherwise, adds properties " +
"to the message data. If originator type is not <b>DEVICE</b> or rule node failed to get device credentials " +
"- send Message via <code>Failure</code> chain, otherwise <code>Success</code> chain is used.",
nodeDescription = "Adds device credentials to the message or message metadata",
nodeDetails = "if message originator type is Device and device credentials was successfully fetched, " +
"rule node enriches message or message metadata with <i>credentialsType</i> and <i>credentials</i> properties " +
"and send message via <code>Success</code> chain. Otherwise message will be forwarded via <code>Failure</code> chain.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeFetchDeviceCredentialsConfig")
public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo<TbFetchDeviceCredentialsNodeConfiguration> {

View File

@ -36,11 +36,13 @@ import org.thingsboard.server.common.msg.TbMsg;
@RuleNode(type = ComponentType.ENRICHMENT,
name = "originator attributes",
configClazz = TbGetAttributesNodeConfiguration.class,
nodeDescription = "Enrich the message body or metadata with the originator attributes and/or timeseries data",
nodeDetails = "If Attributes enrichment configured, <b>CLIENT/SHARED/SERVER</b> attributes are added into Message data/metadata " +
"with specific prefix: <i>cs/shared/ss</i>. Latest telemetry value added into Message data/metadata without prefix. " +
"To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
nodeDescription = "Adds originator attributes and/or latest timeseries data for the message originator to the message or message metadata",
nodeDetails = "If attributes enrichment configured, <i>CLIENT/SHARED/SERVER</i> attributes are added into message or message metadata " +
"with specific prefix: <i>cs/shared/ss</i>. Latest telemetry value adds without prefix. <br><br>" +
"See the following examples of accessing those attributes in other nodes:<br>" +
"<code>metadata.cs_serialNumber</code> - to access client side attribute 'serialNumber' that was fetched to message metadata.<br>" +
"<code>metadata.shared_limit</code> - to access shared side attribute 'limit' that was fetched to message metadata.<br>" +
"<code>msg.temperature</code> - to access latest telemetry 'temperature' that was fetched to message.<br>",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorAttributesConfig")
public class TbGetAttributesNode extends TbAbstractGetAttributesNode<TbGetAttributesNodeConfiguration, EntityId> {

View File

@ -35,16 +35,17 @@ import org.thingsboard.server.common.data.util.TbPair;
type = ComponentType.ENRICHMENT,
name = "customer attributes",
configClazz = TbGetEntityDataNodeConfiguration.class,
nodeDescription = "Add Originators Customer Attributes or Latest Telemetry into Message or Metadata",
nodeDetails = "Enrich the Message or Metadata with the corresponding customer's latest attributes or telemetry value. " +
"The customer is selected based on the originator of the message: device, asset, etc. " +
"</br>" +
nodeDescription = "Adds message originator customer attributes or latest telemetry into message or message metadata",
nodeDetails = "Enriches incoming message or message metadata with the customer's attributes or latest telemetry values. <br><br>" +
"The customer is selected based on the originator of the message. " +
"Supported originator types: <br><br>" +
"Customer, User, Asset, Device. <br><br>" +
"Useful when you store some parameters on the customer level and would like to use them for message processing.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeCustomerAttributesConfig")
public class TbGetCustomerAttributeNode extends TbAbstractGetEntityDataNode<CustomerId> {
private static final String CUSTOMER_NOT_FOUND_MESSAGE = "Failed to find customer for entity with id %s and type %s";
private static final String CUSTOMER_NOT_FOUND_MESSAGE = "Failed to find customer for entity with id: %s and type: %s";
@Override
protected TbGetEntityDataNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException {
@ -54,14 +55,6 @@ public class TbGetCustomerAttributeNode extends TbAbstractGetEntityDataNode<Cust
return config;
}
@Override
protected void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException {
if (dataToFetch == null || dataToFetch.equals(DataToFetch.FIELDS)) {
throw new TbNodeException("DataToFetch property has invalid value: " + dataToFetch +
". Only ATTRIBUTES and LATEST_TELEMETRY values supported!");
}
}
@Override
protected ListenableFuture<CustomerId> findEntityAsync(TbContext ctx, EntityId originator) {
return Futures.transformAsync(EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, originator),

View File

@ -44,10 +44,13 @@ import java.util.NoSuchElementException;
@RuleNode(type = ComponentType.ENRICHMENT,
name = "customer details",
configClazz = TbGetCustomerDetailsNodeConfiguration.class,
nodeDescription = "Enrich the message body or metadata with the corresponding customer details: title, address, email, phone, etc.",
nodeDetails = "If checkbox: <b>Add selected details to the message metadata</b> is selected, existing fields will be added to the message metadata instead of message data.<br><br>" +
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
nodeDescription = "Adds originator customer details into message or message metadata",
nodeDetails = "Enriches incoming message or message metadata with the corresponding customer details. " +
"Selected details adds to the message with predefined prefix: <code>customer_</code>. Examples: <code>customer_title</code>, <code>customer_address</code>, etc. <br><br>" +
"The customer is selected based on the originator of the message. Supported originator types: <br><br>" +
"Device, Asset, Entity view, User, Edge. <br><br>" +
"If message originator is not assigned to customer, or originator is not supported - " +
"message will be forwarded via <code>Failure</code> chain, otherwise, <code>Success</code> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig")
public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetCustomerDetailsNodeConfiguration, CustomerId> {
@ -96,9 +99,9 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
if (hasCustomerId.getCustomerId() == null || hasCustomerId.getCustomerId().isNullUid()) {
if (hasCustomerId instanceof HasName) {
var hasName = (HasName) hasCustomerId;
throw new RuntimeException(originator.getEntityType().getNormalName() + " with name '" + hasName.getName() + "' is not assigned to Customer.");
throw new RuntimeException(originator.getEntityType().getNormalName() + " with name '" + hasName.getName() + "' is not assigned to Customer!");
}
throw new RuntimeException(originator.getEntityType().getNormalName() + " with id '" + originator + "' is not assigned to Customer.");
throw new RuntimeException(originator.getEntityType().getNormalName() + " with id '" + originator + "' is not assigned to Customer!");
} else {
return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), hasCustomerId.getCustomerId());
}

View File

@ -34,11 +34,15 @@ import org.thingsboard.server.common.msg.TbMsg;
@RuleNode(type = ComponentType.ENRICHMENT,
name = "related device attributes",
configClazz = TbGetDeviceAttrNodeConfiguration.class,
nodeDescription = "Add Originators Related Device Attributes and Latest Telemetry value into Message Data or Metadata",
nodeDetails = "If Attributes enrichment configured, <b>CLIENT/SHARED/SERVER</b> attributes are added into Message data/metadata " +
"with specific prefix: <i>cs/shared/ss</i>. Latest telemetry value added into Message data/metadata without prefix. " +
"To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
nodeDescription = "Add originators related device attributes and latest telemetry values into message or message metadata",
nodeDetails = "Related device lookup based on the configured relation query. " +
"If multiple related devices are found, only first device is used for message enrichment, other entities are discarded.<br><br>" +
"If Attributes enrichment configured, <i>CLIENT/SHARED/SERVER</i> attributes are added into message or message metadata " +
"with specific prefix: <i>cs/shared/ss</i>. Latest telemetry value adds into message or message metadata without prefix. <br><br>" +
"See the following examples of accessing those attributes in other nodes:<br>" +
"<code>metadata.cs_serialNumber</code> - to access client side attribute 'serialNumber' that was fetched to message metadata.<br>" +
"<code>metadata.shared_limit</code> - to access shared side attribute 'limit' that was fetched to message metadata.<br>" +
"<code>msg.temperature</code> - to access latest telemetry 'temperature' that was fetched to message.<br>",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeDeviceAttributesConfig")
public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode<TbGetDeviceAttrNodeConfiguration, DeviceId> {

View File

@ -37,9 +37,12 @@ import java.util.concurrent.ExecutionException;
@RuleNode(type = ComponentType.ENRICHMENT,
name = "originator fields",
configClazz = TbGetOriginatorFieldsConfiguration.class,
nodeDescription = "Add Message Originator fields values into Message Metadata or Message Data",
nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored. " +
"This node supports only following originator types: TENANT, CUSTOMER, USER, ASSET, DEVICE, ALARM, RULE_CHAIN, ENTITY_VIEW.",
nodeDescription = "Adds message originator fields values into message or message metadata",
nodeDetails = "Fetches fields values specified in the mapping. If specified field is not part of originator fields it will be ignored. " +
"Supported originator types: <br><br>" +
"Tenant, Customer, User, Asset, Device, Alarm, Rule chain, Entity view.<br><br>" +
"If message originator is not supported - message will be forwarded via <code>Failure</code> chain, " +
"otherwise, <code>Success</code> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorFieldsConfig")
public class TbGetOriginatorFieldsNode extends TbAbstractGetMappedDataNode<EntityId, TbGetOriginatorFieldsConfiguration> {

View File

@ -34,15 +34,18 @@ import java.util.Arrays;
@Slf4j
@RuleNode(
type = ComponentType.ENRICHMENT,
name = "related attributes",
name = "related entity data",
configClazz = TbGetRelatedDataNodeConfiguration.class,
nodeDescription = "Add Originators Related Entity Attributes or Latest Telemetry into Message Metadata/Data",
nodeDetails = "Related Entity found using configured relation direction and Relation Type. " +
"If multiple Related Entities are found, only first Entity is used for attributes enrichment, other entities are discarded. " +
"If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " +
"If Latest Telemetry enrichment configured, latest telemetry added into Metadata/Data. " +
"To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.",
nodeDescription = "Adds originators related entity data into message or message metadata",
nodeDetails = "Related entity lookup based on the configured relation query. " +
"If multiple related entities are found, only first entity is used for message enrichment, other entities are discarded.<br><br>" +
"Data to fetch configuration: <br><br>" +
"<i>Attributes</i> - rule node fetches server scope attributes configured in mapping and adds them into message or message metadata. " +
"Access example in other nodes: <code>metadata.serialNumber</code>, <code>msg.serialNumber</code>.<br>" +
"<i>Latest telemetry</i> - rule node fetches latest telemetry configured in mapping and adds them into message or message metadata. " +
"Access example in other nodes: <code>metadata.temperature</code>, <code>msg.temperature</code>.<br>" +
"<i>Fields</i> - rule node fetches fields configured in mapping and adds them into message or message metadata. " +
"Access example in other nodes: <code>metadata.entityName</code>, <code>msg.entityName</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeRelatedAttributesConfig")
public class TbGetRelatedAttributeNode extends TbAbstractGetEntityDataNode<EntityId> {

View File

@ -54,13 +54,17 @@ import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfigurati
@RuleNode(type = ComponentType.ENRICHMENT,
name = "originator telemetry",
configClazz = TbGetTelemetryNodeConfiguration.class,
nodeDescription = "Add Message Originator Telemetry for selected time range into Message Metadata\n",
nodeDetails = "The node allows you to select fetch mode: <b>FIRST/LAST/ALL</b> to fetch telemetry of certain time range that are added into Message metadata without any prefix. " +
"If selected fetch mode <b>ALL</b> Telemetry will be added like array into Message Metadata where <b>key</b> is Timestamp and <b>value</b> is value of Telemetry.</br>" +
"If selected fetch mode <b>FIRST</b> or <b>LAST</b> Telemetry will be added like string without Timestamp.</br>" +
"Also, the rule node allows you to select telemetry sampling order: <b>ASC</b> or <b>DESC</b>. </br>" +
"Aggregation feature allows you to fetch aggregated telemetry as a single value by <b>AVG, COUNT, SUM, MIN, MAX, NONE</b>. </br>" +
"<b>Note</b>: The maximum size of the fetched array is 1000 records.\n ",
nodeDescription = "Adds message originator telemetry for selected time range into message metadata",
nodeDetails = "The node allows you to configure fetch interval and fetch strategy. Fetch strategy section allows you to select fetch mode: <i>First/Last/All</i> <br><br>" +
"If selected fetch mode <i>First</i> rule node will retrieve the closest telemetry to the fetch interval's start.<br>" +
"If selected fetch mode <i>Last</i> rule node will retrieve the closest telemetry to the fetch interval's end.<br>" +
"If selected fetch mode <i>All</i> rule node will retrieve telemetry from the fetch interval with configurable query parameters.<br><br>" +
"Query parameters: <br><br>" +
"Data aggregation function: <i>Min/Max/Average/Sum/Count/None</i>. " +
"If selected aggregation function <i>None</i> rule node allows you to configure additional query parameters: <br><br>" +
"Order by timestamp: <i>Ascending/Descending</i><br><br>" +
"Limit: Min value - 2, max value - 1000.<br><br>" +
"Other data aggregation functions useful when you need to get the aggregated telemetry data as a single value for the configured fetch interval.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase")
public class TbGetTelemetryNode implements TbNode {

View File

@ -34,11 +34,9 @@ import org.thingsboard.server.common.data.util.TbPair;
type = ComponentType.ENRICHMENT,
name = "tenant attributes",
configClazz = TbGetEntityDataNodeConfiguration.class,
nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata/Data",
nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " +
"If Latest Telemetry enrichment configured, latest telemetry added into Metadata/Data. " +
"To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.",
nodeDescription = "Adds message originator tenant attributes or latest telemetry into message or message metadata",
nodeDetails = "Enriches incoming message or message metadata with the tenant's attributes or latest telemetry values. " +
"Useful when you store some parameters on the tenant level and would like to use them for message processing.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeTenantAttributesConfig")
public class TbGetTenantAttributeNode extends TbAbstractGetEntityDataNode<TenantId> {
@ -56,14 +54,6 @@ public class TbGetTenantAttributeNode extends TbAbstractGetEntityDataNode<Tenant
return Futures.immediateFuture(ctx.getTenantId());
}
@Override
protected void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException {
if (dataToFetch == null || dataToFetch.equals(DataToFetch.FIELDS)) {
throw new TbNodeException("DataToFetch property has invalid value: " + dataToFetch +
". Only ATTRIBUTES and LATEST_TELEMETRY values supported!");
}
}
@Override
public TbPair<Boolean, JsonNode> upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException {
return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration);

View File

@ -33,10 +33,9 @@ import org.thingsboard.server.common.msg.TbMsg;
@RuleNode(type = ComponentType.ENRICHMENT,
name = "tenant details",
configClazz = TbGetTenantDetailsNodeConfiguration.class,
nodeDescription = "Adds fields from Tenant details to the message body or metadata",
nodeDetails = "If checkbox: <b>Add selected details to the message metadata</b> is selected, existing fields will be added to the message metadata instead of message data.<br><br>" +
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
nodeDescription = "Adds originator tenant details into message or message metadata",
nodeDetails = "Enriches incoming message or message metadata with the corresponding tenant details. " +
"Selected details adds to the message with predefined prefix: <code>tenant_</code>, Examples: <code>tenant_title</code> or <code>tenant_address</code>, etc.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig")
public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetTenantDetailsNodeConfiguration, TenantId> {

View File

@ -262,7 +262,7 @@ public class TbGetCustomerAttributeNodeTest {
var actualException = actualExceptionCaptor.getValue();
var expectedExceptionMessage = String.format(
"Failed to find customer for entity with id %s and type %s",
"Failed to find customer for entity with id: %s and type: %s",
userId.getId(), userId.getEntityType().getNormalName());
assertEquals(msg, actualMessage);

View File

@ -385,7 +385,7 @@ public class TbGetCustomerDetailsNodeTest {
assertThat(actualMsg.getMetaData()).isEqualTo(msg.getMetaData());
assertThat(actualException).isInstanceOf(RuntimeException.class);
assertThat(actualException.getMessage()).isEqualTo("Device with name 'Thermostat' is not assigned to Customer.");
assertThat(actualException.getMessage()).isEqualTo("Device with name 'Thermostat' is not assigned to Customer!");
}
@Test