Browse Source

[3.3] added tests for resources (#4282)

* added TbResourceService test

* fix ResourceService test

* created TbResourceControllerSqlTest

* fixed BaseTbResourceServiceTest
pull/4298/head
Yevhen Bondarenko 6 years ago
committed by GitHub
parent
commit
0d62b2890c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 33
      application/src/main/java/org/thingsboard/server/controller/TbResourceController.java
  2. 1
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  3. 1
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  4. 284
      application/src/test/java/org/thingsboard/server/controller/BaseTbResourceControllerTest.java
  5. 23
      application/src/test/java/org/thingsboard/server/controller/sql/TbResourceControllerSqlTest.java
  6. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/resource/TbResourceService.java
  7. 4
      common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java
  8. 5
      common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java
  9. 37
      common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/Resource.java
  10. 1
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  11. 19
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java
  12. 9
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java
  13. 125
      dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java
  14. 4
      dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java
  15. 16
      dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java
  16. 19
      dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java
  17. 1
      dao/src/main/resources/sql/schema-entities-hsql.sql
  18. 1
      dao/src/main/resources/sql/schema-entities.sql
  19. 4
      dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
  20. 350
      dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java
  21. 23
      dao/src/test/java/org/thingsboard/server/dao/service/sql/TbResourceServiceSqlTest.java

33
application/src/main/java/org/thingsboard/server/controller/TbResourceController.java

@ -16,6 +16,10 @@
package org.thingsboard.server.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -31,11 +35,13 @@ import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.resource.TbResourceService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.Base64;
import java.util.List;
@Slf4j
@ -52,6 +58,27 @@ public class TbResourceController extends BaseController {
this.resourceService = resourceService;
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<org.springframework.core.io.Resource> downloadResource(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
checkParameter(RESOURCE_ID, strResourceId);
try {
TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
TbResource tbResource = checkResourceId(resourceId, Operation.READ);
ByteArrayResource resource = new ByteArrayResource(Base64.getDecoder().decode(tbResource.getData().getBytes()));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tbResource.getFileName())
.header("x-filename", tbResource.getFileName())
.contentLength(resource.contentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/resource/info/{resourceId}", method = RequestMethod.GET)
@ResponseBody
@ -103,7 +130,11 @@ public class TbResourceController extends BaseController {
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return checkNotNull(resourceService.findResourcesByTenantId(getTenantId(), pageLink));
if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) {
return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), pageLink));
} else {
return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), pageLink));
}
} catch (Exception e) {
throw handleException(e);
}

1
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -205,6 +205,7 @@ public class InstallScripts {
try {
byte[] fileBytes = Files.readAllBytes(path);
TbResource resource = new TbResource();
resource.setFileName(path.getFileName().toString());
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setResourceType(ResourceType.LWM2M_MODEL);
resource.setData(Base64.getEncoder().encodeToString(fileBytes));

1
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -458,6 +458,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
"resource_type varchar(32) NOT NULL, " +
"resource_key varchar(255) NOT NULL, " +
"search_text varchar(255), " +
"file_name varchar(255) NOT NULL, " +
"data varchar, " +
"CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)" +
");");

284
application/src/test/java/org/thingsboard/server/controller/BaseTbResourceControllerTest.java

@ -0,0 +1,284 @@
/**
* Copyright © 2016-2021 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 org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public abstract class BaseTbResourceControllerTest extends AbstractControllerTest {
private IdComparator<TbResourceInfo> idComparator = new IdComparator<>();
private static final String DEFAULT_FILE_NAME = "test.jks";
private Tenant savedTenant;
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);
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 testSaveTbResource() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My first resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = doPost("/api/resource", resource, TbResource.class);
Assert.assertNotNull(savedResource);
Assert.assertNotNull(savedResource.getId());
Assert.assertTrue(savedResource.getCreatedTime() > 0);
Assert.assertEquals(savedTenant.getId(), savedResource.getTenantId());
Assert.assertEquals(resource.getTitle(), savedResource.getTitle());
Assert.assertEquals(DEFAULT_FILE_NAME, savedResource.getFileName());
Assert.assertEquals(DEFAULT_FILE_NAME, savedResource.getResourceKey());
Assert.assertEquals(resource.getData(), savedResource.getData());
savedResource.setTitle("My new resource");
doPost("/api/resource", savedResource, TbResource.class);
TbResource foundResource = doGet("/api/resource/" + savedResource.getId().getId().toString(), TbResource.class);
Assert.assertEquals(foundResource.getTitle(), savedResource.getTitle());
}
@Test
public void testUpdateTbResourceFromDifferentTenant() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My first resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = doPost("/api/resource", resource, TbResource.class);
loginDifferentTenant();
doPost("/api/resource", savedResource, TbResource.class, status().isForbidden());
deleteDifferentTenant();
}
@Test
public void testFindTbResourceById() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My first resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = doPost("/api/resource", resource, TbResource.class);
TbResource foundResource = doGet("/api/resource/" + savedResource.getId().getId().toString(), TbResource.class);
Assert.assertNotNull(foundResource);
Assert.assertEquals(savedResource, foundResource);
}
@Test
public void testDeleteTbResource() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My first resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = doPost("/api/resource", resource, TbResource.class);
doDelete("/api/resource/" + savedResource.getId().getId().toString())
.andExpect(status().isOk());
doGet("/api/resource/" + savedResource.getId().getId().toString())
.andExpect(status().isNotFound());
}
@Test
public void testFindTenantTbResources() throws Exception {
List<TbResourceInfo> resources = new ArrayList<>();
for (int i = 0; i < 173; i++) {
TbResource resource = new TbResource();
resource.setTitle("Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
resources.add(new TbResourceInfo(doPost("/api/resource", resource, TbResource.class)));
}
List<TbResourceInfo> loadedResources = new ArrayList<>();
PageLink pageLink = new PageLink(24);
PageData<TbResourceInfo> pageData;
do {
pageData = doGetTypedWithPageLink("/api/resource?",
new TypeReference<PageData<TbResourceInfo>>() {
}, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
Assert.assertEquals(resources, loadedResources);
}
@Test
public void testFindSystemTbResources() throws Exception {
loginSysAdmin();
List<TbResourceInfo> resources = new ArrayList<>();
for (int i = 0; i < 173; i++) {
TbResource resource = new TbResource();
resource.setTitle("Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
resources.add(new TbResourceInfo(doPost("/api/resource", resource, TbResource.class)));
}
List<TbResourceInfo> loadedResources = new ArrayList<>();
PageLink pageLink = new PageLink(24);
PageData<TbResourceInfo> pageData;
do {
pageData = doGetTypedWithPageLink("/api/resource?",
new TypeReference<PageData<TbResourceInfo>>() {
}, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
Assert.assertEquals(resources, loadedResources);
for (TbResourceInfo resource : resources) {
doDelete("/api/resource/" + resource.getId().getId().toString())
.andExpect(status().isOk());
}
pageLink = new PageLink(27);
loadedResources.clear();
do {
pageData = doGetTypedWithPageLink("/api/resource?",
new TypeReference<PageData<TbResourceInfo>>() {
}, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Assert.assertTrue(loadedResources.isEmpty());
}
@Test
public void testFindSystemAndTenantTbResources() throws Exception {
List<TbResourceInfo> systemResources = new ArrayList<>();
List<TbResourceInfo> expectedResources = new ArrayList<>();
for (int i = 0; i < 73; i++) {
TbResource resource = new TbResource();
resource.setTitle("Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
expectedResources.add(new TbResourceInfo(doPost("/api/resource", resource, TbResource.class)));
}
loginSysAdmin();
for (int i = 0; i < 173; i++) {
TbResource resource = new TbResource();
resource.setTitle("Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResourceInfo savedResource = new TbResourceInfo(doPost("/api/resource", resource, TbResource.class));
systemResources.add(savedResource);
if (i >= 73) {
expectedResources.add(savedResource);
}
}
login(tenantAdmin.getEmail(), "testPassword1");
List<TbResourceInfo> loadedResources = new ArrayList<>();
PageLink pageLink = new PageLink(24);
PageData<TbResourceInfo> pageData;
do {
pageData = doGetTypedWithPageLink("/api/resource?",
new TypeReference<PageData<TbResourceInfo>>() {
}, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(expectedResources, idComparator);
Collections.sort(loadedResources, idComparator);
Assert.assertEquals(expectedResources, loadedResources);
loginSysAdmin();
for (TbResourceInfo resource : systemResources) {
doDelete("/api/resource/" + resource.getId().getId().toString())
.andExpect(status().isOk());
}
}
}

23
application/src/test/java/org/thingsboard/server/controller/sql/TbResourceControllerSqlTest.java

@ -0,0 +1,23 @@
/**
* Copyright © 2016-2021 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.BaseTbResourceControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
@DaoSqlTest
public class TbResourceControllerSqlTest extends BaseTbResourceControllerTest {
}

4
common/dao-api/src/main/java/org/thingsboard/server/dao/resource/TbResourceService.java

@ -38,7 +38,9 @@ public interface TbResourceService {
TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId);
PageData<TbResourceInfo> findResourcesByTenantId(TenantId tenantId, PageLink pageLink);
PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink);
PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink);
List<LwM2mObject> findLwM2mObject(TenantId tenantId,
String sortOrder,

4
common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java

@ -27,6 +27,8 @@ public class TbResource extends TbResourceInfo {
private static final long serialVersionUID = 7379609705527272306L;
private String fileName;
private String data;
public TbResource() {
@ -61,6 +63,8 @@ public class TbResource extends TbResourceInfo {
builder.append(getResourceType());
builder.append(", resourceKey=");
builder.append(getResourceKey());
builder.append(", fileName=");
builder.append(fileName);
builder.append(", data=");
builder.append(data);
builder.append("]");

5
common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java

@ -45,12 +45,13 @@ public class TbResourceInfo extends SearchTextBased<TbResourceId> implements Has
this.tenantId = resourceInfo.getTenantId();
this.title = resourceInfo.getTitle();
this.resourceType = resourceInfo.getResourceType();
this.resourceKey = resourceInfo.resourceKey;
this.resourceKey = resourceInfo.getResourceKey();
this.searchText = resourceInfo.getSearchText();
}
@Override
public String getSearchText() {
return searchText;
return searchText != null ? searchText : title;
}
@Override

37
common/data/src/main/java/org/thingsboard/server/common/data/transport/resource/Resource.java

@ -1,37 +0,0 @@
/**
* Copyright © 2016-2021 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.common.data.transport.resource;
import lombok.Data;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.TenantId;
@Data
public class Resource implements HasTenantId {
private TenantId tenantId;
private ResourceType resourceType;
private String resourceId;
private String value;
@Override
public String toString() {
return "Resource{" +
"tenantId=" + tenantId +
", resourceType=" + resourceType +
", resourceId='" + resourceId + '\'' +
'}';
}
}

1
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -464,6 +464,7 @@ public class ModelConstants {
public static final String RESOURCE_TYPE_COLUMN = "resource_type";
public static final String RESOURCE_KEY_COLUMN = "resource_key";
public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY;
public static final String RESOURCE_FILE_NAME_COLUMN = "file_name";
public static final String RESOURCE_DATA_COLUMN = "data";
/**

19
dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java

@ -30,6 +30,7 @@ import javax.persistence.Table;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_FILE_NAME_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN;
@ -58,6 +59,9 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> implements Searc
@Column(name = SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = RESOURCE_FILE_NAME_COLUMN)
private String fileName;
@Column(name = RESOURCE_DATA_COLUMN)
private String data;
@ -65,32 +69,37 @@ public class TbResourceEntity extends BaseSqlEntity<TbResource> implements Searc
}
public TbResourceEntity(TbResource resource) {
this.id = resource.getUuidId();
if (resource.getId() != null) {
this.id = resource.getId().getId();
}
this.createdTime = resource.getCreatedTime();
this.tenantId = resource.getTenantId().getId();
if (resource.getTenantId() != null) {
this.tenantId = resource.getTenantId().getId();
}
this.title = resource.getTitle();
this.resourceType = resource.getResourceType().name();
this.resourceKey = resource.getResourceKey();
this.searchText = resource.getSearchText();
this.fileName = resource.getFileName();
this.data = resource.getData();
}
@Override
public TbResource toData() {
TbResource resource = new TbResource();
resource.setId(new TbResourceId(id));
TbResource resource = new TbResource(new TbResourceId(id));
resource.setCreatedTime(createdTime);
resource.setTenantId(new TenantId(tenantId));
resource.setTitle(title);
resource.setResourceType(ResourceType.valueOf(resourceType));
resource.setResourceKey(resourceKey);
resource.setSearchText(searchText);
resource.setFileName(fileName);
resource.setData(data);
return resource;
}
@Override
public String getSearchTextSource() {
return title;
return this.searchText;
}
}

9
dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java

@ -61,8 +61,10 @@ public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implemen
}
public TbResourceInfoEntity(TbResourceInfo resource) {
this.setUuid(resource.getId().getId());
this.setCreatedTime(resource.getCreatedTime());
if (resource.getId() != null) {
this.id = resource.getId().getId();
}
this.createdTime = resource.getCreatedTime();
this.tenantId = resource.getTenantId().getId();
this.title = resource.getTitle();
this.resourceType = resource.getResourceType().name();
@ -72,8 +74,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implemen
@Override
public TbResourceInfo toData() {
TbResourceInfo resource = new TbResourceInfo();
resource.setId(new TbResourceId(id));
TbResourceInfo resource = new TbResourceInfo(new TbResourceId(id));
resource.setCreatedTime(createdTime);
resource.setTenantId(new TenantId(tenantId));
resource.setTitle(title);

125
dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java

@ -16,14 +16,17 @@
package org.thingsboard.server.dao.resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.leshan.core.model.DDFFileParser;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.InvalidDDFFileException;
import org.eclipse.leshan.core.model.ObjectModel;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.lwm2m.LwM2mInstance;
@ -32,8 +35,11 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mResource;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TenantDao;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -41,6 +47,7 @@ import java.util.ArrayList;
import java.util.Base64;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
@ -55,39 +62,59 @@ public class BaseTbResourceService implements TbResourceService {
public static final String INCORRECT_RESOURCE_ID = "Incorrect resourceId ";
private final TbResourceDao resourceDao;
private final TbResourceInfoDao resourceInfoDao;
private final TenantDao tenantDao;
private final DDFFileParser ddfFileParser;
public BaseTbResourceService(TbResourceDao resourceDao, TbResourceInfoDao resourceInfoDao) {
public BaseTbResourceService(TbResourceDao resourceDao, TbResourceInfoDao resourceInfoDao, TenantDao tenantDao) {
this.resourceDao = resourceDao;
this.resourceInfoDao = resourceInfoDao;
this.tenantDao = tenantDao;
this.ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
}
@Override
public TbResource saveResource(TbResource tbResource) throws InvalidDDFFileException, IOException {
log.trace("Executing saveResource [{}]", tbResource);
if (ResourceType.LWM2M_MODEL.equals(tbResource.getResourceType())) {
public TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException {
log.trace("Executing saveResource [{}]", resource);
if (StringUtils.isEmpty(resource.getData())) {
throw new DataValidationException("Resource data should be specified!");
}
if (ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) {
List<ObjectModel> objectModels =
ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(tbResource.getData())), tbResource.getSearchText());
ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText());
if (!objectModels.isEmpty()) {
ObjectModel objectModel = objectModels.get(0);
String resourceKey = objectModel.id + LWM2M_SEPARATOR_KEY + objectModel.getVersion();
String name = objectModel.name;
tbResource.setResourceKey(resourceKey);
tbResource.setTitle(name);
tbResource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name);
resource.setResourceKey(resourceKey);
resource.setTitle(name);
resource.setSearchText(resourceKey + LWM2M_SEPARATOR_SEARCH_TEXT + name);
} else {
throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
}
} else {
resource.setResourceKey(resource.getFileName());
}
resourceValidator.validate(resource, TbResourceInfo::getTenantId);
try {
return resourceDao.save(resource.getTenantId(), resource);
} catch (Exception t) {
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("resource_unq_key")) {
String field = ResourceType.LWM2M_MODEL.equals(resource.getResourceType()) ? "resourceKey" : "fileName";
throw new DataValidationException("Resource with such " + field + " already exists!");
} else {
throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", tbResource.getSearchText()));
throw t;
}
}
validate(tbResource);
return resourceDao.save(tbResource.getTenantId(), tbResource);
}
@Override
public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey) {
log.trace("Executing getResource [{}] [{}] [{}]", tenantId, resourceType, resourceKey);
validate(tenantId, resourceType, resourceKey);
return resourceDao.getResource(tenantId, resourceType, resourceKey);
}
@ -113,10 +140,17 @@ public class BaseTbResourceService implements TbResourceService {
}
@Override
public PageData<TbResourceInfo> findResourcesByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findByTenantId [{}]", tenantId);
public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findAllTenantResourcesByTenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return resourceInfoDao.findAllTenantResourcesByTenantId(tenantId.getId(), pageLink);
}
@Override
public PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findTenantResourcesByTenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return resourceInfoDao.findTbResourcesByTenantId(tenantId.getId(), pageLink);
return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), pageLink);
}
@Override
@ -154,26 +188,6 @@ public class BaseTbResourceService implements TbResourceService {
tenantResourcesRemover.removeEntities(tenantId, tenantId);
}
protected void validate(TbResource resource) {
if (resource == null) {
throw new DataValidationException("Resource should be specified!");
}
if (resource.getData() == null) {
throw new DataValidationException("Resource value should be specified!");
}
validate(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey());
}
protected void validate(TenantId tenantId, ResourceType resourceType, String resourceId) {
if (resourceType == null) {
throw new DataValidationException("Resource type should be specified!");
}
if (resourceId == null) {
throw new DataValidationException("Resource id should be specified!");
}
validateId(tenantId, "Incorrect tenantId ");
}
private LwM2mObject toLwM2mObject(TbResource resource) {
try {
DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
@ -218,6 +232,37 @@ public class BaseTbResourceService implements TbResourceService {
return "DESC".equals(sortOrder) ? comparator.reversed() : comparator;
}
private DataValidator<TbResource> resourceValidator = new DataValidator<>() {
@Override
protected void validateDataImpl(TenantId tenantId, TbResource resource) {
if (StringUtils.isEmpty(resource.getTitle())) {
throw new DataValidationException("Resource title should be specified!");
}
if (resource.getResourceType() == null) {
throw new DataValidationException("Resource type should be specified!");
}
if (StringUtils.isEmpty(resource.getFileName())) {
throw new DataValidationException("Resource file name should be specified!");
}
if (StringUtils.isEmpty(resource.getResourceKey())) {
throw new DataValidationException("Resource key should be specified!");
}
if (resource.getTenantId() == null) {
resource.setTenantId(new TenantId(ModelConstants.NULL_UUID));
}
if (!resource.getTenantId().getId().equals(ModelConstants.NULL_UUID)) {
Tenant tenant = tenantDao.findById(tenantId, resource.getTenantId().getId());
if (tenant == null) {
throw new DataValidationException("Resource is referencing to non-existent tenant!");
}
}
if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource) == null) {
throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
}
}
};
private PaginatedRemover<TenantId, TbResource> tenantResourcesRemover =
new PaginatedRemover<>() {
@ -231,4 +276,14 @@ public class BaseTbResourceService implements TbResourceService {
deleteResource(tenantId, new TbResourceId(entity.getUuidId()));
}
};
protected Optional<ConstraintViolationException> extractConstraintViolationException(Exception t) {
if (t instanceof ConstraintViolationException) {
return Optional.of((ConstraintViolationException) t);
} else if (t.getCause() instanceof ConstraintViolationException) {
return Optional.of((ConstraintViolationException) (t.getCause()));
} else {
return Optional.empty();
}
}
}

4
dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java

@ -24,6 +24,8 @@ import java.util.UUID;
public interface TbResourceInfoDao extends Dao<TbResourceInfo> {
PageData<TbResourceInfo> findTbResourcesByTenantId(UUID tenantId, PageLink pageLink);
PageData<TbResourceInfo> findAllTenantResourcesByTenantId(UUID tenantId, PageLink pageLink);
PageData<TbResourceInfo> findTenantResourcesByTenantId(UUID tenantId, PageLink pageLink);
}

16
dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java

@ -49,11 +49,21 @@ public class JpaTbResourceInfoDao extends JpaAbstractSearchTextDao<TbResourceInf
}
@Override
public PageData<TbResourceInfo> findTbResourcesByTenantId(UUID tenantId, PageLink pageLink) {
public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(resourceInfoRepository
.findByTenantId(
.findAllTenantResourcesByTenantId(
tenantId,
TenantId.NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink))); }
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<TbResourceInfo> findTenantResourcesByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(resourceInfoRepository
.findTenantResourcesByTenantId(
tenantId,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
}

19
dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java

@ -26,8 +26,8 @@ import java.util.UUID;
public interface TbResourceInfoRepository extends CrudRepository<TbResourceInfoEntity, UUID> {
@Query("SELECT tr FROM TbResourceInfoEntity tr WHERE tr.tenantId = :tenantId " +
"AND LOWER(tr.searchText) LIKE LOWER(CONCAT(:searchText, '%'))" +
@Query("SELECT tr FROM TbResourceInfoEntity tr WHERE " +
"LOWER(tr.searchText) LIKE LOWER(CONCAT(:searchText, '%'))" +
"AND (tr.tenantId = :tenantId " +
"OR (tr.tenantId = :systemAdminId " +
"AND NOT EXISTS " +
@ -35,8 +35,15 @@ public interface TbResourceInfoRepository extends CrudRepository<TbResourceInfoE
"WHERE sr.tenantId = :tenantId " +
"AND tr.resourceType = sr.resourceType " +
"AND tr.resourceKey = sr.resourceKey)))")
Page<TbResourceInfoEntity> findByTenantId(@Param("tenantId") UUID tenantId,
@Param("systemAdminId") UUID sysadminId,
@Param("searchText") String searchText,
Pageable pageable);
Page<TbResourceInfoEntity> findAllTenantResourcesByTenantId(@Param("tenantId") UUID tenantId,
@Param("systemAdminId") UUID sysadminId,
@Param("searchText") String searchText,
Pageable pageable);
@Query("SELECT ri FROM TbResourceInfoEntity ri WHERE " +
"ri.tenantId = :tenantId " +
"AND LOWER(ri.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
Page<TbResourceInfoEntity> findTenantResourcesByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText,
Pageable pageable);
}

1
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -433,6 +433,7 @@ CREATE TABLE IF NOT EXISTS resource (
resource_type varchar(32) NOT NULL,
resource_key varchar(255) NOT NULL,
search_text varchar(255),
file_name varchar(255) NOT NULL,
data varchar,
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
);

1
dao/src/main/resources/sql/schema-entities.sql

@ -459,6 +459,7 @@ CREATE TABLE IF NOT EXISTS resource (
resource_type varchar(32) NOT NULL,
resource_key varchar(255) NOT NULL,
search_text varchar(255),
file_name varchar(255) NOT NULL,
data varchar,
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
);

4
dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java

@ -52,6 +52,7 @@ import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.resource.TbResourceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.tenant.TenantProfileService;
@ -142,6 +143,9 @@ public abstract class AbstractServiceTest {
@Autowired
protected DeviceProfileService deviceProfileService;
@Autowired
protected TbResourceService resourceService;
class IdComparator<D extends HasId> implements Comparator<D> {
@Override
public int compare(D o1, D o2) {

350
dao/src/test/java/org/thingsboard/server/dao/service/BaseTbResourceServiceTest.java

@ -0,0 +1,350 @@
/**
* Copyright © 2016-2021 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.dao.service;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
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.dao.exception.DataValidationException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
public abstract class BaseTbResourceServiceTest extends AbstractServiceTest {
private static final String LWM2M_TEST_MODEL = "<LWM2M xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.openmobilealliance.org/tech/profiles/LWM2M-v1_1.xsd\">\n" +
"<Object ObjectType=\"MODefinition\">\n" +
"<Name>My first resource</Name>\n" +
"<Description1></Description1>\n" +
"<ObjectID>0</ObjectID>\n" +
"<ObjectURN></ObjectURN>\n" +
"<ObjectVersion>1.0</ObjectVersion>\n" +
"<MultipleInstances>Multiple</MultipleInstances>\n" +
"<Mandatory>Mandatory</Mandatory>\n" +
"<Resources>\n" +
"<Item ID=\"0\">\n" +
"<Name>LWM2M</Name>\n" +
"<Operations></Operations>\n" +
"<MultipleInstances>Single</MultipleInstances>\n" +
"<Mandatory>Mandatory</Mandatory>\n" +
"<Type>String</Type>\n" +
"<RangeEnumeration>0..255</RangeEnumeration>\n" +
"<Units></Units>\n" +
"<Description></Description>\n" +
"</Item>\n" +
"</Resources>\n" +
"<Description2></Description2>\n" +
"</Object>\n" +
"</LWM2M>";
private static final String DEFAULT_FILE_NAME = "test.jks";
private IdComparator<TbResourceInfo> idComparator = new IdComparator<>();
private TenantId tenantId;
@Before
public void before() {
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
Tenant savedTenant = tenantService.saveTenant(tenant);
Assert.assertNotNull(savedTenant);
tenantId = savedTenant.getId();
}
@After
public void after() {
tenantService.deleteTenant(tenantId);
}
@Test
public void testSaveTbResource() throws Exception {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My first resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
Assert.assertNotNull(savedResource);
Assert.assertNotNull(savedResource.getId());
Assert.assertTrue(savedResource.getCreatedTime() > 0);
Assert.assertEquals(resource.getTenantId(), savedResource.getTenantId());
Assert.assertEquals(resource.getTitle(), savedResource.getTitle());
Assert.assertEquals(resource.getResourceKey(), savedResource.getResourceKey());
Assert.assertEquals(resource.getData(), savedResource.getData());
savedResource.setTitle("My new resource");
resourceService.saveResource(savedResource);
TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
Assert.assertEquals(foundResource.getTitle(), savedResource.getTitle());
resourceService.deleteResource(tenantId, savedResource.getId());
}
@Test
public void testSaveLwm2mTbResource() throws Exception {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setResourceType(ResourceType.LWM2M_MODEL);
resource.setFileName("test_model.xml");
resource.setData(Base64.getEncoder().encodeToString(LWM2M_TEST_MODEL.getBytes()));
TbResource savedResource = resourceService.saveResource(resource);
Assert.assertNotNull(savedResource);
Assert.assertNotNull(savedResource.getId());
Assert.assertTrue(savedResource.getCreatedTime() > 0);
Assert.assertEquals(resource.getTenantId(), savedResource.getTenantId());
Assert.assertEquals("My first resource", savedResource.getTitle());
Assert.assertEquals("0_1.0", savedResource.getResourceKey());
Assert.assertEquals(resource.getData(), savedResource.getData());
resourceService.deleteResource(tenantId, savedResource.getId());
}
@Test
public void testSaveTbResourceWithEmptyTenant() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
Assert.assertEquals(TenantId.SYS_TENANT_ID, savedResource.getTenantId());
resourceService.deleteResource(tenantId, savedResource.getId());
}
@Test(expected = DataValidationException.class)
public void testSaveTbResourceWithExistsFileName() throws Exception {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
TbResource resource2 = new TbResource();
resource.setTenantId(tenantId);
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
try {
resourceService.saveResource(resource2);
} finally {
resourceService.deleteResource(tenantId, savedResource.getId());
}
}
@Test(expected = DataValidationException.class)
public void testSaveTbResourceWithEmptyTitle() throws Exception {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
resourceService.saveResource(resource);
}
@Test(expected = DataValidationException.class)
public void testSaveTbResourceWithInvalidTenant() throws Exception {
TbResource resource = new TbResource();
resource.setTenantId(new TenantId(Uuids.timeBased()));
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
resourceService.saveResource(resource);
}
@Test
public void testFindResourceById() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
Assert.assertNotNull(foundResource);
Assert.assertEquals(savedResource, foundResource);
resourceService.deleteResource(tenantId, savedResource.getId());
}
@Test
public void testFindResourceByTenantIdAndResourceTypeAndResourceKey() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTenantId(tenantId);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
TbResource foundResource = resourceService.getResource(tenantId, savedResource.getResourceType(), savedResource.getResourceKey());
Assert.assertNotNull(foundResource);
Assert.assertEquals(savedResource, foundResource);
resourceService.deleteResource(tenantId, savedResource.getId());
}
@Test
public void testDeleteResource() throws Exception {
TbResource resource = new TbResource();
resource.setResourceType(ResourceType.JKS);
resource.setTitle("My resource");
resource.setFileName(DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResource savedResource = resourceService.saveResource(resource);
TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
Assert.assertNotNull(foundResource);
resourceService.deleteResource(tenantId, savedResource.getId());
foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
Assert.assertNull(foundResource);
}
@Test
public void testFindTenantResourcesByTenantId() throws Exception {
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
List<TbResourceInfo> resources = new ArrayList<>();
for (int i = 0; i < 165; i++) {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setTitle("Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
resources.add(new TbResourceInfo(resourceService.saveResource(resource)));
}
List<TbResourceInfo> loadedResources = new ArrayList<>();
PageLink pageLink = new PageLink(16);
PageData<TbResourceInfo> pageData;
do {
pageData = resourceService.findTenantResourcesByTenantId(tenantId, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
Assert.assertEquals(resources, loadedResources);
resourceService.deleteResourcesByTenantId(tenantId);
pageLink = new PageLink(31);
pageData = resourceService.findTenantResourcesByTenantId(tenantId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
tenantService.deleteTenant(tenantId);
}
@Test
public void testFindAllTenantResourcesByTenantId() throws Exception {
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
List<TbResourceInfo> resources = new ArrayList<>();
for (int i = 0; i < 100; i++) {
TbResource resource = new TbResource();
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setTitle("System Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
TbResourceInfo tbResourceInfo = new TbResourceInfo(resourceService.saveResource(resource));
if (i >= 50) {
resources.add(tbResourceInfo);
}
}
for (int i = 0; i < 50; i++) {
TbResource resource = new TbResource();
resource.setTenantId(tenantId);
resource.setTitle("Tenant Resource" + i);
resource.setResourceType(ResourceType.JKS);
resource.setFileName(i + DEFAULT_FILE_NAME);
resource.setData("Test Data");
resources.add(new TbResourceInfo(resourceService.saveResource(resource)));
}
List<TbResourceInfo> loadedResources = new ArrayList<>();
PageLink pageLink = new PageLink(10);
PageData<TbResourceInfo> pageData;
do {
pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink);
loadedResources.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(resources, idComparator);
Collections.sort(loadedResources, idComparator);
Assert.assertEquals(resources, loadedResources);
resourceService.deleteResourcesByTenantId(tenantId);
pageLink = new PageLink(100);
pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(pageData.getData().size(), 100);
resourceService.deleteResourcesByTenantId(TenantId.SYS_TENANT_ID);
pageLink = new PageLink(100);
pageData = resourceService.findAllTenantResourcesByTenantId(TenantId.SYS_TENANT_ID, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
tenantService.deleteTenant(tenantId);
}
}

23
dao/src/test/java/org/thingsboard/server/dao/service/sql/TbResourceServiceSqlTest.java

@ -0,0 +1,23 @@
/**
* Copyright © 2016-2021 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.dao.service.sql;
import org.thingsboard.server.dao.service.BaseTbResourceServiceTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
@DaoSqlTest
public class TbResourceServiceSqlTest extends BaseTbResourceServiceTest {
}
Loading…
Cancel
Save