4 changed files with 0 additions and 832 deletions
@ -1,236 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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.metadata; |
|
||||
|
|
||||
import com.datastax.oss.driver.api.core.uuid.Uuids; |
|
||||
import com.google.common.collect.Lists; |
|
||||
import com.google.common.util.concurrent.Futures; |
|
||||
import org.junit.runner.RunWith; |
|
||||
import org.mockito.ArgumentCaptor; |
|
||||
import org.mockito.Mock; |
|
||||
import org.mockito.junit.MockitoJUnitRunner; |
|
||||
import org.thingsboard.common.util.JacksonUtil; |
|
||||
import org.thingsboard.rule.engine.api.TbContext; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeException; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.User; |
|
||||
import org.thingsboard.server.common.data.asset.Asset; |
|
||||
import org.thingsboard.server.common.data.id.CustomerId; |
|
||||
import org.thingsboard.server.common.data.id.EntityId; |
|
||||
import org.thingsboard.server.common.data.id.RuleChainId; |
|
||||
import org.thingsboard.server.common.data.id.RuleNodeId; |
|
||||
import org.thingsboard.server.common.data.id.TenantId; |
|
||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
||||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|
||||
import org.thingsboard.server.common.msg.TbMsg; |
|
||||
import org.thingsboard.server.common.msg.TbMsgDataType; |
|
||||
import org.thingsboard.server.common.msg.TbMsgMetaData; |
|
||||
import org.thingsboard.server.dao.asset.AssetService; |
|
||||
import org.thingsboard.server.dao.attributes.AttributesService; |
|
||||
import org.thingsboard.server.dao.device.DeviceService; |
|
||||
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|
||||
import org.thingsboard.server.dao.user.UserService; |
|
||||
|
|
||||
import java.util.HashMap; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
import java.util.NoSuchElementException; |
|
||||
|
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||
import static org.junit.Assert.assertEquals; |
|
||||
import static org.junit.Assert.assertTrue; |
|
||||
import static org.mockito.ArgumentMatchers.any; |
|
||||
import static org.mockito.ArgumentMatchers.anyCollection; |
|
||||
import static org.mockito.ArgumentMatchers.eq; |
|
||||
import static org.mockito.ArgumentMatchers.same; |
|
||||
import static org.mockito.Mockito.verify; |
|
||||
import static org.mockito.Mockito.when; |
|
||||
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; |
|
||||
|
|
||||
@RunWith(MockitoJUnitRunner.class) |
|
||||
public abstract class OldTbAbstractAttributeNodeTest { |
|
||||
final CustomerId customerId = new CustomerId(Uuids.timeBased()); |
|
||||
final TenantId tenantId = TenantId.fromUUID(Uuids.timeBased()); |
|
||||
final RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased()); |
|
||||
final RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased()); |
|
||||
final String keyAttrConf = "${word}"; |
|
||||
final String valueAttrConf = "${result}"; |
|
||||
@Mock |
|
||||
protected TbContext ctxMock; |
|
||||
@Mock |
|
||||
protected AttributesService attributesServiceMock; |
|
||||
@Mock |
|
||||
protected TimeseriesService timeseriesServiceMock; |
|
||||
@Mock |
|
||||
protected UserService userServiceMock; |
|
||||
@Mock |
|
||||
protected AssetService assetServiceMock; |
|
||||
@Mock |
|
||||
protected DeviceService deviceServiceMock; |
|
||||
TbMsg msg; |
|
||||
Map<String, String> metaData; |
|
||||
TbAbstractGetEntityAttrNode<? extends EntityId> node; |
|
||||
|
|
||||
protected void init(TbAbstractGetEntityAttrNode node) throws TbNodeException { |
|
||||
var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(getTbNodeConfig())); |
|
||||
|
|
||||
metaData = new HashMap<>(); |
|
||||
metaData.putIfAbsent("word", "temperature"); |
|
||||
metaData.putIfAbsent("result", "answer"); |
|
||||
|
|
||||
this.node = node; |
|
||||
this.node.init(null, nodeConfiguration); |
|
||||
} |
|
||||
|
|
||||
void errorThrownIfCannotLoadAttributes(User user) { |
|
||||
msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(getEntityId()), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenThrow(new IllegalStateException("something wrong")); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
final ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class); |
|
||||
verify(ctxMock).tellFailure(same(msg), captor.capture()); |
|
||||
|
|
||||
Throwable value = captor.getValue(); |
|
||||
assertEquals("something wrong", value.getMessage()); |
|
||||
assertTrue(msg.getMetaData().getData().isEmpty()); |
|
||||
} |
|
||||
|
|
||||
void errorThrownIfCannotLoadAttributesAsync(User user) { |
|
||||
msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(getEntityId()), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFailedFuture(new IllegalStateException("something wrong"))); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
final ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class); |
|
||||
verify(ctxMock).tellFailure(same(msg), captor.capture()); |
|
||||
|
|
||||
Throwable value = captor.getValue(); |
|
||||
assertEquals("something wrong", value.getMessage()); |
|
||||
assertTrue(msg.getMetaData().getData().isEmpty()); |
|
||||
} |
|
||||
|
|
||||
void failedChainUsedIfCustomerCannotBeFound(User user) { |
|
||||
msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
var exceptionCaptor = ArgumentCaptor.forClass(NoSuchElementException.class); |
|
||||
verify(ctxMock).tellFailure(eq(msg), exceptionCaptor.capture()); |
|
||||
|
|
||||
assertThat(exceptionCaptor.getValue().getMessage()).contains("Did not find entity! Msg ID: "); |
|
||||
assertTrue(msg.getMetaData().getData().isEmpty()); |
|
||||
} |
|
||||
|
|
||||
void entityAttributeAddedInMetadata(EntityId entityId, String type) { |
|
||||
msg = TbMsg.newMsg(type, entityId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
entityAttributesFetched(getEntityId()); |
|
||||
} |
|
||||
|
|
||||
void usersCustomerAttributesFetched(User user) { |
|
||||
msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
entityAttributesFetched(getEntityId()); |
|
||||
} |
|
||||
|
|
||||
void assetsCustomerAttributesFetched(Asset asset) { |
|
||||
msg = TbMsg.newMsg("ASSET", asset.getId(), new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
entityAttributesFetched(getEntityId()); |
|
||||
} |
|
||||
|
|
||||
void deviceCustomerAttributesFetched(Device device) { |
|
||||
msg = TbMsg.newMsg("DEVICE", device.getId(), new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
entityAttributesFetched(getEntityId()); |
|
||||
} |
|
||||
|
|
||||
void deviceCustomerTelemetryFetched(Device device) throws TbNodeException { |
|
||||
var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(getTbNodeConfigForTelemetry())); |
|
||||
|
|
||||
TbAbstractGetEntityAttrNode node = getEmptyNode(); |
|
||||
node.init(null, nodeConfiguration); |
|
||||
|
|
||||
msg = TbMsg.newMsg("DEVICE", device.getId(), new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
List<TsKvEntry> timeseries = Lists.newArrayList(new BasicTsKvEntry(1L, new StringDataEntry("temperature", "highest"))); |
|
||||
|
|
||||
when(ctxMock.getTimeseriesService()).thenReturn(timeseriesServiceMock); |
|
||||
when(timeseriesServiceMock.findLatest(any(), eq(getEntityId()), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFuture(timeseries)); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
verify(ctxMock).tellSuccess(msg); |
|
||||
assertEquals(msg.getMetaData().getValue("answer"), "highest"); |
|
||||
} |
|
||||
|
|
||||
protected void entityAttributesFetched(EntityId entityId) { |
|
||||
List<AttributeKvEntry> attributes = List.of(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(entityId), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFuture(attributes)); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
|
|
||||
verify(ctxMock).tellSuccess(msg); |
|
||||
assertEquals(msg.getMetaData().getValue("answer"), "high"); |
|
||||
} |
|
||||
|
|
||||
protected TbGetEntityAttrNodeConfiguration getTbNodeConfig() { |
|
||||
return getConfig(false); |
|
||||
} |
|
||||
|
|
||||
protected TbGetEntityAttrNodeConfiguration getTbNodeConfigForTelemetry() { |
|
||||
return getConfig(true); |
|
||||
} |
|
||||
|
|
||||
private TbGetEntityAttrNodeConfiguration getConfig(boolean isTelemetry) { |
|
||||
TbGetEntityAttrNodeConfiguration config = new TbGetEntityAttrNodeConfiguration(); |
|
||||
Map<String, String> conf = new HashMap<>(); |
|
||||
conf.put(keyAttrConf, valueAttrConf); |
|
||||
config.setAttrMapping(conf); |
|
||||
config.setTelemetry(isTelemetry); |
|
||||
config.setFetchTo(FetchTo.METADATA); |
|
||||
return config; |
|
||||
} |
|
||||
|
|
||||
protected abstract TbAbstractGetEntityAttrNode getEmptyNode(); |
|
||||
|
|
||||
abstract EntityId getEntityId(); |
|
||||
|
|
||||
void mockFindDevice(Device device) { |
|
||||
when(ctxMock.getDeviceService()).thenReturn(deviceServiceMock); |
|
||||
when(deviceServiceMock.findDeviceByIdAsync(any(), eq(device.getId()))).thenReturn(Futures.immediateFuture(device)); |
|
||||
} |
|
||||
|
|
||||
void mockFindAsset(Asset asset) { |
|
||||
when(ctxMock.getAssetService()).thenReturn(assetServiceMock); |
|
||||
when(assetServiceMock.findAssetByIdAsync(any(), eq(asset.getId()))).thenReturn(Futures.immediateFuture(asset)); |
|
||||
} |
|
||||
|
|
||||
void mockFindUser(User user) { |
|
||||
when(ctxMock.getUserService()).thenReturn(userServiceMock); |
|
||||
when(userServiceMock.findUserByIdAsync(any(), eq(user.getId()))).thenReturn(Futures.immediateFuture(user)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,184 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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.metadata; |
|
||||
|
|
||||
import com.datastax.oss.driver.api.core.uuid.Uuids; |
|
||||
import com.google.common.collect.Lists; |
|
||||
import com.google.common.util.concurrent.Futures; |
|
||||
import org.junit.Before; |
|
||||
import org.junit.Test; |
|
||||
import org.junit.runner.RunWith; |
|
||||
import org.mockito.ArgumentCaptor; |
|
||||
import org.mockito.junit.MockitoJUnitRunner; |
|
||||
import org.thingsboard.common.util.JacksonUtil; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeException; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.User; |
|
||||
import org.thingsboard.server.common.data.asset.Asset; |
|
||||
import org.thingsboard.server.common.data.id.AssetId; |
|
||||
import org.thingsboard.server.common.data.id.CustomerId; |
|
||||
import org.thingsboard.server.common.data.id.DeviceId; |
|
||||
import org.thingsboard.server.common.data.id.EntityId; |
|
||||
import org.thingsboard.server.common.data.id.UserId; |
|
||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
||||
import org.thingsboard.server.common.msg.TbMsg; |
|
||||
import org.thingsboard.server.common.msg.TbMsgDataType; |
|
||||
import org.thingsboard.server.common.msg.TbMsgMetaData; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows; |
|
||||
import static org.mockito.ArgumentMatchers.any; |
|
||||
import static org.mockito.ArgumentMatchers.anyCollection; |
|
||||
import static org.mockito.ArgumentMatchers.eq; |
|
||||
import static org.mockito.Mockito.never; |
|
||||
import static org.mockito.Mockito.times; |
|
||||
import static org.mockito.Mockito.verify; |
|
||||
import static org.mockito.Mockito.when; |
|
||||
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; |
|
||||
|
|
||||
@RunWith(MockitoJUnitRunner.class) |
|
||||
public class OldTbGetCustomerAttributeNodeTest extends OldTbAbstractAttributeNodeTest { |
|
||||
|
|
||||
User user = new User(); |
|
||||
Asset asset = new Asset(); |
|
||||
Device device = new Device(); |
|
||||
|
|
||||
@Before |
|
||||
public void initDataForTests() throws TbNodeException { |
|
||||
init(new TbGetCustomerAttributeNode()); |
|
||||
user.setCustomerId(customerId); |
|
||||
user.setId(new UserId(UUID.randomUUID())); |
|
||||
|
|
||||
asset.setCustomerId(customerId); |
|
||||
asset.setId(new AssetId(UUID.randomUUID())); |
|
||||
|
|
||||
device.setCustomerId(customerId); |
|
||||
device.setId(new DeviceId(Uuids.timeBased())); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected TbAbstractGetEntityAttrNode<CustomerId> getEmptyNode() { |
|
||||
return new TbGetCustomerAttributeNode(); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected EntityId getEntityId() { |
|
||||
return customerId; |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfFetchToIsNull() { |
|
||||
var node = new TbGetCustomerAttributeNode(); |
|
||||
var config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); |
|
||||
config.setFetchTo(null); |
|
||||
var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); |
|
||||
|
|
||||
var exception = assertThrows(TbNodeException.class, () -> node.init(ctxMock, nodeConfiguration)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new CustomerId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); |
|
||||
|
|
||||
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributes() { |
|
||||
mockFindUser(user); |
|
||||
errorThrownIfCannotLoadAttributes(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributesAsync() { |
|
||||
mockFindUser(user); |
|
||||
errorThrownIfCannotLoadAttributesAsync(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void failedChainUsedIfCustomerCannotBeFound() { |
|
||||
when(ctxMock.getUserService()).thenReturn(userServiceMock); |
|
||||
when(userServiceMock.findUserByIdAsync(any(), eq(user.getId()))).thenReturn(Futures.immediateFuture(null)); |
|
||||
failedChainUsedIfCustomerCannotBeFound(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInMetadata() { |
|
||||
entityAttributeAddedInMetadata(customerId, "CUSTOMER"); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
|
|
||||
msg = TbMsg.newMsg("CUSTOMER", customerId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
List<AttributeKvEntry> attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(customerId), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFuture(attributes)); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
|
|
||||
var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); |
|
||||
verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); |
|
||||
|
|
||||
var expectedMsgData = "{\"answer\":\"high\"}"; |
|
||||
|
|
||||
assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void usersCustomerAttributesFetched() { |
|
||||
mockFindUser(user); |
|
||||
usersCustomerAttributesFetched(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void assetsCustomerAttributesFetched() { |
|
||||
mockFindAsset(asset); |
|
||||
assetsCustomerAttributesFetched(asset); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerAttributesFetched() { |
|
||||
mockFindDevice(device); |
|
||||
deviceCustomerAttributesFetched(device); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerTelemetryFetched() throws TbNodeException { |
|
||||
mockFindDevice(device); |
|
||||
deviceCustomerTelemetryFetched(device); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,235 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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.metadata; |
|
||||
|
|
||||
import com.google.common.collect.Lists; |
|
||||
import com.google.common.util.concurrent.Futures; |
|
||||
import org.junit.Before; |
|
||||
import org.junit.Test; |
|
||||
import org.junit.runner.RunWith; |
|
||||
import org.mockito.ArgumentCaptor; |
|
||||
import org.mockito.Mock; |
|
||||
import org.mockito.junit.MockitoJUnitRunner; |
|
||||
import org.thingsboard.common.util.JacksonUtil; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeException; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.User; |
|
||||
import org.thingsboard.server.common.data.asset.Asset; |
|
||||
import org.thingsboard.server.common.data.id.AssetId; |
|
||||
import org.thingsboard.server.common.data.id.DeviceId; |
|
||||
import org.thingsboard.server.common.data.id.EntityId; |
|
||||
import org.thingsboard.server.common.data.id.UserId; |
|
||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation; |
|
||||
import org.thingsboard.server.common.msg.TbMsg; |
|
||||
import org.thingsboard.server.common.msg.TbMsgDataType; |
|
||||
import org.thingsboard.server.common.msg.TbMsgMetaData; |
|
||||
import org.thingsboard.server.dao.relation.RelationService; |
|
||||
|
|
||||
import java.util.HashMap; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows; |
|
||||
import static org.mockito.ArgumentMatchers.any; |
|
||||
import static org.mockito.ArgumentMatchers.anyCollection; |
|
||||
import static org.mockito.ArgumentMatchers.eq; |
|
||||
import static org.mockito.Mockito.never; |
|
||||
import static org.mockito.Mockito.times; |
|
||||
import static org.mockito.Mockito.verify; |
|
||||
import static org.mockito.Mockito.when; |
|
||||
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; |
|
||||
|
|
||||
@RunWith(MockitoJUnitRunner.class) |
|
||||
public class OldTbGetRelatedAttributeNodeTest extends OldTbAbstractAttributeNodeTest { |
|
||||
User user = new User(); |
|
||||
Asset asset = new Asset(); |
|
||||
Device device = new Device(); |
|
||||
@Mock |
|
||||
private RelationService relationService; |
|
||||
private EntityRelation entityRelation; |
|
||||
|
|
||||
@Before |
|
||||
public void initDataForTests() throws TbNodeException { |
|
||||
init(new TbGetRelatedAttributeNode()); |
|
||||
entityRelation = new EntityRelation(); |
|
||||
entityRelation.setTo(customerId); |
|
||||
entityRelation.setType(EntityRelation.CONTAINS_TYPE); |
|
||||
when(ctxMock.getRelationService()).thenReturn(relationService); |
|
||||
|
|
||||
user.setCustomerId(customerId); |
|
||||
user.setId(new UserId(UUID.randomUUID())); |
|
||||
entityRelation.setFrom(user.getId()); |
|
||||
|
|
||||
asset.setCustomerId(customerId); |
|
||||
asset.setId(new AssetId(UUID.randomUUID())); |
|
||||
|
|
||||
device.setCustomerId(customerId); |
|
||||
device.setId(new DeviceId(UUID.randomUUID())); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected TbAbstractGetEntityAttrNode getEmptyNode() { |
|
||||
return new TbGetRelatedAttributeNode(); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected TbGetEntityAttrNodeConfiguration getTbNodeConfig() { |
|
||||
return getConfig(false); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected TbGetEntityAttrNodeConfiguration getTbNodeConfigForTelemetry() { |
|
||||
return getConfig(true); |
|
||||
} |
|
||||
|
|
||||
private TbGetEntityAttrNodeConfiguration getConfig(boolean isTelemetry) { |
|
||||
TbGetRelatedAttrNodeConfiguration config = new TbGetRelatedAttrNodeConfiguration(); |
|
||||
config = config.defaultConfiguration(); |
|
||||
Map<String, String> conf = new HashMap<>(); |
|
||||
conf.put(keyAttrConf, valueAttrConf); |
|
||||
config.setAttrMapping(conf); |
|
||||
config.setTelemetry(isTelemetry); |
|
||||
config.setFetchTo(FetchTo.METADATA); |
|
||||
return config; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
EntityId getEntityId() { |
|
||||
return customerId; |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfFetchToIsNull() { |
|
||||
var node = new TbGetRelatedAttributeNode(); |
|
||||
var config = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); |
|
||||
config.setFetchTo(null); |
|
||||
var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); |
|
||||
|
|
||||
var exception = assertThrows(TbNodeException.class, () -> node.init(ctxMock, nodeConfiguration)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new DeviceId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); |
|
||||
|
|
||||
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributes() { |
|
||||
entityRelation.setFrom(user.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
errorThrownIfCannotLoadAttributes(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributesAsync() { |
|
||||
entityRelation.setFrom(user.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
errorThrownIfCannotLoadAttributesAsync(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void failedChainUsedIfCustomerCannotBeFound() { |
|
||||
entityRelation.setFrom(customerId); |
|
||||
entityRelation.setTo(null); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
failedChainUsedIfCustomerCannotBeFound(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInMetadata() { |
|
||||
entityRelation.setFrom(customerId); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
entityAttributeAddedInMetadata(customerId, "CUSTOMER"); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
|
|
||||
entityRelation.setFrom(customerId); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
|
|
||||
msg = TbMsg.newMsg("CUSTOMER", customerId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
List<AttributeKvEntry> attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(customerId), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFuture(attributes)); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
|
|
||||
var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); |
|
||||
verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); |
|
||||
|
|
||||
var expectedMsgData = "{\"answer\":\"high\"}"; |
|
||||
|
|
||||
assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void usersCustomerAttributesFetched() { |
|
||||
entityRelation.setFrom(user.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
usersCustomerAttributesFetched(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void assetsCustomerAttributesFetched() { |
|
||||
entityRelation.setFrom(asset.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
assetsCustomerAttributesFetched(asset); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerAttributesFetched() { |
|
||||
entityRelation.setFrom(device.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
deviceCustomerAttributesFetched(device); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerTelemetryFetched() throws TbNodeException { |
|
||||
entityRelation.setFrom(device.getId()); |
|
||||
entityRelation.setTo(customerId); |
|
||||
when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); |
|
||||
deviceCustomerTelemetryFetched(device); |
|
||||
} |
|
||||
} |
|
||||
@ -1,177 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2023 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.metadata; |
|
||||
|
|
||||
import com.google.common.collect.Lists; |
|
||||
import com.google.common.util.concurrent.Futures; |
|
||||
import org.junit.Before; |
|
||||
import org.junit.Test; |
|
||||
import org.junit.runner.RunWith; |
|
||||
import org.mockito.ArgumentCaptor; |
|
||||
import org.mockito.junit.MockitoJUnitRunner; |
|
||||
import org.thingsboard.common.util.JacksonUtil; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
|
||||
import org.thingsboard.rule.engine.api.TbNodeException; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.User; |
|
||||
import org.thingsboard.server.common.data.asset.Asset; |
|
||||
import org.thingsboard.server.common.data.id.AssetId; |
|
||||
import org.thingsboard.server.common.data.id.DeviceId; |
|
||||
import org.thingsboard.server.common.data.id.EntityId; |
|
||||
import org.thingsboard.server.common.data.id.TenantId; |
|
||||
import org.thingsboard.server.common.data.id.UserId; |
|
||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|
||||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
||||
import org.thingsboard.server.common.msg.TbMsg; |
|
||||
import org.thingsboard.server.common.msg.TbMsgDataType; |
|
||||
import org.thingsboard.server.common.msg.TbMsgMetaData; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows; |
|
||||
import static org.mockito.ArgumentMatchers.any; |
|
||||
import static org.mockito.ArgumentMatchers.anyCollection; |
|
||||
import static org.mockito.ArgumentMatchers.eq; |
|
||||
import static org.mockito.Mockito.never; |
|
||||
import static org.mockito.Mockito.times; |
|
||||
import static org.mockito.Mockito.verify; |
|
||||
import static org.mockito.Mockito.when; |
|
||||
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; |
|
||||
|
|
||||
@RunWith(MockitoJUnitRunner.class) |
|
||||
public class OldTbGetTenantAttributeNodeTest extends OldTbAbstractAttributeNodeTest { |
|
||||
User user = new User(); |
|
||||
Asset asset = new Asset(); |
|
||||
Device device = new Device(); |
|
||||
|
|
||||
@Before |
|
||||
public void initDataForTests() throws TbNodeException { |
|
||||
init(new TbGetTenantAttributeNode()); |
|
||||
|
|
||||
user.setTenantId(tenantId); |
|
||||
user.setId(new UserId(UUID.randomUUID())); |
|
||||
|
|
||||
asset.setTenantId(tenantId); |
|
||||
asset.setId(new AssetId(UUID.randomUUID())); |
|
||||
|
|
||||
device.setTenantId(tenantId); |
|
||||
device.setId(new DeviceId(UUID.randomUUID())); |
|
||||
|
|
||||
when(ctxMock.getTenantId()).thenReturn(tenantId); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected TbAbstractGetEntityAttrNode getEmptyNode() { |
|
||||
return new TbGetTenantAttributeNode(); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
EntityId getEntityId() { |
|
||||
return tenantId; |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfFetchToIsNull() { |
|
||||
var node = new TbGetTenantAttributeNode(); |
|
||||
var config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); |
|
||||
config.setFetchTo(null); |
|
||||
var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); |
|
||||
|
|
||||
var exception = assertThrows(TbNodeException.class, () -> node.init(ctxMock, nodeConfiguration)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new TenantId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); |
|
||||
|
|
||||
var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg)); |
|
||||
|
|
||||
assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); |
|
||||
verify(ctxMock, never()).tellSuccess(any()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributes() { |
|
||||
errorThrownIfCannotLoadAttributes(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void errorThrownIfCannotLoadAttributesAsync() { |
|
||||
errorThrownIfCannotLoadAttributesAsync(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void failedChainUsedIfTenantIdFromCtxCannotBeFound() { |
|
||||
when(ctxMock.getTenantId()).thenReturn(null); |
|
||||
failedChainUsedIfCustomerCannotBeFound(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInMetadata() { |
|
||||
entityAttributeAddedInMetadata(tenantId, "TENANT"); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void customerAttributeAddedInData() { |
|
||||
node.fetchTo = FetchTo.DATA; |
|
||||
node.config.setFetchTo(FetchTo.DATA); |
|
||||
|
|
||||
msg = TbMsg.newMsg("TENANT", tenantId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); |
|
||||
|
|
||||
List<AttributeKvEntry> attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); |
|
||||
|
|
||||
when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); |
|
||||
when(attributesServiceMock.find(any(), eq(tenantId), eq(SERVER_SCOPE), anyCollection())) |
|
||||
.thenReturn(Futures.immediateFuture(attributes)); |
|
||||
|
|
||||
node.onMsg(ctxMock, msg); |
|
||||
|
|
||||
var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); |
|
||||
verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); |
|
||||
|
|
||||
var expectedMsgData = "{\"answer\":\"high\"}"; |
|
||||
|
|
||||
assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void usersCustomerAttributesFetched() { |
|
||||
usersCustomerAttributesFetched(user); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void assetsCustomerAttributesFetched() { |
|
||||
assetsCustomerAttributesFetched(asset); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerAttributesFetched() { |
|
||||
deviceCustomerAttributesFetched(device); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void deviceCustomerTelemetryFetched() throws TbNodeException { |
|
||||
deviceCustomerTelemetryFetched(device); |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue