From 3c3da12e29a0b89d6188a7c7a01cfc41c872f9b3 Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Fri, 3 Jul 2020 15:42:07 +0300 Subject: [PATCH 1/6] added EdgeEventController --- .../controller/EdgeEventController.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java new file mode 100644 index 0000000000..b58d1eeb71 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java @@ -0,0 +1,53 @@ +package org.thingsboard.server.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.edge.EdgeEventService; +import org.thingsboard.server.queue.util.TbCoreComponent; + +@Slf4j +@RestController +@TbCoreComponent +@RequestMapping("/api") +public class EdgeEventController extends BaseController { + + @Autowired + private EdgeEventService edgeEventService; + + public static final String EDGE_ID = "edgeId"; + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/edge/{edgeId}/events", method = RequestMethod.GET) + @ResponseBody + public TimePageData getEdgeEvents( + @PathVariable(EDGE_ID) String strEdgeId, + @RequestParam int limit, + @RequestParam(required = false) Long startTime, + @RequestParam(required = false) Long endTime, + @RequestParam(required = false, defaultValue = "false") boolean ascOrder, + @RequestParam(required = false) String offset) throws ThingsboardException { + checkParameter(EDGE_ID, strEdgeId); + try { + TenantId tenantId = getCurrentUser().getTenantId(); + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); + TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); + return checkNotNull(edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } +} + From 0cf800d0a87401aadef991aa527b0c47c23cfaa1 Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Mon, 6 Jul 2020 12:25:15 +0300 Subject: [PATCH 2/6] test, license --- .../controller/EdgeEventController.java | 15 +++ .../BaseEdgeEventControllerTest.java | 127 ++++++++++++++++++ .../nosql/EdgeEventControllerNoSqlTest.java | 23 ++++ .../sql/EdgeEventControllerSqlTest.java | 23 ++++ 4 files changed, 188 insertions(+) create mode 100644 application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java create mode 100644 application/src/test/java/org/thingsboard/server/controller/nosql/EdgeEventControllerNoSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/controller/sql/EdgeEventControllerSqlTest.java diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java index b58d1eeb71..8558c194b2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java @@ -1,3 +1,18 @@ +/** + * 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.controller; import lombok.extern.slf4j.Slf4j; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java new file mode 100644 index 0000000000..6c78aa1626 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java @@ -0,0 +1,127 @@ +/** + * 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.controller; + +import com.fasterxml.jackson.core.type.TypeReference; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.security.Authority; + +import java.util.List; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class BaseEdgeEventControllerTest extends AbstractControllerTest { + + private Tenant savedTenant; + private TenantId tenantId; + private User tenantAdmin; + + @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"); + } + + @After + public void afterTest() throws Exception { + loginSysAdmin(); + + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) + .andExpect(status().isOk()); + } + + @Test + public void testGetEdgeEvents() throws Exception { + Edge edge = constructEdge("TestEdge", "default"); + edge = doPost("/api/edge", edge, Edge.class); + + Device device = constructDevice("TestDevice", "default"); + Asset asset = constructAsset("TestAsset", "default"); + + Device savedDevice = doPost("/api/device", device, Device.class); + Asset savedAsset = doPost("/api/asset", asset, Asset.class); + + doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); + doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); + + Thread.sleep(500); + + List edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", + new TypeReference>() { + }, new TimePageLink(5)).getData(); + + Assert.assertFalse(edgeEvents.isEmpty()); + Assert.assertEquals(3, edgeEvents.size()); + Assert.assertEquals(edgeEvents.get(0).getEdgeEventType(), EdgeEventType.DEVICE); + Assert.assertEquals(edgeEvents.get(1).getEdgeEventType(), EdgeEventType.ASSET); + Assert.assertEquals(edgeEvents.get(2).getEdgeEventType(), EdgeEventType.RULE_CHAIN); + } + + private Edge constructEdge(String name, String type) { + Edge edge = new Edge(); + edge.setTenantId(tenantId); + edge.setName(name); + edge.setType(type); + edge.setSecret(RandomStringUtils.randomAlphanumeric(20)); + edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20)); + return edge; + } + + private Device constructDevice(String name, String type) { + Device device = new Device(); + device.setName(name); + device.setType(type); + return device; + } + + private Asset constructAsset(String name, String type) { + Asset asset = new Asset(); + asset.setName(name); + asset.setType(type); + return asset; + } + + +} diff --git a/application/src/test/java/org/thingsboard/server/controller/nosql/EdgeEventControllerNoSqlTest.java b/application/src/test/java/org/thingsboard/server/controller/nosql/EdgeEventControllerNoSqlTest.java new file mode 100644 index 0000000000..8cb88c83f6 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/nosql/EdgeEventControllerNoSqlTest.java @@ -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.controller.nosql; + +import org.thingsboard.server.controller.BaseEdgeEventControllerTest; +import org.thingsboard.server.dao.service.DaoNoSqlTest; + +@DaoNoSqlTest +public class EdgeEventControllerNoSqlTest extends BaseEdgeEventControllerTest { +} diff --git a/application/src/test/java/org/thingsboard/server/controller/sql/EdgeEventControllerSqlTest.java b/application/src/test/java/org/thingsboard/server/controller/sql/EdgeEventControllerSqlTest.java new file mode 100644 index 0000000000..84b37970ed --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/sql/EdgeEventControllerSqlTest.java @@ -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.controller.sql; + +import org.thingsboard.server.controller.BaseEdgeEventControllerTest; +import org.thingsboard.server.dao.service.DaoSqlTest; + +@DaoSqlTest +public class EdgeEventControllerSqlTest extends BaseEdgeEventControllerTest { +} From 51bfc91f14ae835e35489a9f6c28d40b093acfdf Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Mon, 6 Jul 2020 19:12:21 +0300 Subject: [PATCH 3/6] fixes in EdgeEventControllerTest and in relation processing --- .../paho27873734058141-tcplocalhost1883/.lck | 0 .../edge/DefaultEdgeNotificationService.java | 5 ++-- .../BaseEdgeEventControllerTest.java | 30 ++++++++++++++----- 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 application/paho27873734058141-tcplocalhost1883/.lck diff --git a/application/paho27873734058141-tcplocalhost1883/.lck b/application/paho27873734058141-tcplocalhost1883/.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index eb5fcdad9e..47c6ece48f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.edge; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.Futures; @@ -245,8 +246,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { }, dbCallbackExecutorService); } - private void processRelation(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - EntityRelation relation = mapper.convertValue(edgeNotificationMsg.getEntityBody(), EntityRelation.class); + private void processRelation(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) throws JsonProcessingException { + EntityRelation relation = mapper.readValue(edgeNotificationMsg.getEntityBody(), EntityRelation.class); if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) && !relation.getTo().getEntityType().equals(EntityType.EDGE)) { List>> futures = new ArrayList<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java index 6c78aa1626..72e6f149ec 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java @@ -16,12 +16,16 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.web.client.RestTemplate; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -32,18 +36,23 @@ import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TimePageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.security.Authority; import java.util.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +@Slf4j public class BaseEdgeEventControllerTest extends AbstractControllerTest { private Tenant savedTenant; private TenantId tenantId; private User tenantAdmin; + private RestTemplate restTemplate; + @Before public void beforeTest() throws Exception { loginSysAdmin(); @@ -78,25 +87,31 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { edge = doPost("/api/edge", edge, Edge.class); Device device = constructDevice("TestDevice", "default"); - Asset asset = constructAsset("TestAsset", "default"); - Device savedDevice = doPost("/api/device", device, Device.class); - Asset savedAsset = doPost("/api/asset", asset, Asset.class); doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); + + Asset asset = constructAsset("TestAsset", "default"); + Asset savedAsset = doPost("/api/asset", asset, Asset.class); + doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); - Thread.sleep(500); + EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); + + doPost("/api/relation", relation); + + Thread.sleep(1000); List edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", new TypeReference>() { }, new TimePageLink(5)).getData(); Assert.assertFalse(edgeEvents.isEmpty()); - Assert.assertEquals(3, edgeEvents.size()); - Assert.assertEquals(edgeEvents.get(0).getEdgeEventType(), EdgeEventType.DEVICE); + Assert.assertEquals(4, edgeEvents.size()); + Assert.assertEquals(edgeEvents.get(0).getEdgeEventType(), EdgeEventType.RELATION); Assert.assertEquals(edgeEvents.get(1).getEdgeEventType(), EdgeEventType.ASSET); - Assert.assertEquals(edgeEvents.get(2).getEdgeEventType(), EdgeEventType.RULE_CHAIN); + Assert.assertEquals(edgeEvents.get(2).getEdgeEventType(), EdgeEventType.DEVICE); + Assert.assertEquals(edgeEvents.get(3).getEdgeEventType(), EdgeEventType.RULE_CHAIN); } private Edge constructEdge(String name, String type) { @@ -123,5 +138,4 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { return asset; } - } From 9e124cf9b174fd509b29a91a77de0403f3a67270 Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Mon, 6 Jul 2020 19:18:15 +0300 Subject: [PATCH 4/6] deleted .lck file --- application/paho27873734058141-tcplocalhost1883/.lck | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 application/paho27873734058141-tcplocalhost1883/.lck diff --git a/application/paho27873734058141-tcplocalhost1883/.lck b/application/paho27873734058141-tcplocalhost1883/.lck deleted file mode 100644 index e69de29bb2..0000000000 From 1fe848b04248da55e9665017a7322a2ee83a0984 Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Mon, 6 Jul 2020 19:32:10 +0300 Subject: [PATCH 5/6] deleted unused imports --- .../server/controller/BaseEdgeEventControllerTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java index 72e6f149ec..ac5ea446d2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java @@ -16,15 +16,12 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.web.client.RestTemplate; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; @@ -41,7 +38,6 @@ import org.thingsboard.server.common.data.security.Authority; import java.util.List; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j From 4621d28e33c83122a1d6459cb3f4231dde2b6e0f Mon Sep 17 00:00:00 2001 From: Bohdan Smetaniuk Date: Mon, 6 Jul 2020 19:34:31 +0300 Subject: [PATCH 6/6] deleted unused fields --- .../server/controller/BaseEdgeEventControllerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java index ac5ea446d2..b079be6357 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java @@ -22,7 +22,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.web.client.RestTemplate; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -47,8 +46,6 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { private TenantId tenantId; private User tenantAdmin; - private RestTemplate restTemplate; - @Before public void beforeTest() throws Exception { loginSysAdmin();