Showing
11 changed files
with
554 additions
and
514 deletions
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.edge; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.core.type.TypeReference; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.junit.After; | ||
21 | +import org.junit.Assert; | ||
22 | +import org.junit.Before; | ||
23 | +import org.junit.Test; | ||
24 | +import org.springframework.beans.factory.annotation.Autowired; | ||
25 | +import org.thingsboard.server.common.data.Dashboard; | ||
26 | +import org.thingsboard.server.common.data.DashboardInfo; | ||
27 | +import org.thingsboard.server.common.data.Device; | ||
28 | +import org.thingsboard.server.common.data.EntityType; | ||
29 | +import org.thingsboard.server.common.data.Tenant; | ||
30 | +import org.thingsboard.server.common.data.User; | ||
31 | +import org.thingsboard.server.common.data.alarm.Alarm; | ||
32 | +import org.thingsboard.server.common.data.alarm.AlarmInfo; | ||
33 | +import org.thingsboard.server.common.data.alarm.AlarmSeverity; | ||
34 | +import org.thingsboard.server.common.data.alarm.AlarmStatus; | ||
35 | +import org.thingsboard.server.common.data.asset.Asset; | ||
36 | +import org.thingsboard.server.common.data.edge.Edge; | ||
37 | +import org.thingsboard.server.common.data.id.TenantId; | ||
38 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
39 | +import org.thingsboard.server.common.data.page.TimePageData; | ||
40 | +import org.thingsboard.server.common.data.relation.EntityRelation; | ||
41 | +import org.thingsboard.server.common.data.relation.RelationTypeGroup; | ||
42 | +import org.thingsboard.server.common.data.rule.RuleChain; | ||
43 | +import org.thingsboard.server.common.data.rule.RuleChainType; | ||
44 | +import org.thingsboard.server.common.data.security.Authority; | ||
45 | +import org.thingsboard.server.controller.AbstractControllerTest; | ||
46 | +import org.thingsboard.server.dao.rule.RuleChainService; | ||
47 | +import org.thingsboard.server.edge.imitator.EdgeImitator; | ||
48 | +import org.thingsboard.server.gen.edge.EdgeConfiguration; | ||
49 | + | ||
50 | +import java.util.List; | ||
51 | +import java.util.Map; | ||
52 | +import java.util.Set; | ||
53 | +import java.util.UUID; | ||
54 | + | ||
55 | +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
56 | + | ||
57 | + | ||
58 | +@Slf4j | ||
59 | +abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
60 | + | ||
61 | + private Tenant savedTenant; | ||
62 | + private TenantId tenantId; | ||
63 | + private User tenantAdmin; | ||
64 | + | ||
65 | + private EdgeImitator edgeImitator; | ||
66 | + private Edge edge; | ||
67 | + | ||
68 | + @Autowired | ||
69 | + RuleChainService ruleChainService; | ||
70 | + | ||
71 | + @Before | ||
72 | + public void beforeTest() throws Exception { | ||
73 | + loginSysAdmin(); | ||
74 | + | ||
75 | + Tenant tenant = new Tenant(); | ||
76 | + tenant.setTitle("My tenant"); | ||
77 | + savedTenant = doPost("/api/tenant", tenant, Tenant.class); | ||
78 | + tenantId = savedTenant.getId(); | ||
79 | + Assert.assertNotNull(savedTenant); | ||
80 | + | ||
81 | + tenantAdmin = new User(); | ||
82 | + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); | ||
83 | + tenantAdmin.setTenantId(savedTenant.getId()); | ||
84 | + tenantAdmin.setEmail("tenant2@thingsboard.org"); | ||
85 | + tenantAdmin.setFirstName("Joe"); | ||
86 | + tenantAdmin.setLastName("Downs"); | ||
87 | + | ||
88 | + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | ||
89 | + | ||
90 | + installation(); | ||
91 | + | ||
92 | + edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); | ||
93 | + edgeImitator.connect(); | ||
94 | + Thread.sleep(5000); | ||
95 | + } | ||
96 | + | ||
97 | + @After | ||
98 | + public void afterTest() throws Exception { | ||
99 | + edgeImitator.disconnect(); | ||
100 | + uninstallation(); | ||
101 | + | ||
102 | + loginSysAdmin(); | ||
103 | + | ||
104 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | ||
105 | + .andExpect(status().isOk()); | ||
106 | + } | ||
107 | + | ||
108 | + | ||
109 | + @Test | ||
110 | + public void test() throws Exception { | ||
111 | + testReceivedData(); | ||
112 | + testDevices(); | ||
113 | + testAssets(); | ||
114 | + testRuleChains(); | ||
115 | + testDashboards(); | ||
116 | + testRelations(); | ||
117 | + testAlarms(); | ||
118 | + } | ||
119 | + | ||
120 | + private void testReceivedData() throws Exception { | ||
121 | + log.info("Checking received data"); | ||
122 | + EdgeConfiguration configuration = edgeImitator.getStorage().getConfiguration(); | ||
123 | + Assert.assertNotNull(configuration); | ||
124 | + | ||
125 | + Map<UUID, EntityType> entities = edgeImitator.getStorage().getEntities(); | ||
126 | + Assert.assertFalse(entities.isEmpty()); | ||
127 | + | ||
128 | + Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE); | ||
129 | + Assert.assertEquals(1, devices.size()); | ||
130 | + TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
131 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)); | ||
132 | + for (Device device: pageDataDevices.getData()) { | ||
133 | + Assert.assertTrue(devices.contains(device.getUuidId())); | ||
134 | + } | ||
135 | + | ||
136 | + Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET); | ||
137 | + Assert.assertEquals(1, assets.size()); | ||
138 | + TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", | ||
139 | + new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)); | ||
140 | + for (Asset asset: pageDataAssets.getData()) { | ||
141 | + Assert.assertTrue(assets.contains(asset.getUuidId())); | ||
142 | + } | ||
143 | + | ||
144 | + Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN); | ||
145 | + Assert.assertEquals(1, ruleChains.size()); | ||
146 | + TimePageData<RuleChain> pageDataRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", | ||
147 | + new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100)); | ||
148 | + for (RuleChain ruleChain: pageDataRuleChains.getData()) { | ||
149 | + Assert.assertTrue(ruleChains.contains(ruleChain.getUuidId())); | ||
150 | + } | ||
151 | + log.info("Received data checked"); | ||
152 | + } | ||
153 | + | ||
154 | + private void testDevices() throws Exception { | ||
155 | + log.info("Testing devices"); | ||
156 | + Device device = new Device(); | ||
157 | + device.setName("Edge Device 2"); | ||
158 | + device.setType("test"); | ||
159 | + Device savedDevice = doPost("/api/device", device, Device.class); | ||
160 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
161 | + + "/device/" + savedDevice.getId().getId().toString(), Device.class); | ||
162 | + | ||
163 | + TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
164 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)); | ||
165 | + Assert.assertTrue(pageDataDevices.getData().contains(savedDevice)); | ||
166 | + Thread.sleep(1000); | ||
167 | + Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE); | ||
168 | + Assert.assertEquals(2, devices.size()); | ||
169 | + Assert.assertTrue(devices.contains(savedDevice.getUuidId())); | ||
170 | + | ||
171 | + doDelete("/api/edge/" + edge.getId().getId().toString() | ||
172 | + + "/device/" + savedDevice.getId().getId().toString(), Device.class); | ||
173 | + pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
174 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)); | ||
175 | + Assert.assertFalse(pageDataDevices.getData().contains(savedDevice)); | ||
176 | + Thread.sleep(1000); | ||
177 | + devices = edgeImitator.getStorage().getEntitiesByType(EntityType.DEVICE); | ||
178 | + Assert.assertEquals(1, devices.size()); | ||
179 | + Assert.assertFalse(devices.contains(savedDevice.getUuidId())); | ||
180 | + | ||
181 | + doDelete("/api/device/" + savedDevice.getId().getId().toString()) | ||
182 | + .andExpect(status().isOk()); | ||
183 | + log.info("Devices tested successfully"); | ||
184 | + } | ||
185 | + | ||
186 | + private void testAssets() throws Exception { | ||
187 | + log.info("Testing assets"); | ||
188 | + Asset asset = new Asset(); | ||
189 | + asset.setName("Edge Asset 2"); | ||
190 | + asset.setType("test"); | ||
191 | + Asset savedAsset = doPost("/api/asset", asset, Asset.class); | ||
192 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
193 | + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | ||
194 | + | ||
195 | + TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", | ||
196 | + new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)); | ||
197 | + Assert.assertTrue(pageDataAssets.getData().contains(savedAsset)); | ||
198 | + Thread.sleep(1000); | ||
199 | + Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET); | ||
200 | + Assert.assertEquals(2, assets.size()); | ||
201 | + Assert.assertTrue(assets.contains(savedAsset.getUuidId())); | ||
202 | + | ||
203 | + doDelete("/api/edge/" + edge.getId().getId().toString() | ||
204 | + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | ||
205 | + pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", | ||
206 | + new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)); | ||
207 | + Assert.assertFalse(pageDataAssets.getData().contains(savedAsset)); | ||
208 | + Thread.sleep(1000); | ||
209 | + assets = edgeImitator.getStorage().getEntitiesByType(EntityType.ASSET); | ||
210 | + Assert.assertEquals(1, assets.size()); | ||
211 | + Assert.assertFalse(assets.contains(savedAsset.getUuidId())); | ||
212 | + | ||
213 | + doDelete("/api/asset/" + savedAsset.getId().getId().toString()) | ||
214 | + .andExpect(status().isOk()); | ||
215 | + log.info("Assets tested successfully"); | ||
216 | + } | ||
217 | + | ||
218 | + private void testRuleChains() throws Exception { | ||
219 | + log.info("Testing RuleChains"); | ||
220 | + RuleChain ruleChain = new RuleChain(); | ||
221 | + ruleChain.setName("Edge Test Rule Chain"); | ||
222 | + ruleChain.setType(RuleChainType.EDGE); | ||
223 | + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); | ||
224 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
225 | + + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); | ||
226 | + | ||
227 | + TimePageData<RuleChain> pageDataRuleChain = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", | ||
228 | + new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100)); | ||
229 | + Assert.assertTrue(pageDataRuleChain.getData().contains(savedRuleChain)); | ||
230 | + Thread.sleep(1000); | ||
231 | + Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN); | ||
232 | + Assert.assertEquals(2, ruleChains.size()); | ||
233 | + Assert.assertTrue(ruleChains.contains(savedRuleChain.getUuidId())); | ||
234 | + | ||
235 | + doDelete("/api/edge/" + edge.getId().getId().toString() | ||
236 | + + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); | ||
237 | + pageDataRuleChain = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/ruleChains?", | ||
238 | + new TypeReference<TimePageData<RuleChain>>() {}, new TextPageLink(100)); | ||
239 | + Assert.assertFalse(pageDataRuleChain.getData().contains(savedRuleChain)); | ||
240 | + Thread.sleep(1000); | ||
241 | + ruleChains = edgeImitator.getStorage().getEntitiesByType(EntityType.RULE_CHAIN); | ||
242 | + Assert.assertEquals(1, ruleChains.size()); | ||
243 | + Assert.assertFalse(ruleChains.contains(savedRuleChain.getUuidId())); | ||
244 | + | ||
245 | + doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) | ||
246 | + .andExpect(status().isOk()); | ||
247 | + log.info("RuleChains tested successfully"); | ||
248 | + | ||
249 | + } | ||
250 | + | ||
251 | + private void testDashboards() throws Exception { | ||
252 | + log.info("Testing Dashboards"); | ||
253 | + Dashboard dashboard = new Dashboard(); | ||
254 | + dashboard.setTitle("Edge Test Dashboard"); | ||
255 | + Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); | ||
256 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
257 | + + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | ||
258 | + | ||
259 | + TimePageData<DashboardInfo> pageDataDashboard = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/dashboards?", | ||
260 | + new TypeReference<TimePageData<DashboardInfo>>() {}, new TextPageLink(100)); | ||
261 | + Assert.assertTrue(pageDataDashboard.getData().stream().allMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId()))); | ||
262 | + Thread.sleep(1000); | ||
263 | + Set<UUID> dashboards = edgeImitator.getStorage().getEntitiesByType(EntityType.DASHBOARD); | ||
264 | + Assert.assertEquals(1, dashboards.size()); | ||
265 | + Assert.assertTrue(dashboards.contains(savedDashboard.getUuidId())); | ||
266 | + | ||
267 | + doDelete("/api/edge/" + edge.getId().getId().toString() | ||
268 | + + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | ||
269 | + pageDataDashboard = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/dashboards?", | ||
270 | + new TypeReference<TimePageData<DashboardInfo>>() {}, new TextPageLink(100)); | ||
271 | + Assert.assertFalse(pageDataDashboard.getData().stream().anyMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId()))); | ||
272 | + Thread.sleep(1000); | ||
273 | + dashboards = edgeImitator.getStorage().getEntitiesByType(EntityType.DASHBOARD); | ||
274 | + Assert.assertEquals(0, dashboards.size()); | ||
275 | + Assert.assertFalse(dashboards.contains(savedDashboard.getUuidId())); | ||
276 | + | ||
277 | + doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString()) | ||
278 | + .andExpect(status().isOk()); | ||
279 | + log.info("Dashboards tested successfully"); | ||
280 | + | ||
281 | + } | ||
282 | + | ||
283 | + private void installation() throws Exception { | ||
284 | + edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); | ||
285 | + | ||
286 | + Device device = new Device(); | ||
287 | + device.setName("Edge Device 1"); | ||
288 | + device.setType("test"); | ||
289 | + Device savedDevice = doPost("/api/device", device, Device.class); | ||
290 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
291 | + + "/device/" + savedDevice.getId().getId().toString(), Device.class); | ||
292 | + | ||
293 | + Asset asset = new Asset(); | ||
294 | + asset.setName("Edge Asset 1"); | ||
295 | + asset.setType("test"); | ||
296 | + Asset savedAsset = doPost("/api/asset", asset, Asset.class); | ||
297 | + doPost("/api/edge/" + edge.getId().getId().toString() | ||
298 | + + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); | ||
299 | + } | ||
300 | + | ||
301 | + private void uninstallation() throws Exception { | ||
302 | + | ||
303 | + TimePageData<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
304 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)); | ||
305 | + for (Device device: pageDataDevices.getData()) { | ||
306 | + doDelete("/api/device/" + device.getId().getId().toString()) | ||
307 | + .andExpect(status().isOk()); | ||
308 | + } | ||
309 | + | ||
310 | + TimePageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", | ||
311 | + new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)); | ||
312 | + for (Asset asset: pageDataAssets.getData()) { | ||
313 | + doDelete("/api/asset/" + asset.getId().getId().toString()) | ||
314 | + .andExpect(status().isOk()); | ||
315 | + } | ||
316 | + | ||
317 | + doDelete("/api/edge/" + edge.getId().getId().toString()) | ||
318 | + .andExpect(status().isOk()); | ||
319 | + } | ||
320 | + | ||
321 | + private void testRelations() throws Exception { | ||
322 | + log.info("Testing Relations"); | ||
323 | + List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
324 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)).getData(); | ||
325 | + List<Asset> edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", | ||
326 | + new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100)).getData(); | ||
327 | + | ||
328 | + Assert.assertEquals(1, edgeDevices.size()); | ||
329 | + Assert.assertEquals(1, edgeAssets.size()); | ||
330 | + Device device = edgeDevices.get(0); | ||
331 | + Asset asset = edgeAssets.get(0); | ||
332 | + Assert.assertEquals("Edge Device 1", device.getName()); | ||
333 | + Assert.assertEquals("Edge Asset 1", asset.getName()); | ||
334 | + | ||
335 | + EntityRelation relation = new EntityRelation(); | ||
336 | + relation.setType("test"); | ||
337 | + relation.setFrom(device.getId()); | ||
338 | + relation.setTo(asset.getId()); | ||
339 | + relation.setTypeGroup(RelationTypeGroup.COMMON); | ||
340 | + doPost("/api/relation", relation); | ||
341 | + | ||
342 | + Thread.sleep(1000); | ||
343 | + List<EntityRelation> relations = edgeImitator.getStorage().getRelations(); | ||
344 | + Assert.assertEquals(1, relations.size()); | ||
345 | + Assert.assertTrue(relations.contains(relation)); | ||
346 | + doDelete("/api/relation?" + | ||
347 | + "fromId=" + relation.getFrom().getId().toString() + | ||
348 | + "&fromType=" + relation.getFrom().getEntityType().name() + | ||
349 | + "&relationType=" + relation.getType() + | ||
350 | + "&relationTypeGroup=" + relation.getTypeGroup().name() + | ||
351 | + "&toId=" + relation.getTo().getId().toString() + | ||
352 | + "&toType=" + relation.getTo().getEntityType().name()) | ||
353 | + .andExpect(status().isOk()); | ||
354 | + | ||
355 | + Thread.sleep(1000); | ||
356 | + relations = edgeImitator.getStorage().getRelations(); | ||
357 | + Assert.assertEquals(0, relations.size()); | ||
358 | + Assert.assertFalse(relations.contains(relation)); | ||
359 | + log.info("Relations tested successfully"); | ||
360 | + } | ||
361 | + | ||
362 | + | ||
363 | + private void testAlarms() throws Exception { | ||
364 | + log.info("Testing Alarms"); | ||
365 | + List<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", | ||
366 | + new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100)).getData(); | ||
367 | + Assert.assertEquals(1, edgeDevices.size()); | ||
368 | + Device device = edgeDevices.get(0); | ||
369 | + Assert.assertEquals("Edge Device 1", device.getName()); | ||
370 | + | ||
371 | + Alarm alarm = new Alarm(); | ||
372 | + alarm.setOriginator(device.getId()); | ||
373 | + alarm.setStatus(AlarmStatus.ACTIVE_UNACK); | ||
374 | + alarm.setType("alarm"); | ||
375 | + alarm.setSeverity(AlarmSeverity.CRITICAL); | ||
376 | + | ||
377 | + Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); | ||
378 | + AlarmInfo alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class); | ||
379 | + Thread.sleep(1000); | ||
380 | + | ||
381 | + Assert.assertEquals(1, edgeImitator.getStorage().getAlarms().size()); | ||
382 | + Assert.assertTrue(edgeImitator.getStorage().getAlarms().containsKey(alarmInfo.getType())); | ||
383 | + Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
384 | + doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/ack"); | ||
385 | + | ||
386 | + Thread.sleep(1000); | ||
387 | + alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class); | ||
388 | + Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck()); | ||
389 | + Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
390 | + doPost("/api/alarm/" + savedAlarm.getId().getId().toString() + "/clear"); | ||
391 | + | ||
392 | + Thread.sleep(1000); | ||
393 | + alarmInfo = doGet("/api/alarm/info/" + savedAlarm.getId().getId().toString(), AlarmInfo.class); | ||
394 | + Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck()); | ||
395 | + Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isCleared()); | ||
396 | + Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
397 | + | ||
398 | + doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) | ||
399 | + .andExpect(status().isOk()); | ||
400 | + log.info("Alarms tested successfully"); | ||
401 | + } | ||
402 | + | ||
403 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.edge; | ||
17 | + | ||
18 | +import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; | ||
19 | +import org.junit.BeforeClass; | ||
20 | +import org.junit.ClassRule; | ||
21 | +import org.junit.extensions.cpsuite.ClasspathSuite; | ||
22 | +import org.junit.runner.RunWith; | ||
23 | +import org.thingsboard.server.dao.CustomCassandraCQLUnit; | ||
24 | +import org.thingsboard.server.queue.memory.InMemoryStorage; | ||
25 | + | ||
26 | +import java.util.Arrays; | ||
27 | + | ||
28 | +@RunWith(ClasspathSuite.class) | ||
29 | +@ClasspathSuite.ClassnameFilters({ | ||
30 | + "org.thingsboard.server.edge.nosql.*Test"}) | ||
31 | +public class EdgeNoSqlTestSuite { | ||
32 | + | ||
33 | + @ClassRule | ||
34 | + public static CustomCassandraCQLUnit cassandraUnit = | ||
35 | + new CustomCassandraCQLUnit( | ||
36 | + Arrays.asList( | ||
37 | + new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false), | ||
38 | + new ClassPathCQLDataSet("cassandra/schema-entities.cql", false, false), | ||
39 | + new ClassPathCQLDataSet("cassandra/system-data.cql", false, false), | ||
40 | + new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)), | ||
41 | + "cassandra-test.yaml", 30000l); | ||
42 | + | ||
43 | + @BeforeClass | ||
44 | + public static void cleanupInMemStorage(){ | ||
45 | + InMemoryStorage.getInstance().cleanup(); | ||
46 | + } | ||
47 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.edge; | ||
17 | + | ||
18 | +import org.junit.BeforeClass; | ||
19 | +import org.junit.ClassRule; | ||
20 | +import org.junit.extensions.cpsuite.ClasspathSuite; | ||
21 | +import org.junit.runner.RunWith; | ||
22 | +import org.thingsboard.server.dao.CustomSqlUnit; | ||
23 | +import org.thingsboard.server.queue.memory.InMemoryStorage; | ||
24 | + | ||
25 | +import java.util.Arrays; | ||
26 | + | ||
27 | +@RunWith(ClasspathSuite.class) | ||
28 | +@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.edge.sql.*Test"}) | ||
29 | +public class EdgeSqlTestSuite { | ||
30 | + | ||
31 | + @ClassRule | ||
32 | + public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | ||
33 | + Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql"), | ||
34 | + "sql/hsql/drop-all-tables.sql", | ||
35 | + "sql-test.properties"); | ||
36 | + | ||
37 | + @BeforeClass | ||
38 | + public static void cleanupInMemStorage(){ | ||
39 | + InMemoryStorage.getInstance().cleanup(); | ||
40 | + } | ||
41 | +} |
application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java
renamed from
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edge/EdgeImitator.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.msa.edge; | 16 | +package org.thingsboard.server.edge.imitator; |
17 | 17 | ||
18 | import com.google.common.util.concurrent.FutureCallback; | 18 | import com.google.common.util.concurrent.FutureCallback; |
19 | import com.google.common.util.concurrent.Futures; | 19 | import com.google.common.util.concurrent.Futures; |
@@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j; | ||
24 | import org.checkerframework.checker.nullness.qual.Nullable; | 24 | import org.checkerframework.checker.nullness.qual.Nullable; |
25 | import org.thingsboard.edge.rpc.EdgeGrpcClient; | 25 | import org.thingsboard.edge.rpc.EdgeGrpcClient; |
26 | import org.thingsboard.edge.rpc.EdgeRpcClient; | 26 | import org.thingsboard.edge.rpc.EdgeRpcClient; |
27 | -import org.thingsboard.server.common.data.edge.EdgeEventType; | 27 | +import org.thingsboard.server.common.data.EntityType; |
28 | import org.thingsboard.server.gen.edge.AlarmUpdateMsg; | 28 | import org.thingsboard.server.gen.edge.AlarmUpdateMsg; |
29 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; | 29 | import org.thingsboard.server.gen.edge.AssetUpdateMsg; |
30 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; | 30 | import org.thingsboard.server.gen.edge.DashboardUpdateMsg; |
@@ -32,7 +32,6 @@ import org.thingsboard.server.gen.edge.DeviceUpdateMsg; | @@ -32,7 +32,6 @@ import org.thingsboard.server.gen.edge.DeviceUpdateMsg; | ||
32 | import org.thingsboard.server.gen.edge.DownlinkMsg; | 32 | import org.thingsboard.server.gen.edge.DownlinkMsg; |
33 | import org.thingsboard.server.gen.edge.DownlinkResponseMsg; | 33 | import org.thingsboard.server.gen.edge.DownlinkResponseMsg; |
34 | import org.thingsboard.server.gen.edge.EdgeConfiguration; | 34 | import org.thingsboard.server.gen.edge.EdgeConfiguration; |
35 | -import org.thingsboard.server.gen.edge.EntityDataProto; | ||
36 | import org.thingsboard.server.gen.edge.RelationUpdateMsg; | 35 | import org.thingsboard.server.gen.edge.RelationUpdateMsg; |
37 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; | 36 | import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; |
38 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; | 37 | import org.thingsboard.server.gen.edge.UplinkResponseMsg; |
@@ -75,7 +74,7 @@ public class EdgeImitator { | @@ -75,7 +74,7 @@ public class EdgeImitator { | ||
75 | this::onUplinkResponse, | 74 | this::onUplinkResponse, |
76 | this::onEdgeUpdate, | 75 | this::onEdgeUpdate, |
77 | this::onDownlink, | 76 | this::onDownlink, |
78 | - this::onError); | 77 | + this::onClose); |
79 | } | 78 | } |
80 | 79 | ||
81 | public void disconnect() throws InterruptedException { | 80 | public void disconnect() throws InterruptedException { |
@@ -107,30 +106,30 @@ public class EdgeImitator { | @@ -107,30 +106,30 @@ public class EdgeImitator { | ||
107 | }, MoreExecutors.directExecutor()); | 106 | }, MoreExecutors.directExecutor()); |
108 | } | 107 | } |
109 | 108 | ||
110 | - private void onError(Exception e) { | ||
111 | - log.error("Error during Edge lifecycle: ", e); | 109 | + private void onClose(Exception e) { |
110 | + log.info("onClose: {}", e.getMessage()); | ||
112 | } | 111 | } |
113 | 112 | ||
114 | private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) { | 113 | private ListenableFuture<List<Void>> processDownlinkMsg(DownlinkMsg downlinkMsg) { |
115 | List<ListenableFuture<Void>> result = new ArrayList<>(); | 114 | List<ListenableFuture<Void>> result = new ArrayList<>(); |
116 | if (downlinkMsg.getDeviceUpdateMsgList() != null && !downlinkMsg.getDeviceUpdateMsgList().isEmpty()) { | 115 | if (downlinkMsg.getDeviceUpdateMsgList() != null && !downlinkMsg.getDeviceUpdateMsgList().isEmpty()) { |
117 | for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) { | 116 | for (DeviceUpdateMsg deviceUpdateMsg: downlinkMsg.getDeviceUpdateMsgList()) { |
118 | - result.add(storage.processEntity(deviceUpdateMsg.getMsgType(), EdgeEventType.DEVICE, new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()))); | 117 | + result.add(storage.processEntity(deviceUpdateMsg.getMsgType(), EntityType.DEVICE, new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()))); |
119 | } | 118 | } |
120 | } | 119 | } |
121 | if (downlinkMsg.getAssetUpdateMsgList() != null && !downlinkMsg.getAssetUpdateMsgList().isEmpty()) { | 120 | if (downlinkMsg.getAssetUpdateMsgList() != null && !downlinkMsg.getAssetUpdateMsgList().isEmpty()) { |
122 | for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) { | 121 | for (AssetUpdateMsg assetUpdateMsg: downlinkMsg.getAssetUpdateMsgList()) { |
123 | - result.add(storage.processEntity(assetUpdateMsg.getMsgType(), EdgeEventType.ASSET, new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()))); | 122 | + result.add(storage.processEntity(assetUpdateMsg.getMsgType(), EntityType.ASSET, new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()))); |
124 | } | 123 | } |
125 | } | 124 | } |
126 | if (downlinkMsg.getRuleChainUpdateMsgList() != null && !downlinkMsg.getRuleChainUpdateMsgList().isEmpty()) { | 125 | if (downlinkMsg.getRuleChainUpdateMsgList() != null && !downlinkMsg.getRuleChainUpdateMsgList().isEmpty()) { |
127 | for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) { | 126 | for (RuleChainUpdateMsg ruleChainUpdateMsg: downlinkMsg.getRuleChainUpdateMsgList()) { |
128 | - result.add(storage.processEntity(ruleChainUpdateMsg.getMsgType(), EdgeEventType.RULE_CHAIN, new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()))); | 127 | + result.add(storage.processEntity(ruleChainUpdateMsg.getMsgType(), EntityType.RULE_CHAIN, new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()))); |
129 | } | 128 | } |
130 | } | 129 | } |
131 | if (downlinkMsg.getDashboardUpdateMsgList() != null && !downlinkMsg.getDashboardUpdateMsgList().isEmpty()) { | 130 | if (downlinkMsg.getDashboardUpdateMsgList() != null && !downlinkMsg.getDashboardUpdateMsgList().isEmpty()) { |
132 | for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) { | 131 | for (DashboardUpdateMsg dashboardUpdateMsg: downlinkMsg.getDashboardUpdateMsgList()) { |
133 | - result.add(storage.processEntity(dashboardUpdateMsg.getMsgType(), EdgeEventType.DASHBOARD, new UUID(dashboardUpdateMsg.getIdMSB(), dashboardUpdateMsg.getIdLSB()))); | 132 | + result.add(storage.processEntity(dashboardUpdateMsg.getMsgType(), EntityType.DASHBOARD, new UUID(dashboardUpdateMsg.getIdMSB(), dashboardUpdateMsg.getIdLSB()))); |
134 | } | 133 | } |
135 | } | 134 | } |
136 | if (downlinkMsg.getRelationUpdateMsgList() != null && !downlinkMsg.getRelationUpdateMsgList().isEmpty()) { | 135 | if (downlinkMsg.getRelationUpdateMsgList() != null && !downlinkMsg.getRelationUpdateMsgList().isEmpty()) { |
@@ -143,13 +142,6 @@ public class EdgeImitator { | @@ -143,13 +142,6 @@ public class EdgeImitator { | ||
143 | result.add(storage.processAlarm(alarmUpdateMsg)); | 142 | result.add(storage.processAlarm(alarmUpdateMsg)); |
144 | } | 143 | } |
145 | } | 144 | } |
146 | - if (downlinkMsg.getEntityDataList() != null && !downlinkMsg.getEntityDataList().isEmpty()) { | ||
147 | - for (EntityDataProto entityDataProto: downlinkMsg.getEntityDataList()) { | ||
148 | - if (entityDataProto.hasPostTelemetryMsg()) { | ||
149 | - result.add(storage.processTelemetry(new UUID(entityDataProto.getEntityIdMSB(), entityDataProto.getEntityIdLSB()), entityDataProto.getPostTelemetryMsg())); | ||
150 | - } | ||
151 | - } | ||
152 | - } | ||
153 | return Futures.allAsList(result); | 145 | return Futures.allAsList(result); |
154 | } | 146 | } |
155 | 147 |
application/src/test/java/org/thingsboard/server/edge/imitator/EdgeStorage.java
renamed from
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edge/EdgeStorage.java
@@ -13,15 +13,15 @@ | @@ -13,15 +13,15 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.msa.edge; | 16 | +package org.thingsboard.server.edge.imitator; |
17 | 17 | ||
18 | import com.google.common.util.concurrent.Futures; | 18 | import com.google.common.util.concurrent.Futures; |
19 | import com.google.common.util.concurrent.ListenableFuture; | 19 | import com.google.common.util.concurrent.ListenableFuture; |
20 | import lombok.Getter; | 20 | import lombok.Getter; |
21 | import lombok.Setter; | 21 | import lombok.Setter; |
22 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
23 | +import org.thingsboard.server.common.data.EntityType; | ||
23 | import org.thingsboard.server.common.data.alarm.AlarmStatus; | 24 | import org.thingsboard.server.common.data.alarm.AlarmStatus; |
24 | -import org.thingsboard.server.common.data.edge.EdgeEventType; | ||
25 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 25 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
26 | import org.thingsboard.server.common.data.relation.EntityRelation; | 26 | import org.thingsboard.server.common.data.relation.EntityRelation; |
27 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; | 27 | import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
@@ -29,7 +29,6 @@ import org.thingsboard.server.gen.edge.AlarmUpdateMsg; | @@ -29,7 +29,6 @@ import org.thingsboard.server.gen.edge.AlarmUpdateMsg; | ||
29 | import org.thingsboard.server.gen.edge.EdgeConfiguration; | 29 | import org.thingsboard.server.gen.edge.EdgeConfiguration; |
30 | import org.thingsboard.server.gen.edge.RelationUpdateMsg; | 30 | import org.thingsboard.server.gen.edge.RelationUpdateMsg; |
31 | import org.thingsboard.server.gen.edge.UpdateMsgType; | 31 | import org.thingsboard.server.gen.edge.UpdateMsgType; |
32 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
33 | 32 | ||
34 | import java.util.ArrayList; | 33 | import java.util.ArrayList; |
35 | import java.util.HashMap; | 34 | import java.util.HashMap; |
@@ -46,20 +45,17 @@ public class EdgeStorage { | @@ -46,20 +45,17 @@ public class EdgeStorage { | ||
46 | 45 | ||
47 | private EdgeConfiguration configuration; | 46 | private EdgeConfiguration configuration; |
48 | 47 | ||
49 | - private Map<UUID, EdgeEventType> entities; | 48 | + private Map<UUID, EntityType> entities; |
50 | private Map<String, AlarmStatus> alarms; | 49 | private Map<String, AlarmStatus> alarms; |
51 | private List<EntityRelation> relations; | 50 | private List<EntityRelation> relations; |
52 | - private Map<UUID, TransportProtos.PostTelemetryMsg> latestTelemetry; | ||
53 | - | ||
54 | 51 | ||
55 | public EdgeStorage() { | 52 | public EdgeStorage() { |
56 | entities = new HashMap<>(); | 53 | entities = new HashMap<>(); |
57 | alarms = new HashMap<>(); | 54 | alarms = new HashMap<>(); |
58 | relations = new ArrayList<>(); | 55 | relations = new ArrayList<>(); |
59 | - latestTelemetry = new HashMap<>(); | ||
60 | } | 56 | } |
61 | 57 | ||
62 | - public ListenableFuture<Void> processEntity(UpdateMsgType msgType, EdgeEventType type, UUID uuid) { | 58 | + public ListenableFuture<Void> processEntity(UpdateMsgType msgType, EntityType type, UUID uuid) { |
63 | switch (msgType) { | 59 | switch (msgType) { |
64 | case ENTITY_CREATED_RPC_MESSAGE: | 60 | case ENTITY_CREATED_RPC_MESSAGE: |
65 | case ENTITY_UPDATED_RPC_MESSAGE: | 61 | case ENTITY_UPDATED_RPC_MESSAGE: |
@@ -105,16 +101,10 @@ public class EdgeStorage { | @@ -105,16 +101,10 @@ public class EdgeStorage { | ||
105 | return Futures.immediateFuture(null); | 101 | return Futures.immediateFuture(null); |
106 | } | 102 | } |
107 | 103 | ||
108 | - public ListenableFuture<Void> processTelemetry(UUID uuid, TransportProtos.PostTelemetryMsg telemetryMsg) { | ||
109 | - latestTelemetry.put(uuid, telemetryMsg); | ||
110 | - return Futures.immediateFuture(null); | ||
111 | - } | ||
112 | - | ||
113 | - public Set<UUID> getEntitiesByType(EdgeEventType type) { | ||
114 | - Map<UUID, EdgeEventType> filtered = entities.entrySet().stream() | 104 | + public Set<UUID> getEntitiesByType(EntityType type) { |
105 | + return entities.entrySet().stream() | ||
115 | .filter(entry -> entry.getValue().equals(type)) | 106 | .filter(entry -> entry.getValue().equals(type)) |
116 | - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
117 | - return filtered.keySet(); | 107 | + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)).keySet(); |
118 | } | 108 | } |
119 | 109 | ||
120 | } | 110 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.edge.nosql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | ||
19 | +import org.thingsboard.server.edge.BaseEdgeTest; | ||
20 | + | ||
21 | +@DaoNoSqlTest | ||
22 | +public class EdgeNoSqlTest extends BaseEdgeTest { | ||
23 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.edge.sql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
19 | +import org.thingsboard.server.edge.BaseEdgeTest; | ||
20 | + | ||
21 | +@DaoSqlTest | ||
22 | +public class EdgeSqlTest extends BaseEdgeTest { | ||
23 | +} |
@@ -94,11 +94,6 @@ | @@ -94,11 +94,6 @@ | ||
94 | <groupId>org.thingsboard</groupId> | 94 | <groupId>org.thingsboard</groupId> |
95 | <artifactId>rest-client</artifactId> | 95 | <artifactId>rest-client</artifactId> |
96 | </dependency> | 96 | </dependency> |
97 | - <dependency> | ||
98 | - <groupId>org.thingsboard.common</groupId> | ||
99 | - <artifactId>edge-api</artifactId> | ||
100 | - <scope>test</scope> | ||
101 | - </dependency> | ||
102 | </dependencies> | 97 | </dependencies> |
103 | 98 | ||
104 | <build> | 99 | <build> |
@@ -31,7 +31,7 @@ import java.util.List; | @@ -31,7 +31,7 @@ import java.util.List; | ||
31 | import java.util.Map; | 31 | import java.util.Map; |
32 | 32 | ||
33 | @RunWith(ClasspathSuite.class) | 33 | @RunWith(ClasspathSuite.class) |
34 | -@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*EdgeTest"}) | 34 | +@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*Test"}) |
35 | public class ContainerTestSuite { | 35 | public class ContainerTestSuite { |
36 | 36 | ||
37 | private static DockerComposeContainer testContainer; | 37 | private static DockerComposeContainer testContainer; |
1 | -/** | ||
2 | - * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.thingsboard.server.msa.edge; | ||
17 | - | ||
18 | -import com.fasterxml.jackson.databind.JsonNode; | ||
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | -import lombok.extern.slf4j.Slf4j; | ||
21 | -import org.junit.*; | ||
22 | -import org.springframework.http.HttpStatus; | ||
23 | -import org.springframework.http.ResponseEntity; | ||
24 | -import org.thingsboard.server.common.data.Dashboard; | ||
25 | -import org.thingsboard.server.common.data.Device; | ||
26 | -import org.thingsboard.server.common.data.alarm.Alarm; | ||
27 | -import org.thingsboard.server.common.data.alarm.AlarmInfo; | ||
28 | -import org.thingsboard.server.common.data.alarm.AlarmSeverity; | ||
29 | -import org.thingsboard.server.common.data.alarm.AlarmStatus; | ||
30 | -import org.thingsboard.server.common.data.asset.Asset; | ||
31 | -import org.thingsboard.server.common.data.edge.Edge; | ||
32 | -import org.thingsboard.server.common.data.edge.EdgeEventType; | ||
33 | -import org.thingsboard.server.common.data.kv.TsKvEntry; | ||
34 | -import org.thingsboard.server.common.data.page.TextPageLink; | ||
35 | -import org.thingsboard.server.common.data.page.TimePageLink; | ||
36 | -import org.thingsboard.server.common.data.relation.EntityRelation; | ||
37 | -import org.thingsboard.server.common.data.relation.RelationTypeGroup; | ||
38 | -import org.thingsboard.server.common.data.rule.RuleChain; | ||
39 | -import org.thingsboard.server.common.data.rule.RuleChainMetaData; | ||
40 | -import org.thingsboard.server.common.data.rule.RuleChainType; | ||
41 | -import org.thingsboard.server.common.data.security.DeviceCredentials; | ||
42 | -import org.thingsboard.server.gen.edge.EdgeConfiguration; | ||
43 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
44 | -import org.thingsboard.server.msa.AbstractContainerTest; | ||
45 | - | ||
46 | -import java.io.IOException; | ||
47 | -import java.util.List; | ||
48 | -import java.util.Map; | ||
49 | -import java.util.Set; | ||
50 | -import java.util.UUID; | ||
51 | - | ||
52 | -@Slf4j | ||
53 | -public class EdgeTest extends AbstractContainerTest { | ||
54 | - | ||
55 | - private static EdgeImitator edgeImitator; | ||
56 | - | ||
57 | - @BeforeClass | ||
58 | - public static void init() throws NoSuchFieldException, IllegalAccessException, InterruptedException, IOException { | ||
59 | - restClient.login("tenant@thingsboard.org", "tenant"); | ||
60 | - installation(); | ||
61 | - edgeImitator = new EdgeImitator("localhost", 7070, "routing", "secret"); | ||
62 | - edgeImitator.connect(); | ||
63 | - Thread.sleep(10000); | ||
64 | - } | ||
65 | - | ||
66 | - @Test | ||
67 | - public void testReceivedData() { | ||
68 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
69 | - | ||
70 | - EdgeConfiguration configuration = edgeImitator.getStorage().getConfiguration(); | ||
71 | - Assert.assertNotNull(configuration); | ||
72 | - | ||
73 | - Map<UUID, EdgeEventType> entities = edgeImitator.getStorage().getEntities(); | ||
74 | - Assert.assertFalse(entities.isEmpty()); | ||
75 | - | ||
76 | - Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE); | ||
77 | - Assert.assertEquals(1, devices.size()); | ||
78 | - for (Device device: restClient.getEdgeDevices(edge.getId(), new TextPageLink(1)).getData()) { | ||
79 | - Assert.assertTrue(devices.contains(device.getUuidId())); | ||
80 | - } | ||
81 | - | ||
82 | - Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN); | ||
83 | - Assert.assertEquals(1, ruleChains.size()); | ||
84 | - for (RuleChain ruleChain: restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(1)).getData()) { | ||
85 | - Assert.assertTrue(ruleChains.contains(ruleChain.getUuidId())); | ||
86 | - } | ||
87 | - | ||
88 | - Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET); | ||
89 | - Assert.assertEquals(1, assets.size()); | ||
90 | - for (Asset asset: restClient.getEdgeAssets(edge.getId(), new TextPageLink(1)).getData()) { | ||
91 | - Assert.assertTrue(assets.contains(asset.getUuidId())); | ||
92 | - } | ||
93 | - } | ||
94 | - | ||
95 | - @Test | ||
96 | - public void testDevices() throws Exception { | ||
97 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
98 | - | ||
99 | - Device device = new Device(); | ||
100 | - device.setName("Edge Device 2"); | ||
101 | - device.setType("test"); | ||
102 | - Device savedDevice = restClient.saveDevice(device); | ||
103 | - restClient.assignDeviceToEdge(edge.getId(), savedDevice.getId()); | ||
104 | - | ||
105 | - Thread.sleep(1000); | ||
106 | - Assert.assertTrue(restClient.getEdgeDevices(edge.getId(), new TextPageLink(2)).getData().contains(savedDevice)); | ||
107 | - Set<UUID> devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE); | ||
108 | - Assert.assertEquals(2, devices.size()); | ||
109 | - Assert.assertTrue(devices.contains(savedDevice.getUuidId())); | ||
110 | - | ||
111 | - restClient.unassignDeviceFromEdge(edge.getId(), savedDevice.getId()); | ||
112 | - Thread.sleep(1000); | ||
113 | - Assert.assertFalse(restClient.getEdgeDevices(edge.getId(), new TextPageLink(2)).getData().contains(savedDevice)); | ||
114 | - devices = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DEVICE); | ||
115 | - Assert.assertEquals(1, devices.size()); | ||
116 | - Assert.assertFalse(devices.contains(savedDevice.getUuidId())); | ||
117 | - | ||
118 | - restClient.deleteDevice(savedDevice.getId()); | ||
119 | - } | ||
120 | - | ||
121 | - @Test | ||
122 | - public void testAssets() throws Exception { | ||
123 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
124 | - | ||
125 | - Asset asset = new Asset(); | ||
126 | - asset.setName("Edge Asset 2"); | ||
127 | - asset.setType("test"); | ||
128 | - Asset savedAsset = restClient.saveAsset(asset); | ||
129 | - restClient.assignAssetToEdge(edge.getId(), savedAsset.getId()); | ||
130 | - | ||
131 | - Thread.sleep(1000); | ||
132 | - Assert.assertTrue(restClient.getEdgeAssets(edge.getId(), new TextPageLink(2)).getData().contains(savedAsset)); | ||
133 | - Set<UUID> assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET); | ||
134 | - Assert.assertEquals(2, assets.size()); | ||
135 | - Assert.assertTrue(assets.contains(savedAsset.getUuidId())); | ||
136 | - | ||
137 | - restClient.unassignAssetFromEdge(edge.getId(), savedAsset.getId()); | ||
138 | - Thread.sleep(1000); | ||
139 | - Assert.assertFalse(restClient.getEdgeAssets(edge.getId(), new TextPageLink(2)).getData().contains(savedAsset)); | ||
140 | - assets = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.ASSET); | ||
141 | - Assert.assertEquals(1, assets.size()); | ||
142 | - Assert.assertFalse(assets.contains(savedAsset.getUuidId())); | ||
143 | - | ||
144 | - restClient.deleteAsset(savedAsset.getId()); | ||
145 | - } | ||
146 | - | ||
147 | - @Test | ||
148 | - public void testRuleChains() throws Exception { | ||
149 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
150 | - | ||
151 | - RuleChain ruleChain = new RuleChain(); | ||
152 | - ruleChain.setName("Edge Test Rule Chain"); | ||
153 | - ruleChain.setType(RuleChainType.EDGE); | ||
154 | - RuleChain savedRuleChain = restClient.saveRuleChain(ruleChain); | ||
155 | - restClient.assignRuleChainToEdge(edge.getId(), savedRuleChain.getId()); | ||
156 | - | ||
157 | - Thread.sleep(1000); | ||
158 | - Assert.assertTrue(restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(2)).getData().contains(savedRuleChain)); | ||
159 | - Set<UUID> ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN); | ||
160 | - Assert.assertEquals(2, ruleChains.size()); | ||
161 | - Assert.assertTrue(ruleChains.contains(savedRuleChain.getUuidId())); | ||
162 | - | ||
163 | - restClient.unassignRuleChainFromEdge(edge.getId(), savedRuleChain.getId()); | ||
164 | - Thread.sleep(1000); | ||
165 | - Assert.assertFalse(restClient.getEdgeRuleChains(edge.getId(), new TimePageLink(2)).getData().contains(savedRuleChain)); | ||
166 | - ruleChains = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.RULE_CHAIN); | ||
167 | - Assert.assertEquals(1, ruleChains.size()); | ||
168 | - Assert.assertFalse(ruleChains.contains(savedRuleChain.getUuidId())); | ||
169 | - | ||
170 | - restClient.deleteRuleChain(savedRuleChain.getId()); | ||
171 | - | ||
172 | - } | ||
173 | - | ||
174 | - @Test | ||
175 | - public void testDashboards() throws Exception { | ||
176 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
177 | - | ||
178 | - Dashboard dashboard = new Dashboard(); | ||
179 | - dashboard.setTitle("Edge Test Dashboard"); | ||
180 | - Dashboard savedDashboard = restClient.saveDashboard(dashboard); | ||
181 | - restClient.assignDashboardToEdge(edge.getId(), savedDashboard.getId()); | ||
182 | - | ||
183 | - Thread.sleep(1000); | ||
184 | - Assert.assertTrue(restClient.getEdgeDashboards(edge.getId(), new TimePageLink(2)).getData().stream().allMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId()))); | ||
185 | - Set<UUID> dashboards = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DASHBOARD); | ||
186 | - Assert.assertEquals(1, dashboards.size()); | ||
187 | - Assert.assertTrue(dashboards.contains(savedDashboard.getUuidId())); | ||
188 | - | ||
189 | - restClient.unassignDashboardFromEdge(edge.getId(), savedDashboard.getId()); | ||
190 | - Thread.sleep(1000); | ||
191 | - Assert.assertFalse(restClient.getEdgeDashboards(edge.getId(), new TimePageLink(2)).getData().stream().anyMatch(dashboardInfo -> dashboardInfo.getUuidId().equals(savedDashboard.getUuidId()))); | ||
192 | - dashboards = edgeImitator.getStorage().getEntitiesByType(EdgeEventType.DASHBOARD); | ||
193 | - Assert.assertEquals(0, dashboards.size()); | ||
194 | - Assert.assertFalse(dashboards.contains(savedDashboard.getUuidId())); | ||
195 | - | ||
196 | - restClient.deleteDashboard(savedDashboard.getId()); | ||
197 | - | ||
198 | - } | ||
199 | - | ||
200 | - @Test | ||
201 | - public void testRelations() throws InterruptedException { | ||
202 | - Device device = restClient.getTenantDevice("Edge Device 1").get(); | ||
203 | - Asset asset = restClient.getTenantAsset("Edge Asset 1").get(); | ||
204 | - | ||
205 | - EntityRelation relation = new EntityRelation(); | ||
206 | - relation.setType("test"); | ||
207 | - relation.setFrom(device.getId()); | ||
208 | - relation.setTo(asset.getId()); | ||
209 | - relation.setTypeGroup(RelationTypeGroup.COMMON); | ||
210 | - restClient.saveRelation(relation); | ||
211 | - | ||
212 | - Thread.sleep(1000); | ||
213 | - List<EntityRelation> relations = edgeImitator.getStorage().getRelations(); | ||
214 | - Assert.assertEquals(1, relations.size()); | ||
215 | - Assert.assertTrue(relations.contains(relation)); | ||
216 | - restClient.deleteRelation(relation.getFrom(), relation.getType(), relation.getTypeGroup(), relation.getTo()); | ||
217 | - | ||
218 | - Thread.sleep(1000); | ||
219 | - relations = edgeImitator.getStorage().getRelations(); | ||
220 | - Assert.assertEquals(0, relations.size()); | ||
221 | - Assert.assertFalse(relations.contains(relation)); | ||
222 | - } | ||
223 | - | ||
224 | - @Test | ||
225 | - public void testAlarms() throws Exception { | ||
226 | - Device device = restClient.getTenantDevice("Edge Device 1").get(); | ||
227 | - Alarm alarm = new Alarm(); | ||
228 | - alarm.setOriginator(device.getId()); | ||
229 | - alarm.setStatus(AlarmStatus.ACTIVE_UNACK); | ||
230 | - alarm.setType("alarm"); | ||
231 | - alarm.setSeverity(AlarmSeverity.CRITICAL); | ||
232 | - | ||
233 | - Alarm savedAlarm = restClient.saveAlarm(alarm); | ||
234 | - AlarmInfo alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get(); | ||
235 | - Thread.sleep(1000); | ||
236 | - | ||
237 | - Assert.assertEquals(1, edgeImitator.getStorage().getAlarms().size()); | ||
238 | - Assert.assertTrue(edgeImitator.getStorage().getAlarms().containsKey(alarmInfo.getType())); | ||
239 | - Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
240 | - restClient.ackAlarm(savedAlarm.getId()); | ||
241 | - | ||
242 | - Thread.sleep(1000); | ||
243 | - alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get(); | ||
244 | - Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck()); | ||
245 | - Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
246 | - restClient.clearAlarm(savedAlarm.getId()); | ||
247 | - | ||
248 | - Thread.sleep(1000); | ||
249 | - alarmInfo = restClient.getAlarmInfoById(savedAlarm.getId()).get(); | ||
250 | - Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isAck()); | ||
251 | - Assert.assertTrue(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()).isCleared()); | ||
252 | - Assert.assertEquals(edgeImitator.getStorage().getAlarms().get(alarmInfo.getType()), alarmInfo.getStatus()); | ||
253 | - | ||
254 | - restClient.deleteAlarm(savedAlarm.getId()); | ||
255 | - | ||
256 | - } | ||
257 | - | ||
258 | - @Ignore | ||
259 | - @Test | ||
260 | - public void testTelemetry() throws Exception { | ||
261 | - Device device = restClient.getTenantDevice("Edge Device 1").get(); | ||
262 | - DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(device.getId()).get(); | ||
263 | - ResponseEntity response = restClient.getRestTemplate() | ||
264 | - .postForEntity(HTTPS_URL + "/api/v1/{credentialsId}/telemetry", | ||
265 | - "{'test': 25}", | ||
266 | - ResponseEntity.class, | ||
267 | - deviceCredentials.getCredentialsId()); | ||
268 | - Assert.assertEquals(response.getStatusCode(), HttpStatus.OK); | ||
269 | - Thread.sleep(1000); | ||
270 | - List<String> keys = restClient.getTimeseriesKeys(device.getId()); | ||
271 | - List<TsKvEntry> latestTimeseries = restClient.getLatestTimeseries(device.getId(), keys); | ||
272 | - Assert.assertEquals(1, latestTimeseries.size()); | ||
273 | - TsKvEntry tsKvEntry = latestTimeseries.get(0); | ||
274 | - Map<UUID, TransportProtos.PostTelemetryMsg> telemetry = edgeImitator.getStorage().getLatestTelemetry(); | ||
275 | - Assert.assertEquals(1, telemetry.size()); | ||
276 | - Assert.assertTrue(telemetry.containsKey(device.getUuidId())); | ||
277 | - TransportProtos.PostTelemetryMsg telemetryMsg = telemetry.get(device.getUuidId()); | ||
278 | - Assert.assertEquals(1, telemetryMsg.getTsKvListCount()); | ||
279 | - TransportProtos.TsKvListProto tsKv = telemetryMsg.getTsKvListList().get(0); | ||
280 | - Assert.assertEquals(tsKvEntry.getTs(), tsKv.getTs()); | ||
281 | - Assert.assertEquals(1, tsKv.getKvCount()); | ||
282 | - TransportProtos.KeyValueProto keyValue = tsKv.getKvList().get(0); | ||
283 | - Assert.assertEquals(tsKvEntry.getKey(), keyValue.getKey()); | ||
284 | - Assert.assertEquals(tsKvEntry.getValueAsString(), Long.toString(keyValue.getLongV())); | ||
285 | - } | ||
286 | - | ||
287 | - @AfterClass | ||
288 | - public static void destroy() throws InterruptedException { | ||
289 | - uninstallation(); | ||
290 | - edgeImitator.disconnect(); | ||
291 | - } | ||
292 | - | ||
293 | - private static void installation() throws IOException { | ||
294 | - Edge edge = new Edge(); | ||
295 | - edge.setName("Edge1"); | ||
296 | - edge.setType("test"); | ||
297 | - edge.setRoutingKey("routing"); | ||
298 | - edge.setSecret("secret"); | ||
299 | - Edge savedEdge = restClient.saveEdge(edge); | ||
300 | - | ||
301 | - Device device = new Device(); | ||
302 | - device.setName("Edge Device 1"); | ||
303 | - device.setType("test"); | ||
304 | - Device savedDevice = restClient.saveDevice(device); | ||
305 | - restClient.assignDeviceToEdge(savedEdge.getId(), savedDevice.getId()); | ||
306 | - | ||
307 | - Asset asset = new Asset(); | ||
308 | - asset.setName("Edge Asset 1"); | ||
309 | - asset.setType("test"); | ||
310 | - Asset savedAsset = restClient.saveAsset(asset); | ||
311 | - restClient.assignAssetToEdge(savedEdge.getId(), savedAsset.getId()); | ||
312 | - | ||
313 | - ObjectMapper mapper = new ObjectMapper(); | ||
314 | - Class edgeTestClass = EdgeTest.class; | ||
315 | - JsonNode configuration = mapper.readTree(edgeTestClass.getClassLoader().getResourceAsStream("RootRuleChain.json")); | ||
316 | - RuleChain ruleChain = mapper.treeToValue(configuration.get("ruleChain"), RuleChain.class); | ||
317 | - RuleChainMetaData ruleChainMetaData = mapper.treeToValue(configuration.get("metadata"), RuleChainMetaData.class); | ||
318 | - RuleChain savedRuleChain = restClient.saveRuleChain(ruleChain); | ||
319 | - ruleChainMetaData.setRuleChainId(savedRuleChain.getId()); | ||
320 | - restClient.saveRuleChainMetaData(ruleChainMetaData); | ||
321 | - restClient.setRootRuleChain(savedRuleChain.getId()); | ||
322 | - } | ||
323 | - | ||
324 | - private static void uninstallation() { | ||
325 | - Device device = restClient.getTenantDevice("Edge Device 1").get(); | ||
326 | - restClient.deleteDevice(device.getId()); | ||
327 | - | ||
328 | - Asset asset = restClient.getTenantAsset("Edge Asset 1").get(); | ||
329 | - restClient.deleteAsset(asset.getId()); | ||
330 | - | ||
331 | - Edge edge = restClient.getTenantEdge("Edge1").get(); | ||
332 | - restClient.deleteEdge(edge.getId()); | ||
333 | - | ||
334 | - List<RuleChain> ruleChains = restClient.getRuleChains(new TextPageLink(3)).getData(); | ||
335 | - RuleChain oldRoot = ruleChains.stream().filter(ruleChain -> ruleChain.getName().equals("Root Rule Chain")).findAny().get(); | ||
336 | - RuleChain newRoot = ruleChains.stream().filter(ruleChain -> ruleChain.getName().equals("Test Root Rule Chain")).findAny().get(); | ||
337 | - restClient.setRootRuleChain(oldRoot.getId()); | ||
338 | - restClient.deleteRuleChain(newRoot.getId()); | ||
339 | - } | ||
340 | - | ||
341 | -} |
msa/black-box-tests/src/test/resources/RootRuleChain.json
deleted
100644 → 0
1 | -{ | ||
2 | - "ruleChain": { | ||
3 | - "additionalInfo": null, | ||
4 | - "name": "Test Root Rule Chain", | ||
5 | - "type": "CORE", | ||
6 | - "firstRuleNodeId": null, | ||
7 | - "root": false, | ||
8 | - "debugMode": false, | ||
9 | - "configuration": null | ||
10 | - }, | ||
11 | - "metadata": { | ||
12 | - "firstNodeIndex": 4, | ||
13 | - "nodes": [ | ||
14 | - { | ||
15 | - "additionalInfo": { | ||
16 | - "layoutX": 1117, | ||
17 | - "layoutY": 156 | ||
18 | - }, | ||
19 | - "type": "org.thingsboard.rule.engine.edge.TbMsgPushToEdgeNode", | ||
20 | - "name": "Push to edge", | ||
21 | - "debugMode": false, | ||
22 | - "configuration": { | ||
23 | - "version": 0 | ||
24 | - } | ||
25 | - }, | ||
26 | - { | ||
27 | - "additionalInfo": { | ||
28 | - "layoutX": 825, | ||
29 | - "layoutY": 407 | ||
30 | - }, | ||
31 | - "type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", | ||
32 | - "name": "RPC Call Request", | ||
33 | - "debugMode": false, | ||
34 | - "configuration": { | ||
35 | - "timeoutInSeconds": 60 | ||
36 | - } | ||
37 | - }, | ||
38 | - { | ||
39 | - "additionalInfo": { | ||
40 | - "layoutX": 826, | ||
41 | - "layoutY": 327 | ||
42 | - }, | ||
43 | - "type": "org.thingsboard.rule.engine.action.TbLogNode", | ||
44 | - "name": "Log Other", | ||
45 | - "debugMode": false, | ||
46 | - "configuration": { | ||
47 | - "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" | ||
48 | - } | ||
49 | - }, | ||
50 | - { | ||
51 | - "additionalInfo": { | ||
52 | - "layoutX": 827, | ||
53 | - "layoutY": 244 | ||
54 | - }, | ||
55 | - "type": "org.thingsboard.rule.engine.action.TbLogNode", | ||
56 | - "name": "Log RPC from Device", | ||
57 | - "debugMode": false, | ||
58 | - "configuration": { | ||
59 | - "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" | ||
60 | - } | ||
61 | - }, | ||
62 | - { | ||
63 | - "additionalInfo": { | ||
64 | - "layoutX": 347, | ||
65 | - "layoutY": 149 | ||
66 | - }, | ||
67 | - "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", | ||
68 | - "name": "Message Type Switch", | ||
69 | - "debugMode": false, | ||
70 | - "configuration": { | ||
71 | - "version": 0 | ||
72 | - } | ||
73 | - }, | ||
74 | - { | ||
75 | - "additionalInfo": { | ||
76 | - "layoutX": 821, | ||
77 | - "layoutY": 72 | ||
78 | - }, | ||
79 | - "type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode", | ||
80 | - "name": "Save Client Attributes", | ||
81 | - "debugMode": false, | ||
82 | - "configuration": { | ||
83 | - "scope": "CLIENT_SCOPE" | ||
84 | - } | ||
85 | - }, | ||
86 | - { | ||
87 | - "additionalInfo": { | ||
88 | - "layoutX": 824, | ||
89 | - "layoutY": 156 | ||
90 | - }, | ||
91 | - "type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", | ||
92 | - "name": "Save Timeseries", | ||
93 | - "debugMode": false, | ||
94 | - "configuration": { | ||
95 | - "defaultTTL": 0 | ||
96 | - } | ||
97 | - } | ||
98 | - ], | ||
99 | - "connections": [ | ||
100 | - { | ||
101 | - "fromIndex": 4, | ||
102 | - "toIndex": 1, | ||
103 | - "type": "RPC Request to Device" | ||
104 | - }, | ||
105 | - { | ||
106 | - "fromIndex": 4, | ||
107 | - "toIndex": 3, | ||
108 | - "type": "RPC Request from Device" | ||
109 | - }, | ||
110 | - { | ||
111 | - "fromIndex": 4, | ||
112 | - "toIndex": 6, | ||
113 | - "type": "Post telemetry" | ||
114 | - }, | ||
115 | - { | ||
116 | - "fromIndex": 4, | ||
117 | - "toIndex": 5, | ||
118 | - "type": "Post attributes" | ||
119 | - }, | ||
120 | - { | ||
121 | - "fromIndex": 4, | ||
122 | - "toIndex": 2, | ||
123 | - "type": "Other" | ||
124 | - }, | ||
125 | - { | ||
126 | - "fromIndex": 6, | ||
127 | - "toIndex": 0, | ||
128 | - "type": "Success" | ||
129 | - } | ||
130 | - ], | ||
131 | - "ruleChainConnections": null | ||
132 | - } | ||
133 | -} |