From dcdd3478924651b03d304114fb5ee52f0a346d64 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 27 Jun 2022 19:57:29 +0300 Subject: [PATCH] refactoring: tests Device --- .../DefaultTbNotificationEntityService.java | 12 +- .../entitiy/TbNotificationEntityService.java | 4 +- .../device/DefaultTbDeviceService.java | 13 +- .../controller/AbstractNotifyEntityTest.java | 112 ++++++-- .../controller/BaseDeviceControllerTest.java | 261 ++++++++++++++++-- 5 files changed, 338 insertions(+), 64 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 76477c974b..f27199d6bb 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -158,16 +158,16 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS @Override public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, - DeviceCredentials deviceCredentials, SecurityUser user) { + DeviceCredentials deviceCredentials, ActionType actionType, SecurityUser user) { tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null); - sendEntityNotificationMsg(tenantId, deviceId, EdgeEventActionType.CREDENTIALS_UPDATED); - logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials); + sendEntityNotificationMsg(tenantId, deviceId, edgeTypeByActionType(actionType)); + logEntityAction(tenantId, deviceId, device, customerId, actionType, user, deviceCredentials); } @Override public void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, - Device device, Tenant tenant, SecurityUser user, Object... additionalInfo) { - logEntityAction(tenantId, deviceId, device, customerId, ActionType.ASSIGNED_TO_TENANT, user, additionalInfo); + Device device, Tenant tenant, ActionType actionType, SecurityUser user, Object... additionalInfo) { + logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo); pushAssignedFromNotification(tenant, newTenantId, device); } @@ -358,6 +358,8 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS return EdgeEventActionType.ASSIGNED_TO_EDGE; case UNASSIGNED_FROM_EDGE: return EdgeEventActionType.UNASSIGNED_FROM_EDGE; + case CREDENTIALS_UPDATED: + return EdgeEventActionType.CREDENTIALS_UPDATED; default: return null; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 5ce91046d6..e7f90527d4 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -83,10 +83,10 @@ public interface TbNotificationEntityService { List relatedEdgeIds, SecurityUser user, Object... additionalInfo); void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, - DeviceCredentials deviceCredentials, SecurityUser user); + DeviceCredentials deviceCredentials, ActionType actionType, SecurityUser user); void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, - Device device, Tenant tenant, SecurityUser user, Object... additionalInfo); + Device device, Tenant tenant, ActionType actionType, SecurityUser user, Object... additionalInfo); void notifyEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType, SecurityUser user, Object... additionalInfo); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java index 12449f60e2..6547e694fc 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java @@ -27,7 +27,6 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -107,7 +106,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T try { Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(user.getTenantId(), deviceId, customerId)); notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, customerId, savedDevice, - actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, deviceId.toString(), customerId.toString(), customer.getName()); + actionType, edgeTypeByActionType(actionType), user, true, deviceId.toString(), customerId.toString(), customer.getName()); return savedDevice; } catch (Exception e) { @@ -178,13 +177,14 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T public DeviceCredentials updateDeviceCredentials(Device device, DeviceCredentials deviceCredentials, SecurityUser user) throws ThingsboardException { TenantId tenantId = device.getTenantId(); DeviceId deviceId = device.getId(); + ActionType actionType = ActionType.CREDENTIALS_UPDATED; try { DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials)); - notificationEntityService.notifyUpdateDeviceCredentials(tenantId, deviceId, device.getCustomerId(), device, result, user); + notificationEntityService.notifyUpdateDeviceCredentials(tenantId, deviceId, device.getCustomerId(), device, result, actionType, user); return result; } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, - ActionType.CREDENTIALS_UPDATED, user, e, deviceCredentials); + actionType, user, e, deviceCredentials); throw handleException(e); } } @@ -229,17 +229,18 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T public Device assignDeviceToTenant(Device device, Tenant newTenant, SecurityUser user) throws ThingsboardException { TenantId tenantId = device.getTenantId(); TenantId newTenantId = newTenant.getId(); + ActionType actionType = ActionType.ASSIGNED_TO_TENANT; try { Tenant tenant = tenantService.findTenantById(tenantId); Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device); notificationEntityService.notifyAssignDeviceToTenant(tenantId, newTenantId, device.getId(), - assignedDevice.getCustomerId(), assignedDevice, tenant, user, newTenantId.toString(), newTenant.getName()); + assignedDevice.getCustomerId(), assignedDevice, tenant, actionType, user, newTenantId.toString(), newTenant.getName()); return assignedDevice; } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, - ActionType.ASSIGNED_TO_TENANT, user, e, newTenantId.toString()); + actionType, user, e, newTenantId.toString()); throw handleException(e); } } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 1ab5db4681..7757016cbf 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -20,6 +20,7 @@ import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.springframework.boot.test.mock.mockito.SpyBean; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.audit.ActionType; @@ -30,10 +31,13 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Objects; @@ -100,7 +104,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ArgumentMatcher matcherEntityClassEquals = argument -> argument.getClass().equals(entity.getClass()); ArgumentMatcher matcherOriginatorId = argument -> argument.getClass().equals(originatorId.getClass()); testLogEntityActionAdditionalInfo(matcherEntityClassEquals, matcherOriginatorId, tenantId, customerId, userId, userName, actionType, cntTime, - additionalInfo); + extractMatcherAdditionalInfo(additionalInfo)); testPushMsgToRuleEngineTime(originatorId, tenantId, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -113,7 +117,20 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ArgumentMatcher matcherEntityClassEquals = argument -> argument.getClass().equals(entity.getClass()); ArgumentMatcher matcherOriginatorId = argument -> argument.getClass().equals(originatorId.getClass()); testLogEntityActionAdditionalInfo(matcherEntityClassEquals, matcherOriginatorId, tenantId, customerId, userId, userName, actionType, cntTime, - additionalInfo); + extractMatcherAdditionalInfo(additionalInfo)); + testPushMsgToRuleEngineTime(originatorId, tenantId, cntTimeEdge); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(HasName entity, HasName originator, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, ActionType actionTypeEdge, int cntTime, int cntTimeEdge, int cntAdditionalInfo) { + EntityId originatorId = createEntityId_NULL_UUID(originator); + testSendNotificationMsgToEdgeServiceTimeEntityEqAny(tenantId, actionTypeEdge, cntTime); + ArgumentMatcher matcherEntityClassEquals = argument -> argument.getClass().equals(entity.getClass()); + ArgumentMatcher matcherOriginatorId = argument -> argument.getClass().equals(originatorId.getClass()); + testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, customerId, userId, userName, actionType, cntTime, + cntAdditionalInfo); testPushMsgToRuleEngineTime(originatorId, tenantId, cntTimeEdge); Mockito.reset(tbClusterService, auditLogService); } @@ -143,6 +160,18 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.reset(tbClusterService, auditLogService); } + + protected void testNotifyEntityMsgToEdgePushMsgToCoreOneTime(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, Object... additionalInfo) { + int cntTime = 1; + testSendNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); + testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); + tesPushMsgToCoreTime(cntTime); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyEntityEqualsOneTimeError(HasName entity, TenantId tenantId, UserId userId, String userName, ActionType actionType, Exception exp, Object... additionalInfo) { @@ -153,7 +182,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ArgumentMatcher matcherError = argument -> argument.getMessage().contains(exp.getMessage()) & argument.getClass().equals(exp.getClass()); testLogEntityActionErrorAdditionalInfo(matcherEntityEquals, entity_originator_NULL_UUID, tenantId, customer_NULL_UUID, userId, - userName, actionType, 1, matcherError, additionalInfo); + userName, actionType, 1, matcherError, extractMatcherAdditionalInfo(additionalInfo)); testPushMsgToRuleEngineNever(entity_originator_NULL_UUID); } @@ -167,7 +196,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ArgumentMatcher matcherError = argument -> argument.getMessage().contains(exp.getMessage()) & argument.getClass().equals(exp.getClass()); testLogEntityActionErrorAdditionalInfo(matcherEntityIsNull, entity_originator_NULL_UUID, tenantId, customer_NULL_UUID, - userId, userName, actionType, 1, matcherError, additionalInfo); + userId, userName, actionType, 1, matcherError, extractMatcherAdditionalInfo(additionalInfo)); testPushMsgToRuleEngineNever(entity_originator_NULL_UUID); } @@ -179,6 +208,26 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.reset(tbClusterService, auditLogService); } + protected void testNotificationUpdateGatewayOneTime(Device device, Device oldDevice) { + Mockito.verify(gatewayNotificationsService, times(1)).onDeviceUpdated(Mockito.eq(device), Mockito.eq(oldDevice)); + } + + protected void testNotificationUpdateGatewayTime(int cntTimes) { + Mockito.verify(gatewayNotificationsService, times(cntTimes)).onDeviceUpdated(Mockito.any(Device.class), Mockito.isNull()); + } + + protected void testNotificationUpdateGatewayNever() { + Mockito.verify(gatewayNotificationsService, never()).onDeviceUpdated(Mockito.any(Device.class), Mockito.any(Device.class)); + } + + protected void testNotificationDeleteGatewayOneTime(Device device) { + Mockito.verify(gatewayNotificationsService, times(1)).onDeviceDeleted(device); + } + + protected void testNotificationDeleteGatewayNever() { + Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class)); + } + private void testNotificationMsgToEdgeServiceNever(EntityId entityId) { Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(), Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.any()); @@ -219,13 +268,17 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); } + private void tesPushMsgToCoreTime(int cntTime) { + Mockito.verify(tbClusterService, times(cntTime)).pushMsgToCore(Mockito.any(ToDeviceActorNotificationMsg.class), Mockito.isNull()); + } + private void testLogEntityAction(HasName entity, EntityId originatorId, TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, int cntTime, Object... additionalInfo) { ArgumentMatcher matcherEntityEquals = argument -> argument.equals(entity); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testLogEntityActionAdditionalInfo(matcherEntityEquals, matcherOriginatorId, tenantId, customerId, userId, userName, - actionType, cntTime, additionalInfo); + actionType, cntTime, extractMatcherAdditionalInfo(additionalInfo)); } private void testLogEntityActionEntityEqClass(HasName entity, EntityId originatorId, TenantId tenantId, @@ -234,13 +287,13 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ArgumentMatcher matcherEntityEquals = argument -> argument.getClass().equals(entity.getClass()); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testLogEntityActionAdditionalInfo(matcherEntityEquals, matcherOriginatorId, tenantId, customerId, userId, userName, - actionType, cntTime, additionalInfo); + actionType, cntTime, extractMatcherAdditionalInfo(additionalInfo)); } private void testLogEntityActionAdditionalInfo(ArgumentMatcher matcherEntity, ArgumentMatcher matcherOriginatorId, TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType, int cntTime, Object... additionalInfo) { - switch (additionalInfo.length) { + ActionType actionType, int cntTime, List> matcherAdditionalInfos) { + switch (matcherAdditionalInfos.size()) { case 1: Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), @@ -251,7 +304,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.isNull(), - Mockito.eq(extractParameter(String.class, 0, additionalInfo))); + Mockito.argThat(matcherAdditionalInfos.get(0))); break; case 2: Mockito.verify(auditLogService, times(cntTime)) @@ -263,8 +316,8 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.isNull(), - Mockito.eq(extractParameter(String.class, 0, additionalInfo)), - Mockito.eq(extractParameter(String.class, 1, additionalInfo))); + Mockito.argThat(matcherAdditionalInfos.get(0)), + Mockito.argThat(matcherAdditionalInfos.get(1))); break; case 3: Mockito.verify(auditLogService, times(cntTime)) @@ -276,9 +329,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.isNull(), - Mockito.eq(extractParameter(String.class, 0, additionalInfo)), - Mockito.eq(extractParameter(String.class, 1, additionalInfo)), - Mockito.eq(extractParameter(String.class, 2, additionalInfo))); + Mockito.argThat(matcherAdditionalInfos.get(0)), + Mockito.argThat(matcherAdditionalInfos.get(1)), + Mockito.argThat(matcherAdditionalInfos.get(2))); break; default: Mockito.verify(auditLogService, times(cntTime)) @@ -351,8 +404,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { private void testLogEntityActionErrorAdditionalInfo(ArgumentMatcher matcherEntity, EntityId originatorId, TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, - int cntTime, ArgumentMatcher matcherError, Object... additionalInfo) { - switch (additionalInfo.length) { + int cntTime, ArgumentMatcher matcherError, + List> matcherAdditionalInfos) { + switch (matcherAdditionalInfos.size()) { case 1: Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), @@ -363,7 +417,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.argThat(matcherError), - Mockito.eq(extractParameter(String.class, 0, additionalInfo))); + Mockito.argThat(matcherAdditionalInfos.get(0))); break; case 2: Mockito.verify(auditLogService, times(cntTime)) @@ -375,8 +429,8 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.argThat(matcherError), - Mockito.eq(extractParameter(String.class, 0, additionalInfo)), - Mockito.eq(extractParameter(String.class, 1, additionalInfo))); + Mockito.argThat(Mockito.eq(matcherAdditionalInfos.get(0))), + Mockito.argThat(Mockito.eq(matcherAdditionalInfos.get(1)))); case 3: Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), @@ -387,9 +441,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.argThat(matcherEntity), Mockito.eq(actionType), Mockito.argThat(matcherError), - Mockito.eq(extractParameter(String.class, 0, additionalInfo)), - Mockito.eq(extractParameter(String.class, 1, additionalInfo)), - Mockito.eq(extractParameter(String.class, 3, additionalInfo))); + Mockito.argThat(Mockito.eq(matcherAdditionalInfos.get(0))), + Mockito.argThat(Mockito.eq(matcherAdditionalInfos.get(1))), + Mockito.argThat(Mockito.eq(matcherAdditionalInfos.get(2)))); break; default: Mockito.verify(auditLogService, times(cntTime)) @@ -404,10 +458,18 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { } } - private T extractParameter(Class clazz, int index, Object... additionalInfo) { + private List> extractMatcherAdditionalInfo(Object... additionalInfos) { + List> matcherAdditionalInfos = new ArrayList<>(additionalInfos.length); + for (Object additionalInfo : additionalInfos) { + matcherAdditionalInfos.add(argument -> argument.equals(extractParameter(additionalInfo.getClass(), additionalInfo))); + } + return matcherAdditionalInfos; + } + + private T extractParameter(Class clazz, Object additionalInfo) { T result = null; - if (additionalInfo != null && additionalInfo.length > index) { - Object paramObject = additionalInfo[index]; + if (additionalInfo != null) { + Object paramObject = additionalInfo; if (clazz.isInstance(paramObject)) { result = clazz.cast(paramObject); } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java index 8852438b89..1321829683 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java @@ -27,12 +27,14 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceCredentialsId; @@ -44,6 +46,8 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; +import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.model.ModelConstants; import java.util.ArrayList; @@ -99,7 +103,6 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { doDelete("/api/tenant/" + savedTenant.getId().getId()) .andExpect(status().isOk()); - log.debug("afterTest done"); } @Test @@ -107,8 +110,17 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { Device device = new Device(); device.setName("My device"); device.setType("default"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + Device savedDevice = doPost("/api/device", device, Device.class); + Device oldDevice = new Device(savedDevice); + testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED); + testNotificationUpdateGatewayNever(); + Assert.assertNotNull(savedDevice); Assert.assertNotNull(savedDevice.getId()); Assert.assertTrue(savedDevice.getCreatedTime() > 0); @@ -127,9 +139,15 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { Assert.assertNotNull(deviceCredentials.getCredentialsId()); Assert.assertEquals(20, deviceCredentials.getCredentialsId().length()); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + savedDevice.setName("My new device"); doPost("/api/device", savedDevice, Device.class); + testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(), + tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED); + testNotificationUpdateGatewayOneTime(savedDevice, oldDevice); + Device foundDevice = doGet("/api/device/" + savedDevice.getId().getId(), Device.class); Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); } @@ -139,13 +157,35 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { Device device = new Device(); device.setName(RandomStringUtils.randomAlphabetic(300)); device.setType("default"); - doPost("/api/device", device).andExpect(statusReason(containsString("length of name must be equal or less than 255"))); - device.setName("Normal Name"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + String msgError = "length of name must be equal or less than 255"; + doPost("/api/device", device).andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); + testNotificationUpdateGatewayNever(); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + device.setTenantId(savedTenant.getId()); + msgError = "length of type must be equal or less than 255"; device.setType(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/device", device).andExpect(statusReason(containsString("length of type must be equal or less than 255"))); + doPost("/api/device", device).andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); + testNotificationUpdateGatewayNever(); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + msgError = "length of label must be equal or less than 255"; device.setType("Normal type"); device.setLabel(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/device", device).andExpect(statusReason(containsString("length of label must be equal or less than 255"))); + doPost("/api/device", device).andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); + testNotificationUpdateGatewayNever(); } @Test @@ -155,7 +195,22 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/device", savedDevice, Device.class, status().isNotFound()); + + testNotifyEntityNever(savedDevice.getId(), savedDevice); + testNotificationUpdateGatewayNever(); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + doDelete("/api/device/" + savedDevice.getId().getId().toString()) + .andExpect(status().isNotFound()); + + testNotifyEntityNever(savedDevice.getId(), savedDevice); + testNotificationUpdateGatewayNever(); + deleteDifferentTenant(); } @@ -173,12 +228,24 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { @Test public void testFindDeviceTypesByTenantId() throws Exception { List devices = new ArrayList<>(); - for (int i = 0; i < 3; i++) { + + int cntEntity = 3; + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + for (int i = 0; i < cntEntity; i++) { Device device = new Device(); device.setName("My device B" + i); device.setType("typeB"); devices.add(doPost("/api/device", device, Device.class)); } + + testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Device(), new Device(), + savedTenant.getId(), + tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED, cntEntity); + testNotificationUpdateGatewayNever(); + for (int i = 0; i < 7; i++) { Device device = new Device(); device.setName("My device C" + i); @@ -192,7 +259,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { devices.add(doPost("/api/device", device, Device.class)); } List deviceTypes = doGetTyped("/api/device/types", - new TypeReference>() { + new TypeReference<>() { }); Assert.assertNotNull(deviceTypes); @@ -211,10 +278,14 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doDelete("/api/device/" + savedDevice.getId().getId()) .andExpect(status().isOk()); -// gatewayNotificationsService.onDeviceDeleted(device); + testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(), + tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.DELETED, savedDevice.getId().getId().toString()); + testNotificationDeleteGatewayOneTime(savedDevice); doGet("/api/device/" + savedDevice.getId().getId()) .andExpect(status().isNotFound()); @@ -224,17 +295,33 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { public void testSaveDeviceWithEmptyType() throws Exception { Device device = new Device(); device.setName("My device"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + Device savedDevice = doPost("/api/device", device, Device.class); Assert.assertEquals("default", savedDevice.getType()); + + testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED); + testNotificationUpdateGatewayNever(); } @Test public void testSaveDeviceWithEmptyName() throws Exception { Device device = new Device(); device.setType("default"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + String msgError = "Device name should be specified"; doPost("/api/device", device) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Device name should be specified"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); + testNotificationUpdateGatewayNever(); } @Test @@ -248,17 +335,33 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { customer.setTitle("My customer"); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + Device assignedDevice = doPost("/api/customer/" + savedCustomer.getId().getId() + "/device/" + savedDevice.getId().getId(), Device.class); Assert.assertEquals(savedCustomer.getId(), assignedDevice.getCustomerId()); + testNotifyEntityAllOneTime(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), savedTenant.getId(), + savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, + assignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(), + savedCustomer.getTitle()); + testNotificationUpdateGatewayNever(); + Device foundDevice = doGet("/api/device/" + savedDevice.getId().getId(), Device.class); Assert.assertEquals(savedCustomer.getId(), foundDevice.getCustomerId()); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + Device unassignedDevice = doDelete("/api/customer/device/" + savedDevice.getId().getId(), Device.class); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedDevice.getCustomerId().getId()); + testNotifyEntityAllOneTime(unassignedDevice, unassignedDevice.getId(), unassignedDevice.getId(), savedTenant.getId(), + savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, + unassignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(), + savedCustomer.getTitle()); + testNotificationDeleteGatewayNever(); + foundDevice = doGet("/api/device/" + savedDevice.getId().getId(), Device.class); Assert.assertEquals(ModelConstants.NULL_UUID, foundDevice.getCustomerId().getId()); } @@ -269,9 +372,15 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { device.setName("My device"); device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/customer/" + Uuids.timeBased().toString() + "/device/" + savedDevice.getId().getId()) .andExpect(status().isNotFound()); + + testNotifyEntityNever(savedDevice.getId(), savedDevice); + testNotificationUpdateGatewayNever(); } @Test @@ -290,7 +399,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { tenantAdmin2.setFirstName("Joe"); tenantAdmin2.setLastName("Downs"); - tenantAdmin2 = createUserAndLogin(tenantAdmin2, "testPassword1"); + createUserAndLogin(tenantAdmin2, "testPassword1"); Customer customer = new Customer(); customer.setTitle("Different customer"); @@ -303,10 +412,15 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/customer/" + savedCustomer.getId().getId() + "/device/" + savedDevice.getId().getId()) .andExpect(status().isForbidden()); + testNotifyEntityNever(savedDevice.getId(), savedDevice); + testNotificationUpdateGatewayNever(); + loginSysAdmin(); doDelete("/api/tenant/" + savedTenant2.getId().getId()) @@ -335,9 +449,16 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { Assert.assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId()); deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); deviceCredentials.setCredentialsId("access_token"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/device/credentials", deviceCredentials) .andExpect(status().isOk()); + testNotifyEntityMsgToEdgePushMsgToCoreOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(), + tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.CREDENTIALS_UPDATED, deviceCredentials); + testNotificationUpdateGatewayNever(); + DeviceCredentials foundDeviceCredentials = doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class); @@ -347,8 +468,14 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { @Test public void testSaveDeviceCredentialsWithEmptyDevice() throws Exception { DeviceCredentials deviceCredentials = new DeviceCredentials(); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/device/credentials", deviceCredentials) .andExpect(status().isBadRequest()); + + testNotifyEntityNever(deviceCredentials.getDeviceId(), new Device()); + testNotificationUpdateGatewayNever(); } @Test @@ -360,9 +487,18 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { DeviceCredentials deviceCredentials = doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class); deviceCredentials.setCredentialsType(null); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + String msgError = "Device credentials type should be specified"; doPost("/api/device/credentials", deviceCredentials) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Device credentials type should be specified"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityIsNullOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.CREDENTIALS_UPDATED, + new DataValidationException(msgError), deviceCredentials); + testNotificationUpdateGatewayNever(); } @Test @@ -374,9 +510,18 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { DeviceCredentials deviceCredentials = doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class); deviceCredentials.setCredentialsId(null); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + String msgError = "Device credentials id should be specified"; doPost("/api/device/credentials", deviceCredentials) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Device credentials id should be specified"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityIsNullOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.CREDENTIALS_UPDATED, + new DeviceCredentialsValidationException(msgError), deviceCredentials); + testNotificationUpdateGatewayNever(); } @Test @@ -392,9 +537,18 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { newDeviceCredentials.setDeviceId(deviceCredentials.getDeviceId()); newDeviceCredentials.setCredentialsType(deviceCredentials.getCredentialsType()); newDeviceCredentials.setCredentialsId(deviceCredentials.getCredentialsId()); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + String msgError = "Unable to update non-existent device credentials"; doPost("/api/device/credentials", newDeviceCredentials) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Unable to update non-existent device credentials"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityIsNullOneTimeError(device, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.CREDENTIALS_UPDATED, + new DeviceCredentialsValidationException(msgError), newDeviceCredentials); + testNotificationUpdateGatewayNever(); } @Test @@ -406,26 +560,40 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { DeviceCredentials deviceCredentials = doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class); deviceCredentials.setDeviceId(new DeviceId(Uuids.timeBased())); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/device/credentials", deviceCredentials) .andExpect(status().isNotFound()); + + testNotifyEntityNever(savedDevice.getId(), savedDevice); + testNotificationUpdateGatewayNever(); } @Test public void testFindTenantDevices() throws Exception { log.debug("testFindTenantDevices"); - futures = new ArrayList<>(178); - for (int i = 0; i < 178; i++) { + int cntEntity = 178; + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + futures = new ArrayList<>(cntEntity); + for (int i = 0; i < cntEntity; i++) { Device device = new Device(); device.setName("Device" + i); device.setType("default"); futures.add(executor.submit(() -> doPost("/api/device", device, Device.class))); } - log.debug("await create devices"); + List devices = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); - log.debug("start reading"); - List loadedDevices = new ArrayList<>(178); + testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Device(), new Device(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED, cntEntity); + testNotificationUpdateGatewayNever(); + + List loadedDevices = new ArrayList<>(cntEntity); PageLink pageLink = new PageLink(23); do { pageData = doGetTypedWithPageLink("/api/tenant/devices?", @@ -437,11 +605,16 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { } } while (pageData.hasNext()); - log.debug("asserting"); assertThat(devices).containsExactlyInAnyOrderElementsOf(loadedDevices); - log.debug("delete devices async"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + deleteEntitiesAsync("/api/device/", loadedDevices, executor).get(TIMEOUT, TimeUnit.SECONDS); - log.debug("done"); + + testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new Device(), new Device(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.DELETED, cntEntity, 1); + testNotificationUpdateGatewayNever(); } @Test @@ -606,9 +779,12 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { customer.setTitle("Test customer"); customer = doPost("/api/customer", customer, Customer.class); CustomerId customerId = customer.getId(); + int cntEntity = 128; - futures = new ArrayList<>(128); - for (int i = 0; i < 128; i++) { + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + + futures = new ArrayList<>(cntEntity); + for (int i = 0; i < cntEntity; i++) { Device device = new Device(); device.setName("Device" + i); device.setType("default"); @@ -620,7 +796,12 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { List devices = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); - List loadedDevices = new ArrayList<>(128); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Device(), new Device(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity * 2); + testNotificationUpdateGatewayNever(); + + List loadedDevices = new ArrayList<>(cntEntity); PageLink pageLink = new PageLink(23); do { pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId() + "/devices?", @@ -633,9 +814,14 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { assertThat(devices).containsExactlyInAnyOrderElementsOf(loadedDevices); - log.debug("delete devices async"); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + deleteEntitiesAsync("/api/customer/device/", loadedDevices, executor).get(TIMEOUT, TimeUnit.SECONDS); - log.debug("done"); + + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Device(), new Device(), + savedTenant.getId(), customerId, tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 3); + testNotificationUpdateGatewayNever(); } @Test @@ -845,10 +1031,18 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { createUserAndLogin(user, "testPassword1"); login("tenant2@thingsboard.org", "testPassword1"); + + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + Device assignedDevice = doPost("/api/tenant/" + savedDifferentTenant.getId().getId() + "/device/" + savedDevice.getId().getId(), Device.class); doGet("/api/device/" + assignedDevice.getId().getId(), Device.class, status().isNotFound()); + testNotifyEntityOneTimeMsgToEdgeServiceNever(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ASSIGNED_TO_TENANT, savedDifferentTenant.getId().getId().toString(), savedDifferentTenant.getTitle()); + testNotificationUpdateGatewayNever(); + login("tenant9@thingsboard.org", "testPassword1"); Device foundDevice1 = doGet("/api/device/" + assignedDevice.getId().getId(), Device.class); @@ -871,17 +1065,32 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { device.setType("default"); Device savedDevice = doPost("/api/device", device, Device.class); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doPost("/api/edge/" + savedEdge.getId().getId() + "/device/" + savedDevice.getId().getId(), Device.class); + testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ASSIGNED_TO_EDGE, + savedDevice.getId().getId().toString(), savedEdge.getId().getId().toString(), savedEdge.getName()); + testNotificationUpdateGatewayNever(); + pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/devices?", PAGE_DATA_DEVICE_TYPE_REF, new PageLink(100)); Assert.assertEquals(1, pageData.getData().size()); + Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); + doDelete("/api/edge/" + savedEdge.getId().getId() + "/device/" + savedDevice.getId().getId(), Device.class); + testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.UNASSIGNED_FROM_EDGE, savedDevice.getId().getId().toString(), savedEdge.getId().getId().toString(), savedEdge.getName()); + testNotificationUpdateGatewayNever(); + pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/devices?", PAGE_DATA_DEVICE_TYPE_REF, new PageLink(100));