created enum for originator source values

This commit is contained in:
IrynaMatveieva 2024-08-09 16:06:00 +03:00
parent ec1c2e307c
commit 46a147792e
5 changed files with 58 additions and 67 deletions

View File

@ -0,0 +1,24 @@
/**
* 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.rule.engine.transform;
public enum ChangeOriginatorSource {
CUSTOMER,
TENANT,
RELATED,
ALARM_ORIGINATOR,
ENTITY
}

View File

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.rule.engine.transform; package org.thingsboard.rule.engine.transform;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -34,10 +33,12 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.ENTITY;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.RELATED;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
type = ComponentType.TRANSFORMATION, type = ComponentType.TRANSFORMATION,
@ -59,16 +60,6 @@ import java.util.NoSuchElementException;
) )
public class TbChangeOriginatorNode extends TbAbstractTransformNode<TbChangeOriginatorNodeConfiguration> { public class TbChangeOriginatorNode extends TbAbstractTransformNode<TbChangeOriginatorNodeConfiguration> {
private static final String CUSTOMER_SOURCE = "CUSTOMER";
private static final String TENANT_SOURCE = "TENANT";
private static final String RELATED_SOURCE = "RELATED";
private static final String ALARM_ORIGINATOR_SOURCE = "ALARM_ORIGINATOR";
private static final String ENTITY_SOURCE = "ENTITY";
private final String supportedOriginatorSourcesStr = String.join(", ", List.of(
CUSTOMER_SOURCE, TENANT_SOURCE, RELATED_SOURCE, ALARM_ORIGINATOR_SOURCE, ENTITY_SOURCE)
);
@Override @Override
protected TbChangeOriginatorNodeConfiguration loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { protected TbChangeOriginatorNodeConfiguration loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
var config = TbNodeUtils.convert(configuration, TbChangeOriginatorNodeConfiguration.class); var config = TbNodeUtils.convert(configuration, TbChangeOriginatorNodeConfiguration.class);
@ -89,15 +80,15 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode<TbChangeOrig
private ListenableFuture<? extends EntityId> getNewOriginator(TbContext ctx, TbMsg msg) { private ListenableFuture<? extends EntityId> getNewOriginator(TbContext ctx, TbMsg msg) {
switch (config.getOriginatorSource()) { switch (config.getOriginatorSource()) {
case CUSTOMER_SOURCE: case CUSTOMER:
return EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator()); return EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator());
case TENANT_SOURCE: case TENANT:
return Futures.immediateFuture(ctx.getTenantId()); return Futures.immediateFuture(ctx.getTenantId());
case RELATED_SOURCE: case RELATED:
return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, msg.getOriginator(), config.getRelationsQuery()); return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, msg.getOriginator(), config.getRelationsQuery());
case ALARM_ORIGINATOR_SOURCE: case ALARM_ORIGINATOR:
return EntitiesAlarmOriginatorIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator()); return EntitiesAlarmOriginatorIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator());
case ENTITY_SOURCE: case ENTITY:
EntityType entityType = EntityType.valueOf(config.getEntityType()); EntityType entityType = EntityType.valueOf(config.getEntityType());
String entityName = TbNodeUtils.processPattern(config.getEntityNamePattern(), msg); String entityName = TbNodeUtils.processPattern(config.getEntityNamePattern(), msg);
try { try {
@ -112,27 +103,19 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode<TbChangeOrig
} }
private void validateConfig(TbChangeOriginatorNodeConfiguration conf) { private void validateConfig(TbChangeOriginatorNodeConfiguration conf) {
HashSet<String> knownSources = Sets.newHashSet(CUSTOMER_SOURCE, TENANT_SOURCE, RELATED_SOURCE, ALARM_ORIGINATOR_SOURCE, ENTITY_SOURCE); if (conf.getOriginatorSource().equals(RELATED)) {
if (!knownSources.contains(conf.getOriginatorSource())) {
log.error("Unsupported source type '{}'! Only {} types are allowed.", conf.getOriginatorSource(), supportedOriginatorSourcesStr);
throw new IllegalArgumentException("Unsupported source type '" + conf.getOriginatorSource() +
"'! Only " + supportedOriginatorSourcesStr + " types are allowed.");
}
if (conf.getOriginatorSource().equals(RELATED_SOURCE)) {
if (conf.getRelationsQuery() == null) { if (conf.getRelationsQuery() == null) {
log.error("Relations query should be specified if 'Related entity' source is selected."); log.debug("Relations query should be specified if 'Related entity' source is selected.");
throw new IllegalArgumentException("Relations query should be specified if 'Related entity' source is selected."); throw new IllegalArgumentException("Relations query should be specified if 'Related entity' source is selected.");
} }
} }
if (conf.getOriginatorSource().equals(ENTITY)) {
if (conf.getOriginatorSource().equals(ENTITY_SOURCE)) {
if (conf.getEntityType() == null) { if (conf.getEntityType() == null) {
log.error("Entity type should be specified if '{}' source is selected.", ENTITY_SOURCE); log.debug("Entity type should be specified if '{}' source is selected.", ENTITY);
throw new IllegalArgumentException("Entity type should be specified if 'Entity by name pattern' source is selected."); throw new IllegalArgumentException("Entity type should be specified if 'Entity by name pattern' source is selected.");
} }
if (StringUtils.isEmpty(conf.getEntityNamePattern())) { if (StringUtils.isEmpty(conf.getEntityNamePattern())) {
log.error("Name pattern should be specified if '{}' source is selected.", ENTITY_SOURCE); log.debug("Name pattern should be specified if '{}' source is selected.", ENTITY);
throw new IllegalArgumentException("Name pattern should be specified if 'Entity by name pattern' source is selected."); throw new IllegalArgumentException("Name pattern should be specified if 'Entity by name pattern' source is selected.");
} }
EntitiesByNameAndTypeLoader.checkEntityType(EntityType.valueOf(conf.getEntityType())); EntitiesByNameAndTypeLoader.checkEntityType(EntityType.valueOf(conf.getEntityType()));

View File

@ -24,13 +24,12 @@ import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
import java.util.Collections; import java.util.Collections;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.CUSTOMER;
@Data @Data
public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration<TbChangeOriginatorNodeConfiguration> { public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration<TbChangeOriginatorNodeConfiguration> {
private static final String CUSTOMER_SOURCE = "CUSTOMER"; private ChangeOriginatorSource originatorSource;
private String originatorSource;
private RelationsQuery relationsQuery; private RelationsQuery relationsQuery;
private String entityType; private String entityType;
private String entityNamePattern; private String entityNamePattern;
@ -38,7 +37,7 @@ public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration<Tb
@Override @Override
public TbChangeOriginatorNodeConfiguration defaultConfiguration() { public TbChangeOriginatorNodeConfiguration defaultConfiguration() {
TbChangeOriginatorNodeConfiguration configuration = new TbChangeOriginatorNodeConfiguration(); TbChangeOriginatorNodeConfiguration configuration = new TbChangeOriginatorNodeConfiguration();
configuration.setOriginatorSource(CUSTOMER_SOURCE); configuration.setOriginatorSource(CUSTOMER);
RelationsQuery relationsQuery = new RelationsQuery(); RelationsQuery relationsQuery = new RelationsQuery();
relationsQuery.setDirection(EntitySearchDirection.FROM); relationsQuery.setDirection(EntitySearchDirection.FROM);

View File

@ -53,7 +53,7 @@ public class EntitiesByNameAndTypeLoader {
throw new IllegalStateException("Unexpected entity type " + entityType.name()); throw new IllegalStateException("Unexpected entity type " + entityType.name());
} }
if (targetEntity == null) { if (targetEntity == null) {
throw new IllegalStateException("Failed to found " + entityType.getNormalName().toLowerCase() + " with name '" + entityName + "'!"); throw new IllegalStateException("Failed to find " + entityType.getNormalName().toLowerCase() + " with name '" + entityName + "'!");
} }
return targetEntity.getId(); return targetEntity.getId();
} }

View File

@ -58,7 +58,6 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.relation.RelationService;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.UUID; import java.util.UUID;
@ -70,6 +69,11 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.then;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.ALARM_ORIGINATOR;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.CUSTOMER;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.ENTITY;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.RELATED;
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.TENANT;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class TbChangeOriginatorNodeTest { public class TbChangeOriginatorNodeTest {
@ -81,16 +85,6 @@ public class TbChangeOriginatorNodeTest {
private final ListeningExecutor dbExecutor = new TestDbCallbackExecutor(); private final ListeningExecutor dbExecutor = new TestDbCallbackExecutor();
private final String CUSTOMER_SOURCE = "CUSTOMER";
private final String TENANT_SOURCE = "TENANT";
private final String RELATED_SOURCE = "RELATED";
private final String ALARM_ORIGINATOR_SOURCE = "ALARM_ORIGINATOR";
private final String ENTITY_SOURCE = "ENTITY";
private final String supportedOriginatorSourcesStr = String.join(", ", List.of(
CUSTOMER_SOURCE, TENANT_SOURCE, RELATED_SOURCE, ALARM_ORIGINATOR_SOURCE, ENTITY_SOURCE)
);
private TbChangeOriginatorNode node; private TbChangeOriginatorNode node;
private TbChangeOriginatorNodeConfiguration config; private TbChangeOriginatorNodeConfiguration config;
@ -114,7 +108,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void verifyDefaultConfig() { public void verifyDefaultConfig() {
var config = new TbChangeOriginatorNodeConfiguration().defaultConfiguration(); var config = new TbChangeOriginatorNodeConfiguration().defaultConfiguration();
assertThat(config.getOriginatorSource()).isEqualTo(CUSTOMER_SOURCE); assertThat(config.getOriginatorSource()).isEqualTo(CUSTOMER);
RelationsQuery relationsQuery = new RelationsQuery(); RelationsQuery relationsQuery = new RelationsQuery();
relationsQuery.setDirection(EntitySearchDirection.FROM); relationsQuery.setDirection(EntitySearchDirection.FROM);
relationsQuery.setMaxLevel(1); relationsQuery.setMaxLevel(1);
@ -125,18 +119,9 @@ public class TbChangeOriginatorNodeTest {
assertThat(config.getEntityNamePattern()).isNull(); assertThat(config.getEntityNamePattern()).isNull();
} }
@Test
public void givenUnsupportedSource_whenInit_thenThrowsException() {
config.setOriginatorSource("UNSUPPORTED_SOURCE");
assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported source type 'UNSUPPORTED_SOURCE'! Only " + supportedOriginatorSourcesStr + " types are allowed.");
}
@Test @Test
public void givenRelatedSourceAndRelatedQueryIsNull_whenInit_thenThrowsException() { public void givenRelatedSourceAndRelatedQueryIsNull_whenInit_thenThrowsException() {
config.setOriginatorSource(RELATED_SOURCE); config.setOriginatorSource(RELATED);
config.setRelationsQuery(null); config.setRelationsQuery(null);
assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config)))) assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))))
@ -146,7 +131,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenEntitySourceAndEntityTypeIsNull_whenInit_thenThrowsException() { public void givenEntitySourceAndEntityTypeIsNull_whenInit_thenThrowsException() {
config.setOriginatorSource(ENTITY_SOURCE); config.setOriginatorSource(ENTITY);
config.setEntityType(null); config.setEntityType(null);
assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config)))) assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))))
@ -157,7 +142,7 @@ public class TbChangeOriginatorNodeTest {
@ParameterizedTest @ParameterizedTest
@NullAndEmptySource @NullAndEmptySource
public void givenEntitySourceAndEntityNamePatternIsEmpty_whenInit_thenThrowsException(String entityName) { public void givenEntitySourceAndEntityNamePatternIsEmpty_whenInit_thenThrowsException(String entityName) {
config.setOriginatorSource(ENTITY_SOURCE); config.setOriginatorSource(ENTITY);
config.setEntityType(EntityType.DEVICE.name()); config.setEntityType(EntityType.DEVICE.name());
config.setEntityNamePattern(entityName); config.setEntityNamePattern(entityName);
@ -168,7 +153,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenEntitySourceAndUnexpectedEntityType_whenInit_thenThrowsException() { public void givenEntitySourceAndUnexpectedEntityType_whenInit_thenThrowsException() {
config.setOriginatorSource(ENTITY_SOURCE); config.setOriginatorSource(ENTITY);
config.setEntityType(EntityType.TENANT.name()); config.setEntityType(EntityType.TENANT.name());
config.setEntityNamePattern("tenant-A"); config.setEntityNamePattern("tenant-A");
@ -203,7 +188,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenOriginatorSourceIsTenant_whenOnMsg_thenTellSuccess() throws TbNodeException { public void givenOriginatorSourceIsTenant_whenOnMsg_thenTellSuccess() throws TbNodeException {
config.setOriginatorSource(TENANT_SOURCE); config.setOriginatorSource(TENANT);
TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ASSET_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ASSET_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT);
TbMsg expectedMsg = TbMsg.transformMsgOriginator(msg, TENANT_ID); TbMsg expectedMsg = TbMsg.transformMsgOriginator(msg, TENANT_ID);
@ -223,7 +208,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenOriginatorSourceIsRelatedAndNewOriginatorIsNull_whenOnMsg_thenTellFailure() throws TbNodeException { public void givenOriginatorSourceIsRelatedAndNewOriginatorIsNull_whenOnMsg_thenTellFailure() throws TbNodeException {
config.setOriginatorSource(RELATED_SOURCE); config.setOriginatorSource(RELATED);
TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ASSET_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ASSET_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT);
@ -253,7 +238,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenOriginatorSourceIsAlarmOriginator_whenOnMsg_thenTellSuccess() throws TbNodeException { public void givenOriginatorSourceIsAlarmOriginator_whenOnMsg_thenTellSuccess() throws TbNodeException {
config.setOriginatorSource(ALARM_ORIGINATOR_SOURCE); config.setOriginatorSource(ALARM_ORIGINATOR);
AlarmId alarmId = new AlarmId(UUID.fromString("6b43f694-cb5f-4199-9023-e9e40eeb82dd")); AlarmId alarmId = new AlarmId(UUID.fromString("6b43f694-cb5f-4199-9023-e9e40eeb82dd"));
Alarm alarm = new Alarm(alarmId); Alarm alarm = new Alarm(alarmId);
@ -281,7 +266,7 @@ public class TbChangeOriginatorNodeTest {
@ParameterizedTest @ParameterizedTest
@MethodSource @MethodSource
public void givenOriginatorSourceIsEntity_whenOnMsg_thenTellSuccess(String entityNamePattern, TbMsgMetaData metaData, String data) throws TbNodeException { public void givenOriginatorSourceIsEntity_whenOnMsg_thenTellSuccess(String entityNamePattern, TbMsgMetaData metaData, String data) throws TbNodeException {
config.setOriginatorSource(ENTITY_SOURCE); config.setOriginatorSource(ENTITY);
config.setEntityType(EntityType.ASSET.name()); config.setEntityType(EntityType.ASSET.name());
config.setEntityNamePattern(entityNamePattern); config.setEntityNamePattern(entityNamePattern);
@ -315,7 +300,7 @@ public class TbChangeOriginatorNodeTest {
@Test @Test
public void givenOriginatorSourceIsEntityAndEntityCouldNotFound_whenOnMsg_thenTellFailure() throws TbNodeException { public void givenOriginatorSourceIsEntityAndEntityCouldNotFound_whenOnMsg_thenTellFailure() throws TbNodeException {
config.setOriginatorSource(ENTITY_SOURCE); config.setOriginatorSource(ENTITY);
config.setEntityType(EntityType.ASSET.name()); config.setEntityType(EntityType.ASSET.name());
config.setEntityNamePattern("${md-name-pattern}"); config.setEntityNamePattern("${md-name-pattern}");
@ -333,7 +318,7 @@ public class TbChangeOriginatorNodeTest {
ArgumentCaptor<Throwable> throwable = ArgumentCaptor.forClass(Throwable.class); ArgumentCaptor<Throwable> throwable = ArgumentCaptor.forClass(Throwable.class);
then(ctxMock).should().tellFailure(eq(msg), throwable.capture()); then(ctxMock).should().tellFailure(eq(msg), throwable.capture());
assertThat(throwable.getValue()).isInstanceOf(IllegalStateException.class).hasMessage("Failed to found asset with name 'test-asset'!"); assertThat(throwable.getValue()).isInstanceOf(IllegalStateException.class).hasMessage("Failed to find asset with name 'test-asset'!");
} }
} }