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 a5af165699..b5c26e006c 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2022 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 - * + *

+ * 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. @@ -69,7 +69,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { int cntTime = 1; - testSendNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); @@ -96,8 +96,8 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { } protected void testNotifyEntityAllManyRelation(EntityRelation relation, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType, int cntTime) { + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION), Mockito.eq(edgeTypeByActionType(actionType))); @@ -113,7 +113,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { int cntTime = 1; - testSendNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityActionEntityEqClass(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); @@ -122,7 +122,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { protected void testNotifyEntityNeverMsgToEdgeServiceOneTime(HasName entity, EntityId entityId, TenantId tenantId, ActionType actionType) { - testSendNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, 1); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, 1); testLogEntityActionNever(entityId, entity); testPushMsgToRuleEngineNever(entityId); Mockito.reset(tbClusterService, auditLogService); @@ -132,7 +132,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { int cntTime = 1; - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); if (ActionType.RELATIONS_DELETED.equals(actionType)) { @@ -148,7 +148,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ActionType actionType, int cntTime, Object... additionalInfo) { EntityId entityId = createEntityId_NULL_UUID(entity); EntityId originatorId = createEntityId_NULL_UUID(originator); - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); 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, @@ -189,7 +189,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ActionType actionType, int cntTime, int cntAdditionalInfo) { EntityId entityId = createEntityId_NULL_UUID(entity); EntityId originatorId = createEntityId_NULL_UUID(originator); - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); 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, @@ -202,7 +202,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { int cntTime = 1; - testSendNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); @@ -214,7 +214,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { int cntTime = 1; - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); @@ -222,26 +222,28 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.reset(tbClusterService, auditLogService); } - protected void testNotifyEntityBroadcastEntityStateChangeEventManyMsgToEdgeServiceNever(HasName entity, HasName originator, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType, int cntTime, int cntAdditionalInfo) { + protected void testNotifyEntityBroadcastEntityStateChangeEventMany(HasName entity, HasName originator, + TenantId tenantId, CustomerId customerId, + UserId userId, String userName, ActionType actionType, + ActionType actionTypeEdge, + int cntTime, int cntTimeEdge, int cntTimeRuleEngine, + int cntAdditionalInfo) { EntityId entityId = createEntityId_NULL_UUID(entity); EntityId originatorId = createEntityId_NULL_UUID(originator); - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionTypeEdge, cntTimeEdge); 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(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTimeRuleEngine); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); - 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); + testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); tesPushMsgToCoreTime(cntTime); Mockito.reset(tbClusterService, auditLogService); @@ -252,7 +254,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Object... additionalInfo) { CustomerId customer_NULL_UUID = (CustomerId) EntityIdFactory.getByTypeAndUuid(EntityType.CUSTOMER, ModelConstants.NULL_UUID); EntityId entity_originator_NULL_UUID = createEntityId_NULL_UUID(entity); - testNotificationMsgToEdgeServiceNever(entity_originator_NULL_UUID); + testNotificationMsgToEdgeServiceNeverWithActionType(entity_originator_NULL_UUID, actionType); ArgumentMatcher matcherEntityEquals = argument -> argument.getClass().equals(entity.getClass()); ArgumentMatcher matcherError = argument -> argument.getMessage().contains(exp.getMessage()) & argument.getClass().equals(exp.getClass()); @@ -266,7 +268,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Object... additionalInfo) { CustomerId customer_NULL_UUID = (CustomerId) EntityIdFactory.getByTypeAndUuid(EntityType.CUSTOMER, ModelConstants.NULL_UUID); EntityId entity_originator_NULL_UUID = createEntityId_NULL_UUID(entity); - testNotificationMsgToEdgeServiceNever(entity_originator_NULL_UUID); + testNotificationMsgToEdgeServiceNeverWithActionType(entity_originator_NULL_UUID, actionType); ArgumentMatcher matcherEntityIsNull = Objects::isNull; ArgumentMatcher matcherError = argument -> argument.getMessage().contains(exp.getMessage()) & argument.getClass().equals(exp.getClass()); @@ -299,6 +301,13 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class)); } + private void testNotificationMsgToEdgeServiceNeverWithActionType(EntityId entityId, ActionType actionType) { + EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? + EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); + Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(), + Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.eq(edgeEventActionType)); + } + private void testNotificationMsgToEdgeServiceNever(EntityId entityId) { Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(), Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.any()); @@ -317,16 +326,23 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any()); } + protected void testBroadcastEntityStateChangeEventNever(EntityId entityId) { + Mockito.verify(tbClusterService, never()).broadcastEntityStateChangeEvent(Mockito.any(), + Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); + } + private void testPushMsgToRuleEngineTime(ArgumentMatcher matcherOriginatorId, TenantId tenantId, int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).pushMsgToRuleEngine(Mockito.eq(tenantId), Mockito.argThat(matcherOriginatorId), Mockito.any(TbMsg.class), Mockito.isNull()); } - private void testSendNotificationMsgToEdgeServiceTime(EntityId entityId, TenantId tenantId, ActionType actionType, int cntTime) { + private void testNotificationMsgToEdgeServiceTime(EntityId entityId, TenantId tenantId, ActionType actionType, int cntTime) { EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); + ArgumentMatcher matcherEntityId = cntTime == 1 ? argument -> argument.equals(entityId) : + argument -> argument.getClass().equals(entityId.getClass()); Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), - Mockito.any(), Mockito.eq(entityId), Mockito.any(), Mockito.isNull(), + Mockito.any(), Mockito.argThat(matcherEntityId), Mockito.any(), Mockito.isNull(), Mockito.eq(edgeEventActionType)); } @@ -336,7 +352,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.eq(edgeTypeByActionType(actionType))); } - private void testBroadcastEntityStateChangeEventTime(EntityId entityId, TenantId tenantId, int cntTime) { + protected void testBroadcastEntityStateChangeEventTime(EntityId entityId, TenantId tenantId, int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).broadcastEntityStateChangeEvent(Mockito.eq(tenantId), Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); } 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 dc5f9efa23..273ec4f82f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java @@ -113,6 +113,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { 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); @@ -248,8 +249,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { } testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Device(), new Device(), - savedTenant.getId(), - tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, cntEntity); testNotificationUpdateGatewayNever(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java index 08a157484f..f78fd6ce8b 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java @@ -357,7 +357,6 @@ public abstract class BaseEntityRelationControllerTest extends AbstractControlle .andExpect(statusReason(containsString("Requested item wasn't found!"))); testNotifyEntityNever(mainDevice.getId(), null); - } @Test @@ -570,7 +569,6 @@ public abstract class BaseEntityRelationControllerTest extends AbstractControlle .andExpect(status().isNotFound()) .andExpect(statusReason(containsString(msgErrorNoFound("Device", relation.getFrom().getId().toString())))); - deleteDifferentTenant(); } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java index 615914c6d7..84e617f3fa 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java @@ -32,6 +32,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.ResultActions; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -41,6 +42,7 @@ import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; 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.objects.AttributesEntityView; @@ -52,6 +54,7 @@ import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.model.ModelConstants; import java.util.ArrayList; @@ -92,7 +95,6 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @Before public void beforeTest() throws Exception { - log.debug("beforeTest"); executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); loginTenantAdmin(); @@ -126,6 +128,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @Test public void testSaveEntityView() throws Exception { String name = "Test entity view"; + + Mockito.reset(tbClusterService, auditLogService); + EntityView savedView = getNewSavedEntityView(name); Assert.assertNotNull(savedView); @@ -140,6 +145,10 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes assertEquals(savedView, foundEntityView); + testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(foundEntityView, foundEntityView.getId(), foundEntityView.getId(), + tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ADDED); + savedView.setName("New test entity view"); doPost("/api/entityView", savedView, EntityView.class); @@ -147,23 +156,57 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes assertEquals(savedView, foundEntityView); - doGet("/api/tenant/entityViews?entityViewName=" + name, EntityView.class, status().isNotFound()); + testBroadcastEntityStateChangeEventTime(foundEntityView.getId(), tenantId, 1); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundEntityView, foundEntityView, + tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.UPDATED, ActionType.UPDATED, 1, 1, 5); + + doGet("/api/tenant/entityViews?entityViewName=" + name) + .andExpect(status().isNotFound()) + .andExpect(statusReason(containsString("Requested item wasn't found!"))); } @Test public void testSaveEntityViewWithViolationOfValidation() throws Exception { EntityView entityView = createEntityView(RandomStringUtils.randomAlphabetic(300), 0, 0); - doPost("/api/entityView", entityView).andExpect(statusReason(containsString("length of name must be equal or less than 255"))); + + Mockito.reset(tbClusterService, auditLogService); + + String msgError = msgErrorFieldLength("name"); + doPost("/api/entityView", entityView) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(entityView, + tenantId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); + Mockito.reset(tbClusterService, auditLogService); + entityView.setName("Normal name"); + msgError = msgErrorFieldLength("type"); entityView.setType(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/entityView", entityView).andExpect(statusReason(containsString("length of type must be equal or less than 255"))); + doPost("/api/entityView", entityView) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(entityView, + tenantId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test public void testUpdateEntityViewFromDifferentTenant() throws Exception { EntityView savedView = getNewSavedEntityView("Test entity view"); loginDifferentTenant(); - doPost("/api/entityView", savedView, EntityView.class, status().isForbidden()); + + Mockito.reset(tbClusterService, auditLogService); + + doPost("/api/entityView", savedView) + .andExpect(status().isForbidden()) + .andExpect(statusReason(containsString(msgErrorPermission))); + + testNotifyEntityNever(savedView.getId(), savedView); + deleteDifferentTenant(); } @@ -174,20 +217,36 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes view.setCustomerId(customer.getId()); EntityView savedView = doPost("/api/entityView", view, EntityView.class); - doDelete("/api/entityView/" + savedView.getId().getId().toString()) + Mockito.reset(tbClusterService, auditLogService); + + String entityIdStr = savedView.getId().getId().toString(); + doDelete("/api/entityView/" + entityIdStr) .andExpect(status().isOk()); - doGet("/api/entityView/" + savedView.getId().getId().toString()) - .andExpect(status().isNotFound()); + testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedView, savedView.getId(), savedView.getId(), + tenantId, view.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.DELETED, entityIdStr); + + doGet("/api/entityView/" + entityIdStr) + .andExpect(status().isNotFound()) + .andExpect(statusReason(containsString(msgErrorNoFound("Entity view",entityIdStr)))); } @Test public void testSaveEntityViewWithEmptyName() throws Exception { EntityView entityView = new EntityView(); entityView.setType("default"); + + Mockito.reset(tbClusterService, auditLogService); + + String msgError = "Entity view name " + msgErrorShouldBeSpecified; doPost("/api/entityView", entityView) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Entity view name should be specified!"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(entityView, + tenantId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test @@ -195,8 +254,16 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes EntityView view = getNewSavedEntityView("Test entity view"); Customer savedCustomer = doPost("/api/customer", getNewCustomer("My customer"), Customer.class); view.setCustomerId(savedCustomer.getId()); + + Mockito.reset(tbClusterService, auditLogService); + EntityView savedView = doPost("/api/entityView", view, EntityView.class); + testBroadcastEntityStateChangeEventTime(savedView.getId(), tenantId, 1); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(savedView, savedView, + tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.UPDATED, ActionType.UPDATED, 1, 1, 5); + EntityView assignedView = doPost( "/api/customer/" + savedCustomer.getId().getId().toString() + "/entityView/" + savedView.getId().getId().toString(), EntityView.class); @@ -205,18 +272,38 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); assertEquals(savedCustomer.getId(), foundView.getCustomerId()); + testBroadcastEntityStateChangeEventNever(foundView.getId()); + testNotifyEntityAllOneTime(foundView, foundView.getId(), foundView.getId(), + tenantId, foundView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ASSIGNED_TO_CUSTOMER, + foundView.getId().getId().toString(), foundView.getCustomerId().getId().toString(), savedCustomer.getTitle()); + EntityView unAssignedView = doDelete("/api/customer/entityView/" + savedView.getId().getId().toString(), EntityView.class); assertEquals(ModelConstants.NULL_UUID, unAssignedView.getCustomerId().getId()); foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId()); + + testBroadcastEntityStateChangeEventNever(foundView.getId()); + testNotifyEntityAllOneTime(unAssignedView, savedView.getId(), savedView.getId(), + tenantId, savedView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.UNASSIGNED_FROM_CUSTOMER, + savedView.getCustomerId().getId().toString(), savedCustomer.getTitle()); } @Test public void testAssignEntityViewToNonExistentCustomer() throws Exception { EntityView savedView = getNewSavedEntityView("Test entity view"); - doPost("/api/customer/" + Uuids.timeBased().toString() + "/device/" + savedView.getId().getId().toString()) - .andExpect(status().isNotFound()); + + Mockito.reset(tbClusterService, auditLogService); + + String customerIdStr = Uuids.timeBased().toString(); + String msgError = msgErrorNoFound("Customer", customerIdStr); + doPost("/api/customer/" + customerIdStr + "/device/" + savedView.getId().getId().toString()) + .andExpect(status().isNotFound()) + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityNever(savedView.getId(), savedView); } @Test @@ -242,8 +329,13 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes EntityView savedView = getNewSavedEntityView("Test entity view"); + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/customer/" + savedCustomer.getId().getId().toString() + "/entityView/" + savedView.getId().getId().toString()) - .andExpect(status().isForbidden()); + .andExpect(status().isForbidden()) + .andExpect(statusReason(containsString(msgErrorPermission))); + + testNotifyEntityNever(savedView.getId(), savedView); loginSysAdmin(); @@ -257,8 +349,11 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes CustomerId customerId = customer.getId(); String urlTemplate = "/api/customer/" + customerId.getId().toString() + "/entityViewInfos?"; - List> viewFutures = new ArrayList<>(128); - for (int i = 0; i < 128; i++) { + Mockito.reset(tbClusterService, auditLogService); + + int cntEntity = 128; + List> viewFutures = new ArrayList<>(cntEntity); + for (int i = 0; i < cntEntity; i++) { String entityName = "Test entity view " + i; viewFutures.add(executor.submit(() -> new EntityViewInfo(doPost("/api/customer/" + customerId.getId().toString() + "/entityView/" @@ -269,6 +364,15 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes List loadedViews = loadListOfInfo(new PageLink(23), urlTemplate); assertThat(entityViewInfos).containsExactlyInAnyOrderElementsOf(loadedViews); + + testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(), + tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ADDED, ActionType.ADDED, cntEntity, 0, cntEntity*2, 0); + + testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.ASSIGNED_TO_CUSTOMER, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, + cntEntity*2, 3); } @Test @@ -289,12 +393,21 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes assertThat(namesOfView2).as(name2).containsExactlyInAnyOrderElementsOf(loadedNamesOfView2); deleteFutures.clear(); + + Mockito.reset(tbClusterService, auditLogService); + + int cntEntity = loadedNamesOfView1.size(); for (EntityView view : loadedNamesOfView1) { deleteFutures.add(executor.submit(() -> doDelete("/api/customer/entityView/" + view.getId().getId().toString()).andExpect(status().isOk()))); } Futures.allAsList(deleteFutures).get(TIMEOUT, SECONDS); + testBroadcastEntityStateChangeEventNever(loadedNamesOfView1.get(0).getId()); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new EntityView(), new EntityView(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, + ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 2); + PageData pageData = doGetTypedWithPageLink(urlTemplate, PAGE_DATA_ENTITY_VIEW_TYPE_REF, new PageLink(4, 0, name1)); Assert.assertFalse(pageData.hasNext()); @@ -370,10 +483,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes Set expectedActualAttributesSet = Set.of("caKey1", "caKey2", "caKey3", "caKey4"); Set actualAttributesSet = putAttributesAndWait("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}", expectedActualAttributesSet); - log.debug("got correct actualAttributesSet, saving new entity view..."); EntityView savedView = getNewSavedEntityView("Test entity view"); - log.debug("fetching entity view telemetry..."); List> values = await("telemetry/ENTITY_VIEW") .atMost(TIMEOUT, SECONDS) .until(() -> doGetAsyncTyped("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() + @@ -381,7 +492,6 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes }), x -> x.size() >= expectedActualAttributesSet.size()); - log.debug("asserting..."); assertEquals("value1", getValue(values, "caKey1")); assertEquals(true, getValue(values, "caKey2")); assertEquals(42.0, getValue(values, "caKey3")); @@ -526,7 +636,6 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes getWsClient().subscribeLatestUpdate(keysToSubscribe, dtf); String viewDeviceId = testDevice.getId().getId().toString(); - log.debug("deviceid {}", viewDeviceId); DeviceCredentials deviceCredentials = doGet("/api/device/" + viewDeviceId + "/credentials", DeviceCredentials.class); assertEquals(testDevice.getId(), deviceCredentials.getDeviceId()); @@ -534,7 +643,6 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes String accessToken = deviceCredentials.getCredentialsId(); assertNotNull(accessToken); - log.debug("creating mqtt client..."); String clientId = MqttAsyncClient.generateClientId(); MqttAsyncClient client = new MqttAsyncClient("tcp://localhost:1883", clientId, new MemoryPersistence()); @@ -542,14 +650,11 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes options.setUserName(accessToken); client.connect(options); awaitConnected(client, SECONDS.toMillis(30)); - log.debug("mqtt connected..."); MqttMessage message = new MqttMessage(); message.setPayload((stringKV).getBytes()); getWsClient().registerWaitForUpdate(); IMqttDeliveryToken token = client.publish("v1/devices/me/attributes", message); - log.debug("publish token.message {}", token.getMessage()); await("mqtt ack").pollInterval(5, MILLISECONDS).atMost(TIMEOUT, SECONDS).until(() -> token.getMessage() == null); - log.debug("token.message delivered {}", token.getMessage()); assertThat(getWsClient().waitForUpdate()).as("ws update received").isNotBlank(); return getAttributeKeys("DEVICE", viewDeviceId); }