|
|
|
@ -17,24 +17,24 @@ package org.thingsboard.server.controller; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
|
import org.apache.commons.lang3.RandomStringUtils; |
|
|
|
import org.junit.After; |
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Test; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.mockito.ArgumentMatcher; |
|
|
|
import org.mockito.Mockito; |
|
|
|
import org.thingsboard.server.common.data.EntityInfo; |
|
|
|
import org.thingsboard.server.common.data.Tenant; |
|
|
|
import org.thingsboard.server.common.data.TenantProfile; |
|
|
|
import org.thingsboard.server.common.data.id.TenantProfileId; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
|
|
|
import org.thingsboard.server.common.data.queue.ProcessingStrategy; |
|
|
|
import org.thingsboard.server.common.data.queue.ProcessingStrategyType; |
|
|
|
import org.thingsboard.server.common.data.queue.SubmitStrategy; |
|
|
|
import org.thingsboard.server.common.data.queue.SubmitStrategyType; |
|
|
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
|
|
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; |
|
|
|
import org.thingsboard.server.dao.tenant.TenantProfileService; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
@ -42,6 +42,8 @@ import java.util.List; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import static org.hamcrest.Matchers.containsString; |
|
|
|
import static org.mockito.Mockito.never; |
|
|
|
import static org.mockito.Mockito.times; |
|
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
|
|
|
|
|
|
|
public abstract class BaseTenantProfileControllerTest extends AbstractControllerTest { |
|
|
|
@ -52,6 +54,9 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
@Test |
|
|
|
public void testSaveTenantProfile() throws Exception { |
|
|
|
loginSysAdmin(); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
|
|
|
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); |
|
|
|
Assert.assertNotNull(savedTenantProfile); |
|
|
|
@ -64,17 +69,28 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
Assert.assertEquals(tenantProfile.isIsolatedTbCore(), savedTenantProfile.isIsolatedTbCore()); |
|
|
|
Assert.assertEquals(tenantProfile.isIsolatedTbRuleEngine(), savedTenantProfile.isIsolatedTbRuleEngine()); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(savedTenantProfile, ComponentLifecycleEvent.CREATED, 1); |
|
|
|
|
|
|
|
savedTenantProfile.setName("New tenant profile"); |
|
|
|
doPost("/api/tenantProfile", savedTenantProfile, TenantProfile.class); |
|
|
|
TenantProfile foundTenantProfile = doGet("/api/tenantProfile/"+savedTenantProfile.getId().getId().toString(), TenantProfile.class); |
|
|
|
Assert.assertEquals(foundTenantProfile.getName(), savedTenantProfile.getName()); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(savedTenantProfile, ComponentLifecycleEvent.UPDATED, 1); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void testSaveTenantProfileWithViolationOfLengthValidation() throws Exception { |
|
|
|
loginSysAdmin(); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
TenantProfile tenantProfile = this.createTenantProfile(RandomStringUtils.randomAlphabetic(300)); |
|
|
|
doPost("/api/tenantProfile", tenantProfile).andExpect(statusReason(containsString("length of name must be equal or less than 255"))); |
|
|
|
doPost("/api/tenantProfile", tenantProfile) |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString(msgErrorFieldLength("name")))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -122,9 +138,15 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
@Test |
|
|
|
public void testSaveTenantProfileWithEmptyName() throws Exception { |
|
|
|
loginSysAdmin(); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
TenantProfile tenantProfile = new TenantProfile(); |
|
|
|
doPost("/api/tenantProfile", tenantProfile).andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("Tenant profile name should be specified"))); |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("Tenant profile name " + msgErrorShouldBeSpecified))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -132,9 +154,15 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
loginSysAdmin(); |
|
|
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
|
|
|
doPost("/api/tenantProfile", tenantProfile).andExpect(status().isOk()); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
TenantProfile tenantProfile2 = this.createTenantProfile("Tenant Profile"); |
|
|
|
doPost("/api/tenantProfile", tenantProfile2).andExpect(status().isBadRequest()) |
|
|
|
doPost("/api/tenantProfile", tenantProfile2) |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("Tenant profile with such name already exists"))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -144,8 +172,14 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); |
|
|
|
savedTenantProfile.setIsolatedTbRuleEngine(true); |
|
|
|
addMainQueueConfig(savedTenantProfile); |
|
|
|
doPost("/api/tenantProfile", savedTenantProfile).andExpect(status().isBadRequest()) |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
doPost("/api/tenantProfile", savedTenantProfile) |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("Can't update isolatedTbRuleEngine property"))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -153,9 +187,15 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
loginSysAdmin(); |
|
|
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
|
|
|
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
savedTenantProfile.setIsolatedTbCore(true); |
|
|
|
doPost("/api/tenantProfile", savedTenantProfile).andExpect(status().isBadRequest()) |
|
|
|
doPost("/api/tenantProfile", savedTenantProfile) |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("Can't update isolatedTbCore property"))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -169,10 +209,14 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
tenant.setTenantProfileId(savedTenantProfile.getId()); |
|
|
|
Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
doDelete("/api/tenantProfile/" + savedTenantProfile.getId().getId().toString()) |
|
|
|
.andExpect(status().isBadRequest()) |
|
|
|
.andExpect(statusReason(containsString("The tenant profile referenced by the tenants cannot be deleted"))); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventNeverTenantProfile(); |
|
|
|
|
|
|
|
doDelete("/api/tenant/"+savedTenant.getId().getId().toString()) |
|
|
|
.andExpect(status().isOk()); |
|
|
|
} |
|
|
|
@ -183,11 +227,16 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
|
|
|
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
doDelete("/api/tenantProfile/" + savedTenantProfile.getId().getId().toString()) |
|
|
|
.andExpect(status().isOk()); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(savedTenantProfile, ComponentLifecycleEvent.DELETED, 1); |
|
|
|
|
|
|
|
doGet("/api/tenantProfile/" + savedTenantProfile.getId().getId().toString()) |
|
|
|
.andExpect(status().isNotFound()); |
|
|
|
.andExpect(status().isNotFound()) |
|
|
|
.andExpect(statusReason(containsString(msgErrorNoFound("Tenant profile", savedTenantProfile.getId().getId().toString())))); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -196,21 +245,26 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
List<TenantProfile> tenantProfiles = new ArrayList<>(); |
|
|
|
PageLink pageLink = new PageLink(17); |
|
|
|
PageData<TenantProfile> pageData = doGetTypedWithPageLink("/api/tenantProfiles?", |
|
|
|
new TypeReference<PageData<TenantProfile>>(){}, pageLink); |
|
|
|
new TypeReference<>(){}, pageLink); |
|
|
|
Assert.assertFalse(pageData.hasNext()); |
|
|
|
Assert.assertEquals(1, pageData.getTotalElements()); |
|
|
|
tenantProfiles.addAll(pageData.getData()); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
int cntEntity = 28; |
|
|
|
for (int i=0;i<28;i++) { |
|
|
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"+i); |
|
|
|
tenantProfiles.add(doPost("/api/tenantProfile", tenantProfile, TenantProfile.class)); |
|
|
|
} |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(new TenantProfile(), ComponentLifecycleEvent.CREATED, cntEntity); |
|
|
|
|
|
|
|
List<TenantProfile> loadedTenantProfiles = new ArrayList<>(); |
|
|
|
pageLink = new PageLink(17); |
|
|
|
do { |
|
|
|
pageData = doGetTypedWithPageLink("/api/tenantProfiles?", |
|
|
|
new TypeReference<PageData<TenantProfile>>(){}, pageLink); |
|
|
|
new TypeReference<>(){}, pageLink); |
|
|
|
loadedTenantProfiles.addAll(pageData.getData()); |
|
|
|
if (pageData.hasNext()) { |
|
|
|
pageLink = pageLink.nextPageLink(); |
|
|
|
@ -222,6 +276,8 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
|
|
|
|
Assert.assertEquals(tenantProfiles, loadedTenantProfiles); |
|
|
|
|
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
|
|
|
|
for (TenantProfile tenantProfile : loadedTenantProfiles) { |
|
|
|
if (!tenantProfile.isDefault()) { |
|
|
|
doDelete("/api/tenantProfile/" + tenantProfile.getId().getId().toString()) |
|
|
|
@ -234,6 +290,8 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
new TypeReference<PageData<TenantProfile>>(){}, pageLink); |
|
|
|
Assert.assertFalse(pageData.hasNext()); |
|
|
|
Assert.assertEquals(1, pageData.getTotalElements()); |
|
|
|
|
|
|
|
testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(new TenantProfile(), ComponentLifecycleEvent.DELETED, cntEntity); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@ -242,7 +300,7 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
List<TenantProfile> tenantProfiles = new ArrayList<>(); |
|
|
|
PageLink pageLink = new PageLink(17); |
|
|
|
PageData<TenantProfile> tenantProfilePageData = doGetTypedWithPageLink("/api/tenantProfiles?", |
|
|
|
new TypeReference<PageData<TenantProfile>>(){}, pageLink); |
|
|
|
new TypeReference<>(){}, pageLink); |
|
|
|
Assert.assertFalse(tenantProfilePageData.hasNext()); |
|
|
|
Assert.assertEquals(1, tenantProfilePageData.getTotalElements()); |
|
|
|
tenantProfiles.addAll(tenantProfilePageData.getData()); |
|
|
|
@ -322,4 +380,28 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController |
|
|
|
profileData.setQueueConfiguration(Collections.singletonList(mainQueueConfiguration)); |
|
|
|
tenantProfile.setProfileData(profileData); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void testBroadcastEntityStateChangeEventTimeManyTimeTenantProfile(TenantProfile tenantProfile, ComponentLifecycleEvent event, int cntTime) { |
|
|
|
ArgumentMatcher<TenantProfile> matcherTenantProfile = cntTime == 1 ? argument -> argument.equals(tenantProfile) : |
|
|
|
argument -> argument.getClass().equals(TenantProfile.class); |
|
|
|
if (ComponentLifecycleEvent.DELETED.equals(event)) { |
|
|
|
Mockito.verify(tbClusterService, times( cntTime)).onTenantProfileDelete(Mockito.argThat( matcherTenantProfile), |
|
|
|
Mockito.isNull()); |
|
|
|
testBroadcastEntityStateChangeEventNever(createEntityId_NULL_UUID(new Tenant())); |
|
|
|
} else { |
|
|
|
Mockito.verify(tbClusterService, times( cntTime)).onTenantProfileChange(Mockito.argThat(matcherTenantProfile), |
|
|
|
Mockito.isNull()); |
|
|
|
TenantProfileId tenantProfileIdId = cntTime == 1 ? tenantProfile.getId() : (TenantProfileId) createEntityId_NULL_UUID(tenantProfile); |
|
|
|
testBroadcastEntityStateChangeEventTime(tenantProfileIdId, null, cntTime); |
|
|
|
} |
|
|
|
Mockito.reset(tbClusterService); |
|
|
|
} |
|
|
|
|
|
|
|
private void testBroadcastEntityStateChangeEventNeverTenantProfile() { |
|
|
|
Mockito.verify(tbClusterService, never()).onTenantProfileChange(Mockito.any(TenantProfile.class), |
|
|
|
Mockito.isNull()); |
|
|
|
testBroadcastEntityStateChangeEventNever(createEntityId_NULL_UUID(new Tenant())); |
|
|
|
Mockito.reset(tbClusterService, auditLogService); |
|
|
|
} |
|
|
|
} |
|
|
|
|