created enum for originator source values
This commit is contained in:
		
							parent
							
								
									ec1c2e307c
								
							
						
					
					
						commit
						46a147792e
					
				@ -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
 | 
			
		||||
}
 | 
			
		||||
@ -15,7 +15,6 @@
 | 
			
		||||
 */
 | 
			
		||||
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.ListenableFuture;
 | 
			
		||||
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.msg.TbMsg;
 | 
			
		||||
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.NoSuchElementException;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.ENTITY;
 | 
			
		||||
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.RELATED;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@RuleNode(
 | 
			
		||||
        type = ComponentType.TRANSFORMATION,
 | 
			
		||||
@ -59,16 +60,6 @@ import java.util.NoSuchElementException;
 | 
			
		||||
)
 | 
			
		||||
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
 | 
			
		||||
    protected TbChangeOriginatorNodeConfiguration loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
 | 
			
		||||
        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) {
 | 
			
		||||
        switch (config.getOriginatorSource()) {
 | 
			
		||||
            case CUSTOMER_SOURCE:
 | 
			
		||||
            case CUSTOMER:
 | 
			
		||||
                return EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator());
 | 
			
		||||
            case TENANT_SOURCE:
 | 
			
		||||
            case TENANT:
 | 
			
		||||
                return Futures.immediateFuture(ctx.getTenantId());
 | 
			
		||||
            case RELATED_SOURCE:
 | 
			
		||||
            case RELATED:
 | 
			
		||||
                return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, msg.getOriginator(), config.getRelationsQuery());
 | 
			
		||||
            case ALARM_ORIGINATOR_SOURCE:
 | 
			
		||||
            case ALARM_ORIGINATOR:
 | 
			
		||||
                return EntitiesAlarmOriginatorIdAsyncLoader.findEntityIdAsync(ctx, msg.getOriginator());
 | 
			
		||||
            case ENTITY_SOURCE:
 | 
			
		||||
            case ENTITY:
 | 
			
		||||
                EntityType entityType = EntityType.valueOf(config.getEntityType());
 | 
			
		||||
                String entityName = TbNodeUtils.processPattern(config.getEntityNamePattern(), msg);
 | 
			
		||||
                try {
 | 
			
		||||
@ -112,27 +103,19 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode<TbChangeOrig
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void validateConfig(TbChangeOriginatorNodeConfiguration conf) {
 | 
			
		||||
        HashSet<String> knownSources = Sets.newHashSet(CUSTOMER_SOURCE, TENANT_SOURCE, RELATED_SOURCE, ALARM_ORIGINATOR_SOURCE, ENTITY_SOURCE);
 | 
			
		||||
        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.getOriginatorSource().equals(RELATED)) {
 | 
			
		||||
            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.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (conf.getOriginatorSource().equals(ENTITY_SOURCE)) {
 | 
			
		||||
        if (conf.getOriginatorSource().equals(ENTITY)) {
 | 
			
		||||
            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.");
 | 
			
		||||
            }
 | 
			
		||||
            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.");
 | 
			
		||||
            }
 | 
			
		||||
            EntitiesByNameAndTypeLoader.checkEntityType(EntityType.valueOf(conf.getEntityType()));
 | 
			
		||||
 | 
			
		||||
@ -24,13 +24,12 @@ import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.rule.engine.transform.ChangeOriginatorSource.CUSTOMER;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration<TbChangeOriginatorNodeConfiguration> {
 | 
			
		||||
 | 
			
		||||
    private static final String CUSTOMER_SOURCE = "CUSTOMER";
 | 
			
		||||
 | 
			
		||||
    private String originatorSource;
 | 
			
		||||
 | 
			
		||||
    private ChangeOriginatorSource originatorSource;
 | 
			
		||||
    private RelationsQuery relationsQuery;
 | 
			
		||||
    private String entityType;
 | 
			
		||||
    private String entityNamePattern;
 | 
			
		||||
@ -38,7 +37,7 @@ public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration<Tb
 | 
			
		||||
    @Override
 | 
			
		||||
    public TbChangeOriginatorNodeConfiguration defaultConfiguration() {
 | 
			
		||||
        TbChangeOriginatorNodeConfiguration configuration = new TbChangeOriginatorNodeConfiguration();
 | 
			
		||||
        configuration.setOriginatorSource(CUSTOMER_SOURCE);
 | 
			
		||||
        configuration.setOriginatorSource(CUSTOMER);
 | 
			
		||||
 | 
			
		||||
        RelationsQuery relationsQuery = new RelationsQuery();
 | 
			
		||||
        relationsQuery.setDirection(EntitySearchDirection.FROM);
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,7 @@ public class EntitiesByNameAndTypeLoader {
 | 
			
		||||
                throw new IllegalStateException("Unexpected entity type " + entityType.name());
 | 
			
		||||
        }
 | 
			
		||||
        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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,6 @@ import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.dao.relation.RelationService;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.NoSuchElementException;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
@ -70,6 +69,11 @@ import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
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)
 | 
			
		||||
public class TbChangeOriginatorNodeTest {
 | 
			
		||||
@ -81,16 +85,6 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    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 TbChangeOriginatorNodeConfiguration config;
 | 
			
		||||
 | 
			
		||||
@ -114,7 +108,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    public void verifyDefaultConfig() {
 | 
			
		||||
        var config = new TbChangeOriginatorNodeConfiguration().defaultConfiguration();
 | 
			
		||||
        assertThat(config.getOriginatorSource()).isEqualTo(CUSTOMER_SOURCE);
 | 
			
		||||
        assertThat(config.getOriginatorSource()).isEqualTo(CUSTOMER);
 | 
			
		||||
        RelationsQuery relationsQuery = new RelationsQuery();
 | 
			
		||||
        relationsQuery.setDirection(EntitySearchDirection.FROM);
 | 
			
		||||
        relationsQuery.setMaxLevel(1);
 | 
			
		||||
@ -125,18 +119,9 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
        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
 | 
			
		||||
    public void givenRelatedSourceAndRelatedQueryIsNull_whenInit_thenThrowsException() {
 | 
			
		||||
        config.setOriginatorSource(RELATED_SOURCE);
 | 
			
		||||
        config.setOriginatorSource(RELATED);
 | 
			
		||||
        config.setRelationsQuery(null);
 | 
			
		||||
 | 
			
		||||
        assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))))
 | 
			
		||||
@ -146,7 +131,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenEntitySourceAndEntityTypeIsNull_whenInit_thenThrowsException() {
 | 
			
		||||
        config.setOriginatorSource(ENTITY_SOURCE);
 | 
			
		||||
        config.setOriginatorSource(ENTITY);
 | 
			
		||||
        config.setEntityType(null);
 | 
			
		||||
 | 
			
		||||
        assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))))
 | 
			
		||||
@ -157,7 +142,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
    @ParameterizedTest
 | 
			
		||||
    @NullAndEmptySource
 | 
			
		||||
    public void givenEntitySourceAndEntityNamePatternIsEmpty_whenInit_thenThrowsException(String entityName) {
 | 
			
		||||
        config.setOriginatorSource(ENTITY_SOURCE);
 | 
			
		||||
        config.setOriginatorSource(ENTITY);
 | 
			
		||||
        config.setEntityType(EntityType.DEVICE.name());
 | 
			
		||||
        config.setEntityNamePattern(entityName);
 | 
			
		||||
 | 
			
		||||
@ -168,7 +153,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenEntitySourceAndUnexpectedEntityType_whenInit_thenThrowsException() {
 | 
			
		||||
        config.setOriginatorSource(ENTITY_SOURCE);
 | 
			
		||||
        config.setOriginatorSource(ENTITY);
 | 
			
		||||
        config.setEntityType(EntityType.TENANT.name());
 | 
			
		||||
        config.setEntityNamePattern("tenant-A");
 | 
			
		||||
 | 
			
		||||
@ -203,7 +188,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    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 expectedMsg = TbMsg.transformMsgOriginator(msg, TENANT_ID);
 | 
			
		||||
@ -223,7 +208,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
@ -253,7 +238,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    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"));
 | 
			
		||||
        Alarm alarm = new Alarm(alarmId);
 | 
			
		||||
@ -281,7 +266,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
    @ParameterizedTest
 | 
			
		||||
    @MethodSource
 | 
			
		||||
    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.setEntityNamePattern(entityNamePattern);
 | 
			
		||||
 | 
			
		||||
@ -315,7 +300,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void givenOriginatorSourceIsEntityAndEntityCouldNotFound_whenOnMsg_thenTellFailure() throws TbNodeException {
 | 
			
		||||
        config.setOriginatorSource(ENTITY_SOURCE);
 | 
			
		||||
        config.setOriginatorSource(ENTITY);
 | 
			
		||||
        config.setEntityType(EntityType.ASSET.name());
 | 
			
		||||
        config.setEntityNamePattern("${md-name-pattern}");
 | 
			
		||||
 | 
			
		||||
@ -333,7 +318,7 @@ public class TbChangeOriginatorNodeTest {
 | 
			
		||||
 | 
			
		||||
        ArgumentCaptor<Throwable> throwable = ArgumentCaptor.forClass(Throwable.class);
 | 
			
		||||
        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'!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user