edge services test
This commit is contained in:
parent
a6ae072bc9
commit
43b913ffdb
@ -0,0 +1,403 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 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.server.edge;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
|
import org.thingsboard.server.common.data.DashboardInfo;
|
||||||
|
import org.thingsboard.server.common.data.Device;
|
||||||
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
|
import org.thingsboard.server.common.data.User;
|
||||||
|
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||||
|
import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
||||||
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||||
|
import org.thingsboard.server.common.data.asset.Asset;
|
||||||
|
import org.thingsboard.server.common.data.edge.Edge;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.common.data.page.TextPageLink;
|
||||||
|
import org.thingsboard.server.common.data.page.TimePageData;
|
||||||
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
|
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||||
|
import org.thingsboard.server.common.data.security.Authority;
|
||||||
|
import org.thingsboard.server.controller.AbstractControllerTest;
|
||||||
|
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||||
|
import org.thingsboard.server.edge.imitator.EdgeImitator;
|
||||||
|
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
abstract public class BaseEdgeTest extends AbstractControllerTest {
|
||||||
|
|
||||||
|
private Tenant savedTenant;
|
||||||
|
private TenantId tenantId;
|
||||||
|
private User tenantAdmin;
|
||||||
|
|
||||||
|
private EdgeImitator edgeImitator;
|
||||||
|
private Edge edge;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RuleChainService ruleChainService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeTest() throws Exception {
|
||||||
|
loginSysAdmin();
|
||||||
|
|
||||||
|
Tenant tenant = new Tenant();
|
||||||
|
tenant.setTitle("My tenant");
|
||||||
|
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
|
||||||
|
tenantId = savedTenant.getId();
|
||||||
|
Assert.assertNotNull(savedTenant);
|
||||||
|
|
||||||
|
tenantAdmin = new User();
|
||||||
|
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
|
||||||
|
tenantAdmin.setTenantId(savedTenant.getId());
|
||||||
|
tenantAdmin.setEmail("tenant2@thingsboard.org");
|
||||||
|
tenantAdmin.setFirstName("Joe");
|
||||||
|
tenantAdmin.setLastName("Downs");
|
||||||
|
|
||||||
|
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
|
||||||
|
|
||||||
|
installation();
|
||||||
|
|
||||||
|
edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret());
|
||||||
|
edgeImitator.connect();
|
||||||
|
Thread.sleep(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterTest() throws Exception {
|
||||||
|
edgeImitator.disconnect();
|
||||||
|
uninstallation();
|
||||||
|
|
||||||
|
loginSysAdmin();
|
||||||
|
|
||||||
|
doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
testReceivedData();
|
||||||
|
testDevices();
|
||||||
|
testAssets();
|
||||||
|
testRuleChains();
|
||||||
|
testDashboards();
|
||||||
|
testRelations();
|
||||||
|
testAlarms();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testReceivedData() throws Exception {
|
||||||
|
log.info("Checking received data");
|
||||||
|
EdgeConfiguration configuration = edgeImitator.getStorage().getConfiguration();
|
||||||
|
Assert.assertNotNull(configuration);
|
||||||
|
|
||||||
|
Map<UUID, EntityType> entities = edgeImitator.getStorage().getEntities();
|
||||||
|
Assert.assertFalse(entities.isEmpty());
|
||||||
|
|
||||||
|
Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE);
|
||||||
|
Assert.assertEquals(1, devices.size());
|
||||||
|
TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
|
||||||
|
for (Device device: pageDataDevices.getData()) {
|
||||||
|
Assert.assertTrue(devices.contains(device.getUuidId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET);
|
||||||
|
Assert.assertEquals(1, assets.size());
|
||||||
|
TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
|
||||||
|
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
|
||||||
|
for (Asset asset: pageDataAssets.getData()) {
|
||||||
|
Assert.assertTrue(assets.contains(asset.getUuidId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN);
|
||||||
|
Assert.assertEquals(1, ruleChains.size());
|
||||||
|
TimePageData<RuleChain> pageDataRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?",
|
||||||
|
new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100));
|
||||||
|
for (RuleChain ruleChain: pageDataRuleChains.getData()) {
|
||||||
|
Assert.assertTrue(ruleChains.contains(ruleChain.getUuidId()));
|
||||||
|
}
|
||||||
|
log.info("Received data checked");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testDevices() throws Exception {
|
||||||
|
log.info("Testing devices");
|
||||||
|
Device device = new Device();
|
||||||
|
device.setName("Edge Device 2");
|
||||||
|
device.setType("test");
|
||||||
|
Device savedDevice = doPost("/api/device", device, Device.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/device/" + savedDevice.getId().getId().toString(), Device.class);
|
||||||
|
|
||||||
|
TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertTrue(pageDataDevices.getData().contains(savedDevice));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE);
|
||||||
|
Assert.assertEquals(2, devices.size());
|
||||||
|
Assert.assertTrue(devices.contains(savedDevice.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/device/" + savedDevice.getId().getId().toString(), Device.class);
|
||||||
|
pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertFalse(pageDataDevices.getData().contains(savedDevice));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE);
|
||||||
|
Assert.assertEquals(1, devices.size());
|
||||||
|
Assert.assertFalse(devices.contains(savedDevice.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/device/" + savedDevice.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
log.info("Devices tested successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAssets() throws Exception {
|
||||||
|
log.info("Testing assets");
|
||||||
|
Asset asset = new Asset();
|
||||||
|
asset.setName("Edge Asset 2");
|
||||||
|
asset.setType("test");
|
||||||
|
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
|
||||||
|
|
||||||
|
TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
|
||||||
|
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertTrue(pageDataAssets.getData().contains(savedAsset));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET);
|
||||||
|
Assert.assertEquals(2, assets.size());
|
||||||
|
Assert.assertTrue(assets.contains(savedAsset.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
|
||||||
|
pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
|
||||||
|
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertFalse(pageDataAssets.getData().contains(savedAsset));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET);
|
||||||
|
Assert.assertEquals(1, assets.size());
|
||||||
|
Assert.assertFalse(assets.contains(savedAsset.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/asset/" + savedAsset.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
log.info("Assets tested successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testRuleChains() throws Exception {
|
||||||
|
log.info("Testing RuleChains");
|
||||||
|
RuleChain ruleChain = new RuleChain();
|
||||||
|
ruleChain.setName("Edge Test Rule Chain");
|
||||||
|
ruleChain.setType(RuleChainType.EDGE);
|
||||||
|
RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class);
|
||||||
|
|
||||||
|
TimePageData<RuleChain> pageDataRuleChain = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?",
|
||||||
|
new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertTrue(pageDataRuleChain.getData().contains(savedRuleChain));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN);
|
||||||
|
Assert.assertEquals(2, ruleChains.size());
|
||||||
|
Assert.assertTrue(ruleChains.contains(savedRuleChain.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class);
|
||||||
|
pageDataRuleChain = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?",
|
||||||
|
new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertFalse(pageDataRuleChain.getData().contains(savedRuleChain));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN);
|
||||||
|
Assert.assertEquals(1, ruleChains.size());
|
||||||
|
Assert.assertFalse(ruleChains.contains(savedRuleChain.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
log.info("RuleChains tested successfully");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testDashboards() throws Exception {
|
||||||
|
log.info("Testing Dashboards");
|
||||||
|
Dashboard dashboard = new Dashboard();
|
||||||
|
dashboard.setTitle("Edge Test Dashboard");
|
||||||
|
Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
|
||||||
|
|
||||||
|
TimePageData<DashboardInfo> pageDataDashboard = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/dashboards?",
|
||||||
|
new TypeReference<TimePageData<DashboardInfo>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertTrue(pageDataDashboard.getData().stream().allMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId())));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Set<UUID> dashboards = edgeImitator.getStorage().getEntitiesByType(EntityType.DASHBOARD);
|
||||||
|
Assert.assertEquals(1, dashboards.size());
|
||||||
|
Assert.assertTrue(dashboards.contains(savedDashboard.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
|
||||||
|
pageDataDashboard = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/dashboards?",
|
||||||
|
new TypeReference<TimePageData<DashboardInfo>>() {}, new TextPageLink(100));
|
||||||
|
Assert.assertFalse(pageDataDashboard.getData().stream().anyMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId())));
|
||||||
|
Thread.sleep(1000);
|
||||||
|
dashboards = edgeImitator.getStorage().getEntitiesByType(EntityType.DASHBOARD);
|
||||||
|
Assert.assertEquals(0, dashboards.size());
|
||||||
|
Assert.assertFalse(dashboards.contains(savedDashboard.getUuidId()));
|
||||||
|
|
||||||
|
doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
log.info("Dashboards tested successfully");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installation() throws Exception {
|
||||||
|
edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class);
|
||||||
|
|
||||||
|
Device device = new Device();
|
||||||
|
device.setName("Edge Device 1");
|
||||||
|
device.setType("test");
|
||||||
|
Device savedDevice = doPost("/api/device", device, Device.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/device/" + savedDevice.getId().getId().toString(), Device.class);
|
||||||
|
|
||||||
|
Asset asset = new Asset();
|
||||||
|
asset.setName("Edge Asset 1");
|
||||||
|
asset.setType("test");
|
||||||
|
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
|
||||||
|
doPost("/api/edge/" + edge.getId().getId().toString()
|
||||||
|
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninstallation() throws Exception {
|
||||||
|
|
||||||
|
TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
|
||||||
|
for (Device device: pageDataDevices.getData()) {
|
||||||
|
doDelete("/api/device/" + device.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
|
||||||
|
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
|
||||||
|
for (Asset asset: pageDataAssets.getData()) {
|
||||||
|
doDelete("/api/asset/" + asset.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
doDelete("/api/edge/" + edge.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testRelations() throws Exception {
|
||||||
|
log.info("Testing Relations");
|
||||||
|
List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)).getData();
|
||||||
|
List<Asset> edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
|
||||||
|
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)).getData();
|
||||||
|
|
||||||
|
Assert.assertEquals(1, edgeDevices.size());
|
||||||
|
Assert.assertEquals(1, edgeAssets.size());
|
||||||
|
Device device = edgeDevices.get(0);
|
||||||
|
Asset asset = edgeAssets.get(0);
|
||||||
|
Assert.assertEquals("Edge Device 1", device.getName());
|
||||||
|
Assert.assertEquals("Edge Asset 1", asset.getName());
|
||||||
|
|
||||||
|
EntityRelation relation = new EntityRelation();
|
||||||
|
relation.setType("test");
|
||||||
|
relation.setFrom(device.getId());
|
||||||
|
relation.setTo(asset.getId());
|
||||||
|
relation.setTypeGroup(RelationTypeGroup.COMMON);
|
||||||
|
doPost("/api/relation", relation);
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
List<EntityRelation> relations = edgeImitator.getStorage().getRelations();
|
||||||
|
Assert.assertEquals(1, relations.size());
|
||||||
|
Assert.assertTrue(relations.contains(relation));
|
||||||
|
doDelete("/api/relation?" +
|
||||||
|
"fromId=" + relation.getFrom().getId().toString() +
|
||||||
|
"&fromType=" + relation.getFrom().getEntityType().name() +
|
||||||
|
"&relationType=" + relation.getType() +
|
||||||
|
"&relationTypeGroup=" + relation.getTypeGroup().name() +
|
||||||
|
"&toId=" + relation.getTo().getId().toString() +
|
||||||
|
"&toType=" + relation.getTo().getEntityType().name())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
relations = edgeImitator.getStorage().getRelations();
|
||||||
|
Assert.assertEquals(0, relations.size());
|
||||||
|
Assert.assertFalse(relations.contains(relation));
|
||||||
|
log.info("Relations tested successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void testAlarms() throws Exception {
|
||||||
|
log.info("Testing Alarms");
|
||||||
|
List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
|
||||||
|
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)).getData();
|
||||||
|
Assert.assertEquals(1, edgeDevices.size());
|
||||||
|
Device device = edgeDevices.get(0);
|
||||||
|
Assert.assertEquals("Edge Device 1", device.getName());
|
||||||
|
|
||||||
|
Alarm alarm = new Alarm();
|
||||||
|
alarm.setOriginator(device.getId());
|
||||||
|
alarm.setStatus(AlarmStatus.ACTIVE_UNACK);
|
||||||
|
alarm.setType("alarm");
|
||||||
|
alarm.setSeverity(AlarmSeverity.CRITICAL);
|
||||||
|
|
||||||
|
Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class);
|
||||||
|
AlarmInfo alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class);
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, edgeImitator.getStorage().getAlarms().size());
|
||||||
|
Assert.assertTrue(edgeImitator.getStorage().getAlarms().containsKey(alarmInfo.getType()));
|
||||||
|
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
||||||
|
doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/ack");
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class);
|
||||||
|
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck());
|
||||||
|
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
||||||
|
doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/clear");
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class);
|
||||||
|
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck());
|
||||||
|
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isCleared());
|
||||||
|
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
||||||
|
|
||||||
|
doDelete("/api/alarm/" + savedAlarm.getId().getId().toString())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
log.info("Alarms tested successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 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.server.edge;
|
||||||
|
|
||||||
|
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.extensions.cpsuite.ClasspathSuite;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.thingsboard.server.dao.CustomCassandraCQLUnit;
|
||||||
|
import org.thingsboard.server.queue.memory.InMemoryStorage;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@RunWith(ClasspathSuite.class)
|
||||||
|
@ClasspathSuite.ClassnameFilters({
|
||||||
|
"org.thingsboard.server.edge.nosql.*Test"})
|
||||||
|
public class EdgeNoSqlTestSuite {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static CustomCassandraCQLUnit cassandraUnit =
|
||||||
|
new CustomCassandraCQLUnit(
|
||||||
|
Arrays.asList(
|
||||||
|
new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false),
|
||||||
|
new ClassPathCQLDataSet("cassandra/schema-entities.cql", false, false),
|
||||||
|
new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
|
||||||
|
new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)),
|
||||||
|
"cassandra-test.yaml", 30000l);
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void cleanupInMemStorage(){
|
||||||
|
InMemoryStorage.getInstance().cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 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.server.edge;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.extensions.cpsuite.ClasspathSuite;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.thingsboard.server.dao.CustomSqlUnit;
|
||||||
|
import org.thingsboard.server.queue.memory.InMemoryStorage;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@RunWith(ClasspathSuite.class)
|
||||||
|
@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.edge.sql.*Test"})
|
||||||
|
public class EdgeSqlTestSuite {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
|
||||||
|
Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql"),
|
||||||
|
"sql/hsql/drop-all-tables.sql",
|
||||||
|
"sql-test.properties");
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void cleanupInMemStorage(){
|
||||||
|
InMemoryStorage.getInstance().cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.msa.edge;
|
package org.thingsboard.server.edge.imitator;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.thingsboard.edge.rpc.EdgeGrpcClient;
|
import org.thingsboard.edge.rpc.EdgeGrpcClient;
|
||||||
import org.thingsboard.edge.rpc.EdgeRpcClient;
|
import org.thingsboard.edge.rpc.EdgeRpcClient;
|
||||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
|
import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
|
||||||
import org.thingsboard.server.gen.edge.AssetUpdateMsg;
|
import org.thingsboard.server.gen.edge.AssetUpdateMsg;
|
||||||
import org.thingsboard.server.gen.edge.DashboardUpdateMsg;
|
import org.thingsboard.server.gen.edge.DashboardUpdateMsg;
|
||||||
@ -32,7 +32,6 @@ import org.thingsboard.server.gen.edge.DeviceUpdateMsg;
|
|||||||
import org.thingsboard.server.gen.edge.DownlinkMsg;
|
import org.thingsboard.server.gen.edge.DownlinkMsg;
|
||||||
import org.thingsboard.server.gen.edge.DownlinkResponseMsg;
|
import org.thingsboard.server.gen.edge.DownlinkResponseMsg;
|
||||||
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
||||||
import org.thingsboard.server.gen.edge.EntityDataProto;
|
|
||||||
import org.thingsboard.server.gen.edge.RelationUpdateMsg;
|
import org.thingsboard.server.gen.edge.RelationUpdateMsg;
|
||||||
import org.thingsboard.server.gen.edge.RuleChainUpdateMsg;
|
import org.thingsboard.server.gen.edge.RuleChainUpdateMsg;
|
||||||
import org.thingsboard.server.gen.edge.UplinkResponseMsg;
|
import org.thingsboard.server.gen.edge.UplinkResponseMsg;
|
||||||
@ -75,7 +74,7 @@ public class EdgeImitator {
|
|||||||
this::onUplinkResponse,
|
this::onUplinkResponse,
|
||||||
this::onEdgeUpdate,
|
this::onEdgeUpdate,
|
||||||
this::onDownlink,
|
this::onDownlink,
|
||||||
this::onError);
|
this::onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() throws InterruptedException {
|
public void disconnect() throws InterruptedException {
|
||||||
@ -107,30 +106,30 @@ public class EdgeImitator {
|
|||||||
}, MoreExecutors.directExecutor());
|
}, MoreExecutors.directExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onError(Exception e) {
|
private void onClose(Exception e) {
|
||||||
log.error("Error during Edge lifecycle: ", e);
|
log.info("onClose: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) {
|
private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) {
|
||||||
List<ListenableFuture<Void>> result = new ArrayList<>();
|
List<ListenableFuture<Void>> result = new ArrayList<>();
|
||||||
if (downlinkMsg.getDeviceUpdateMsgList() != null && !downlinkMsg.getDeviceUpdateMsgList().isEmpty()) {
|
if (downlinkMsg.getDeviceUpdateMsgList() != null && !downlinkMsg.getDeviceUpdateMsgList().isEmpty()) {
|
||||||
for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) {
|
for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) {
|
||||||
result.add(storage.processEntity(deviceUpdateMsg.getMsgType(), EdgeEventType.DEVICE, new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())));
|
result.add(storage.processEntity(deviceUpdateMsg.getMsgType(), EntityType.DEVICE, new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (downlinkMsg.getAssetUpdateMsgList() != null && !downlinkMsg.getAssetUpdateMsgList().isEmpty()) {
|
if (downlinkMsg.getAssetUpdateMsgList() != null && !downlinkMsg.getAssetUpdateMsgList().isEmpty()) {
|
||||||
for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) {
|
for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) {
|
||||||
result.add(storage.processEntity(assetUpdateMsg.getMsgType(), EdgeEventType.ASSET, new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB())));
|
result.add(storage.processEntity(assetUpdateMsg.getMsgType(), EntityType.ASSET, new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (downlinkMsg.getRuleChainUpdateMsgList() != null && !downlinkMsg.getRuleChainUpdateMsgList().isEmpty()) {
|
if (downlinkMsg.getRuleChainUpdateMsgList() != null && !downlinkMsg.getRuleChainUpdateMsgList().isEmpty()) {
|
||||||
for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) {
|
for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) {
|
||||||
result.add(storage.processEntity(ruleChainUpdateMsg.getMsgType(), EdgeEventType.RULE_CHAIN, new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB())));
|
result.add(storage.processEntity(ruleChainUpdateMsg.getMsgType(), EntityType.RULE_CHAIN, new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (downlinkMsg.getDashboardUpdateMsgList() != null && !downlinkMsg.getDashboardUpdateMsgList().isEmpty()) {
|
if (downlinkMsg.getDashboardUpdateMsgList() != null && !downlinkMsg.getDashboardUpdateMsgList().isEmpty()) {
|
||||||
for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) {
|
for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) {
|
||||||
result.add(storage.processEntity(dashboardUpdateMsg.getMsgType(), EdgeEventType.DASHBOARD, new UUID(dashboardUpdateMsg.getIdMSB(), dashboardUpdateMsg.getIdLSB())));
|
result.add(storage.processEntity(dashboardUpdateMsg.getMsgType(), EntityType.DASHBOARD, new UUID(dashboardUpdateMsg.getIdMSB(), dashboardUpdateMsg.getIdLSB())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (downlinkMsg.getRelationUpdateMsgList() != null && !downlinkMsg.getRelationUpdateMsgList().isEmpty()) {
|
if (downlinkMsg.getRelationUpdateMsgList() != null && !downlinkMsg.getRelationUpdateMsgList().isEmpty()) {
|
||||||
@ -143,13 +142,6 @@ public class EdgeImitator {
|
|||||||
result.add(storage.processAlarm(alarmUpdateMsg));
|
result.add(storage.processAlarm(alarmUpdateMsg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (downlinkMsg.getEntityDataList() != null && !downlinkMsg.getEntityDataList().isEmpty()) {
|
|
||||||
for (EntityDataProto entityDataProto: downlinkMsg.getEntityDataList()) {
|
|
||||||
if (entityDataProto.hasPostTelemetryMsg()) {
|
|
||||||
result.add(storage.processTelemetry(new UUID(entityDataProto.getEntityIdMSB(), entityDataProto.getEntityIdLSB()), entityDataProto.getPostTelemetryMsg()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Futures.allAsList(result);
|
return Futures.allAsList(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,15 +13,15 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.msa.edge;
|
package org.thingsboard.server.edge.imitator;
|
||||||
|
|
||||||
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.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
|
|
||||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
@ -29,7 +29,6 @@ import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
|
|||||||
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
||||||
import org.thingsboard.server.gen.edge.RelationUpdateMsg;
|
import org.thingsboard.server.gen.edge.RelationUpdateMsg;
|
||||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -46,20 +45,17 @@ public class EdgeStorage {
|
|||||||
|
|
||||||
private EdgeConfiguration configuration;
|
private EdgeConfiguration configuration;
|
||||||
|
|
||||||
private Map<UUID, EdgeEventType> entities;
|
private Map<UUID, EntityType> entities;
|
||||||
private Map<String, AlarmStatus> alarms;
|
private Map<String, AlarmStatus> alarms;
|
||||||
private List<EntityRelation> relations;
|
private List<EntityRelation> relations;
|
||||||
private Map<UUID, TransportProtos.PostTelemetryMsg> latestTelemetry;
|
|
||||||
|
|
||||||
|
|
||||||
public EdgeStorage() {
|
public EdgeStorage() {
|
||||||
entities = new HashMap<>();
|
entities = new HashMap<>();
|
||||||
alarms = new HashMap<>();
|
alarms = new HashMap<>();
|
||||||
relations = new ArrayList<>();
|
relations = new ArrayList<>();
|
||||||
latestTelemetry = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Void> processEntity(UpdateMsgType msgType, EdgeEventType type, UUID uuid) {
|
public ListenableFuture<Void> processEntity(UpdateMsgType msgType, EntityType type, UUID uuid) {
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
case ENTITY_CREATED_RPC_MESSAGE:
|
case ENTITY_CREATED_RPC_MESSAGE:
|
||||||
case ENTITY_UPDATED_RPC_MESSAGE:
|
case ENTITY_UPDATED_RPC_MESSAGE:
|
||||||
@ -105,16 +101,10 @@ public class EdgeStorage {
|
|||||||
return Futures.immediateFuture(null);
|
return Futures.immediateFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Void> processTelemetry(UUID uuid, TransportProtos.PostTelemetryMsg telemetryMsg) {
|
public Set<UUID> getEntitiesByType(EntityType type) {
|
||||||
latestTelemetry.put(uuid, telemetryMsg);
|
return entities.entrySet().stream()
|
||||||
return Futures.immediateFuture(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<UUID> getEntitiesByType(EdgeEventType type) {
|
|
||||||
Map<UUID, EdgeEventType> filtered = entities.entrySet().stream()
|
|
||||||
.filter(entry -> entry.getValue().equals(type))
|
.filter(entry -> entry.getValue().equals(type))
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)).keySet();
|
||||||
return filtered.keySet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 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.server.edge.nosql;
|
||||||
|
|
||||||
|
import org.thingsboard.server.dao.service.DaoNoSqlTest;
|
||||||
|
import org.thingsboard.server.edge.BaseEdgeTest;
|
||||||
|
|
||||||
|
@DaoNoSqlTest
|
||||||
|
public class EdgeNoSqlTest extends BaseEdgeTest {
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 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.server.edge.sql;
|
||||||
|
|
||||||
|
import org.thingsboard.server.dao.service.DaoSqlTest;
|
||||||
|
import org.thingsboard.server.edge.BaseEdgeTest;
|
||||||
|
|
||||||
|
@DaoSqlTest
|
||||||
|
public class EdgeSqlTest extends BaseEdgeTest {
|
||||||
|
}
|
||||||
@ -94,11 +94,6 @@
|
|||||||
<groupId>org.thingsboard</groupId>
|
<groupId>org.thingsboard</groupId>
|
||||||
<artifactId>rest-client</artifactId>
|
<artifactId>rest-client</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.thingsboard.common</groupId>
|
|
||||||
<artifactId>edge-api</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@RunWith(ClasspathSuite.class)
|
@RunWith(ClasspathSuite.class)
|
||||||
@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*EdgeTest"})
|
@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*Test"})
|
||||||
public class ContainerTestSuite {
|
public class ContainerTestSuite {
|
||||||
|
|
||||||
private static DockerComposeContainer testContainer;
|
private static DockerComposeContainer testContainer;
|
||||||
|
|||||||
@ -1,341 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2020 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.server.msa.edge;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.junit.*;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.thingsboard.server.common.data.Dashboard;
|
|
||||||
import org.thingsboard.server.common.data.Device;
|
|
||||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
|
||||||
import org.thingsboard.server.common.data.asset.Asset;
|
|
||||||
import org.thingsboard.server.common.data.edge.Edge;
|
|
||||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
|
|
||||||
import org.thingsboard.server.common.data.kv.TsKvEntry;
|
|
||||||
import org.thingsboard.server.common.data.page.TextPageLink;
|
|
||||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
|
||||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
|
||||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
|
||||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
|
||||||
import org.thingsboard.server.common.data.security.DeviceCredentials;
|
|
||||||
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
|
||||||
import org.thingsboard.server.msa.AbstractContainerTest;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class EdgeTest extends AbstractContainerTest {
|
|
||||||
|
|
||||||
private static EdgeImitator edgeImitator;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void init() throws NoSuchFieldException, IllegalAccessException, InterruptedException, IOException {
|
|
||||||
restClient.login("tenant@thingsboard.org", "tenant");
|
|
||||||
installation();
|
|
||||||
edgeImitator = new EdgeImitator("localhost", 7070, "routing", "secret");
|
|
||||||
edgeImitator.connect();
|
|
||||||
Thread.sleep(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReceivedData() {
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
|
|
||||||
EdgeConfiguration configuration = edgeImitator.getStorage().getConfiguration();
|
|
||||||
Assert.assertNotNull(configuration);
|
|
||||||
|
|
||||||
Map<UUID, EdgeEventType> entities = edgeImitator.getStorage().getEntities();
|
|
||||||
Assert.assertFalse(entities.isEmpty());
|
|
||||||
|
|
||||||
Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE);
|
|
||||||
Assert.assertEquals(1, devices.size());
|
|
||||||
for (Device device: restClient.getEdgeDevices(edge.getId(), new TextPageLink(1)).getData()) {
|
|
||||||
Assert.assertTrue(devices.contains(device.getUuidId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN);
|
|
||||||
Assert.assertEquals(1, ruleChains.size());
|
|
||||||
for (RuleChain ruleChain: restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(1)).getData()) {
|
|
||||||
Assert.assertTrue(ruleChains.contains(ruleChain.getUuidId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET);
|
|
||||||
Assert.assertEquals(1, assets.size());
|
|
||||||
for (Asset asset: restClient.getEdgeAssets(edge.getId(), new TextPageLink(1)).getData()) {
|
|
||||||
Assert.assertTrue(assets.contains(asset.getUuidId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDevices() throws Exception {
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
|
|
||||||
Device device = new Device();
|
|
||||||
device.setName("Edge Device 2");
|
|
||||||
device.setType("test");
|
|
||||||
Device savedDevice = restClient.saveDevice(device);
|
|
||||||
restClient.assignDeviceToEdge(edge.getId(), savedDevice.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertTrue(restClient.getEdgeDevices(edge.getId(), new TextPageLink(2)).getData().contains(savedDevice));
|
|
||||||
Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE);
|
|
||||||
Assert.assertEquals(2, devices.size());
|
|
||||||
Assert.assertTrue(devices.contains(savedDevice.getUuidId()));
|
|
||||||
|
|
||||||
restClient.unassignDeviceFromEdge(edge.getId(), savedDevice.getId());
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertFalse(restClient.getEdgeDevices(edge.getId(), new TextPageLink(2)).getData().contains(savedDevice));
|
|
||||||
devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE);
|
|
||||||
Assert.assertEquals(1, devices.size());
|
|
||||||
Assert.assertFalse(devices.contains(savedDevice.getUuidId()));
|
|
||||||
|
|
||||||
restClient.deleteDevice(savedDevice.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAssets() throws Exception {
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
|
|
||||||
Asset asset = new Asset();
|
|
||||||
asset.setName("Edge Asset 2");
|
|
||||||
asset.setType("test");
|
|
||||||
Asset savedAsset = restClient.saveAsset(asset);
|
|
||||||
restClient.assignAssetToEdge(edge.getId(), savedAsset.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertTrue(restClient.getEdgeAssets(edge.getId(), new TextPageLink(2)).getData().contains(savedAsset));
|
|
||||||
Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET);
|
|
||||||
Assert.assertEquals(2, assets.size());
|
|
||||||
Assert.assertTrue(assets.contains(savedAsset.getUuidId()));
|
|
||||||
|
|
||||||
restClient.unassignAssetFromEdge(edge.getId(), savedAsset.getId());
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertFalse(restClient.getEdgeAssets(edge.getId(), new TextPageLink(2)).getData().contains(savedAsset));
|
|
||||||
assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET);
|
|
||||||
Assert.assertEquals(1, assets.size());
|
|
||||||
Assert.assertFalse(assets.contains(savedAsset.getUuidId()));
|
|
||||||
|
|
||||||
restClient.deleteAsset(savedAsset.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRuleChains() throws Exception {
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
|
|
||||||
RuleChain ruleChain = new RuleChain();
|
|
||||||
ruleChain.setName("Edge Test Rule Chain");
|
|
||||||
ruleChain.setType(RuleChainType.EDGE);
|
|
||||||
RuleChain savedRuleChain = restClient.saveRuleChain(ruleChain);
|
|
||||||
restClient.assignRuleChainToEdge(edge.getId(), savedRuleChain.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertTrue(restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(2)).getData().contains(savedRuleChain));
|
|
||||||
Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN);
|
|
||||||
Assert.assertEquals(2, ruleChains.size());
|
|
||||||
Assert.assertTrue(ruleChains.contains(savedRuleChain.getUuidId()));
|
|
||||||
|
|
||||||
restClient.unassignRuleChainFromEdge(edge.getId(), savedRuleChain.getId());
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertFalse(restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(2)).getData().contains(savedRuleChain));
|
|
||||||
ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN);
|
|
||||||
Assert.assertEquals(1, ruleChains.size());
|
|
||||||
Assert.assertFalse(ruleChains.contains(savedRuleChain.getUuidId()));
|
|
||||||
|
|
||||||
restClient.deleteRuleChain(savedRuleChain.getId());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDashboards() throws Exception {
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
|
|
||||||
Dashboard dashboard = new Dashboard();
|
|
||||||
dashboard.setTitle("Edge Test Dashboard");
|
|
||||||
Dashboard savedDashboard = restClient.saveDashboard(dashboard);
|
|
||||||
restClient.assignDashboardToEdge(edge.getId(), savedDashboard.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertTrue(restClient.getEdgeDashboards(edge.getId(), new TimePageLink(2)).getData().stream().allMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId())));
|
|
||||||
Set<UUID> dashboards = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DASHBOARD);
|
|
||||||
Assert.assertEquals(1, dashboards.size());
|
|
||||||
Assert.assertTrue(dashboards.contains(savedDashboard.getUuidId()));
|
|
||||||
|
|
||||||
restClient.unassignDashboardFromEdge(edge.getId(), savedDashboard.getId());
|
|
||||||
Thread.sleep(1000);
|
|
||||||
Assert.assertFalse(restClient.getEdgeDashboards(edge.getId(), new TimePageLink(2)).getData().stream().anyMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId())));
|
|
||||||
dashboards = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DASHBOARD);
|
|
||||||
Assert.assertEquals(0, dashboards.size());
|
|
||||||
Assert.assertFalse(dashboards.contains(savedDashboard.getUuidId()));
|
|
||||||
|
|
||||||
restClient.deleteDashboard(savedDashboard.getId());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRelations() throws InterruptedException {
|
|
||||||
Device device = restClient.getTenantDevice("Edge Device 1").get();
|
|
||||||
Asset asset = restClient.getTenantAsset("Edge Asset 1").get();
|
|
||||||
|
|
||||||
EntityRelation relation = new EntityRelation();
|
|
||||||
relation.setType("test");
|
|
||||||
relation.setFrom(device.getId());
|
|
||||||
relation.setTo(asset.getId());
|
|
||||||
relation.setTypeGroup(RelationTypeGroup.COMMON);
|
|
||||||
restClient.saveRelation(relation);
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
List<EntityRelation> relations = edgeImitator.getStorage().getRelations();
|
|
||||||
Assert.assertEquals(1, relations.size());
|
|
||||||
Assert.assertTrue(relations.contains(relation));
|
|
||||||
restClient.deleteRelation(relation.getFrom(), relation.getType(), relation.getTypeGroup(), relation.getTo());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
relations = edgeImitator.getStorage().getRelations();
|
|
||||||
Assert.assertEquals(0, relations.size());
|
|
||||||
Assert.assertFalse(relations.contains(relation));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAlarms() throws Exception {
|
|
||||||
Device device = restClient.getTenantDevice("Edge Device 1").get();
|
|
||||||
Alarm alarm = new Alarm();
|
|
||||||
alarm.setOriginator(device.getId());
|
|
||||||
alarm.setStatus(AlarmStatus.ACTIVE_UNACK);
|
|
||||||
alarm.setType("alarm");
|
|
||||||
alarm.setSeverity(AlarmSeverity.CRITICAL);
|
|
||||||
|
|
||||||
Alarm savedAlarm = restClient.saveAlarm(alarm);
|
|
||||||
AlarmInfo alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get();
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
Assert.assertEquals(1, edgeImitator.getStorage().getAlarms().size());
|
|
||||||
Assert.assertTrue(edgeImitator.getStorage().getAlarms().containsKey(alarmInfo.getType()));
|
|
||||||
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
|
||||||
restClient.ackAlarm(savedAlarm.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get();
|
|
||||||
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck());
|
|
||||||
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
|
||||||
restClient.clearAlarm(savedAlarm.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000);
|
|
||||||
alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get();
|
|
||||||
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck());
|
|
||||||
Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isCleared());
|
|
||||||
Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus());
|
|
||||||
|
|
||||||
restClient.deleteAlarm(savedAlarm.getId());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
|
||||||
public void testTelemetry() throws Exception {
|
|
||||||
Device device = restClient.getTenantDevice("Edge Device 1").get();
|
|
||||||
DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(device.getId()).get();
|
|
||||||
ResponseEntity response = restClient.getRestTemplate()
|
|
||||||
.postForEntity(HTTPS_URL + "/api/v1/{credentialsId}/telemetry",
|
|
||||||
"{'test': 25}",
|
|
||||||
ResponseEntity.class,
|
|
||||||
deviceCredentials.getCredentialsId());
|
|
||||||
Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
|
|
||||||
Thread.sleep(1000);
|
|
||||||
List<String> keys = restClient.getTimeseriesKeys(device.getId());
|
|
||||||
List<TsKvEntry> latestTimeseries = restClient.getLatestTimeseries(device.getId(), keys);
|
|
||||||
Assert.assertEquals(1, latestTimeseries.size());
|
|
||||||
TsKvEntry tsKvEntry = latestTimeseries.get(0);
|
|
||||||
Map<UUID, TransportProtos.PostTelemetryMsg> telemetry = edgeImitator.getStorage().getLatestTelemetry();
|
|
||||||
Assert.assertEquals(1, telemetry.size());
|
|
||||||
Assert.assertTrue(telemetry.containsKey(device.getUuidId()));
|
|
||||||
TransportProtos.PostTelemetryMsg telemetryMsg = telemetry.get(device.getUuidId());
|
|
||||||
Assert.assertEquals(1, telemetryMsg.getTsKvListCount());
|
|
||||||
TransportProtos.TsKvListProto tsKv = telemetryMsg.getTsKvListList().get(0);
|
|
||||||
Assert.assertEquals(tsKvEntry.getTs(), tsKv.getTs());
|
|
||||||
Assert.assertEquals(1, tsKv.getKvCount());
|
|
||||||
TransportProtos.KeyValueProto keyValue = tsKv.getKvList().get(0);
|
|
||||||
Assert.assertEquals(tsKvEntry.getKey(), keyValue.getKey());
|
|
||||||
Assert.assertEquals(tsKvEntry.getValueAsString(), Long.toString(keyValue.getLongV()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void destroy() throws InterruptedException {
|
|
||||||
uninstallation();
|
|
||||||
edgeImitator.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void installation() throws IOException {
|
|
||||||
Edge edge = new Edge();
|
|
||||||
edge.setName("Edge1");
|
|
||||||
edge.setType("test");
|
|
||||||
edge.setRoutingKey("routing");
|
|
||||||
edge.setSecret("secret");
|
|
||||||
Edge savedEdge = restClient.saveEdge(edge);
|
|
||||||
|
|
||||||
Device device = new Device();
|
|
||||||
device.setName("Edge Device 1");
|
|
||||||
device.setType("test");
|
|
||||||
Device savedDevice = restClient.saveDevice(device);
|
|
||||||
restClient.assignDeviceToEdge(savedEdge.getId(), savedDevice.getId());
|
|
||||||
|
|
||||||
Asset asset = new Asset();
|
|
||||||
asset.setName("Edge Asset 1");
|
|
||||||
asset.setType("test");
|
|
||||||
Asset savedAsset = restClient.saveAsset(asset);
|
|
||||||
restClient.assignAssetToEdge(savedEdge.getId(), savedAsset.getId());
|
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
Class edgeTestClass = EdgeTest.class;
|
|
||||||
JsonNode configuration = mapper.readTree(edgeTestClass.getClassLoader().getResourceAsStream("RootRuleChain.json"));
|
|
||||||
RuleChain ruleChain = mapper.treeToValue(configuration.get("ruleChain"), RuleChain.class);
|
|
||||||
RuleChainMetaData ruleChainMetaData = mapper.treeToValue(configuration.get("metadata"), RuleChainMetaData.class);
|
|
||||||
RuleChain savedRuleChain = restClient.saveRuleChain(ruleChain);
|
|
||||||
ruleChainMetaData.setRuleChainId(savedRuleChain.getId());
|
|
||||||
restClient.saveRuleChainMetaData(ruleChainMetaData);
|
|
||||||
restClient.setRootRuleChain(savedRuleChain.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void uninstallation() {
|
|
||||||
Device device = restClient.getTenantDevice("Edge Device 1").get();
|
|
||||||
restClient.deleteDevice(device.getId());
|
|
||||||
|
|
||||||
Asset asset = restClient.getTenantAsset("Edge Asset 1").get();
|
|
||||||
restClient.deleteAsset(asset.getId());
|
|
||||||
|
|
||||||
Edge edge = restClient.getTenantEdge("Edge1").get();
|
|
||||||
restClient.deleteEdge(edge.getId());
|
|
||||||
|
|
||||||
List<RuleChain> ruleChains = restClient.getRuleChains(new TextPageLink(3)).getData();
|
|
||||||
RuleChain oldRoot = ruleChains.stream().filter(ruleChain -> ruleChain.getName().equals("Root Rule Chain")).findAny().get();
|
|
||||||
RuleChain newRoot = ruleChains.stream().filter(ruleChain -> ruleChain.getName().equals("Test Root Rule Chain")).findAny().get();
|
|
||||||
restClient.setRootRuleChain(oldRoot.getId());
|
|
||||||
restClient.deleteRuleChain(newRoot.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
{
|
|
||||||
"ruleChain": {
|
|
||||||
"additionalInfo": null,
|
|
||||||
"name": "Test Root Rule Chain",
|
|
||||||
"type": "CORE",
|
|
||||||
"firstRuleNodeId": null,
|
|
||||||
"root": false,
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": null
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"firstNodeIndex": 4,
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 1117,
|
|
||||||
"layoutY": 156
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.edge.TbMsgPushToEdgeNode",
|
|
||||||
"name": "Push to edge",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"version": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 825,
|
|
||||||
"layoutY": 407
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
|
|
||||||
"name": "RPC Call Request",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"timeoutInSeconds": 60
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 826,
|
|
||||||
"layoutY": 327
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.action.TbLogNode",
|
|
||||||
"name": "Log Other",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 827,
|
|
||||||
"layoutY": 244
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.action.TbLogNode",
|
|
||||||
"name": "Log RPC from Device",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 347,
|
|
||||||
"layoutY": 149
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode",
|
|
||||||
"name": "Message Type Switch",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"version": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 821,
|
|
||||||
"layoutY": 72
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
|
|
||||||
"name": "Save Client Attributes",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"scope": "CLIENT_SCOPE"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"additionalInfo": {
|
|
||||||
"layoutX": 824,
|
|
||||||
"layoutY": 156
|
|
||||||
},
|
|
||||||
"type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode",
|
|
||||||
"name": "Save Timeseries",
|
|
||||||
"debugMode": false,
|
|
||||||
"configuration": {
|
|
||||||
"defaultTTL": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"connections": [
|
|
||||||
{
|
|
||||||
"fromIndex": 4,
|
|
||||||
"toIndex": 1,
|
|
||||||
"type": "RPC Request to Device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fromIndex": 4,
|
|
||||||
"toIndex": 3,
|
|
||||||
"type": "RPC Request from Device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fromIndex": 4,
|
|
||||||
"toIndex": 6,
|
|
||||||
"type": "Post telemetry"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fromIndex": 4,
|
|
||||||
"toIndex": 5,
|
|
||||||
"type": "Post attributes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fromIndex": 4,
|
|
||||||
"toIndex": 2,
|
|
||||||
"type": "Other"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fromIndex": 6,
|
|
||||||
"toIndex": 0,
|
|
||||||
"type": "Success"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ruleChainConnections": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user