Commit ad7c314b2483817989bed5e6aa9da79c3bc35c76

Authored by YevhenBondarenko
Committed by Andrew Shvayka
1 parent bc21db00

TbResource extends SearchTextBased, created TbResourceInfo

Showing 34 changed files with 764 additions and 340 deletions
@@ -39,6 +39,8 @@ import org.thingsboard.server.common.data.EntityView; @@ -39,6 +39,8 @@ import org.thingsboard.server.common.data.EntityView;
39 import org.thingsboard.server.common.data.EntityViewInfo; 39 import org.thingsboard.server.common.data.EntityViewInfo;
40 import org.thingsboard.server.common.data.HasName; 40 import org.thingsboard.server.common.data.HasName;
41 import org.thingsboard.server.common.data.HasTenantId; 41 import org.thingsboard.server.common.data.HasTenantId;
  42 +import org.thingsboard.server.common.data.TbResourceInfo;
  43 +import org.thingsboard.server.common.data.TbResource;
42 import org.thingsboard.server.common.data.Tenant; 44 import org.thingsboard.server.common.data.Tenant;
43 import org.thingsboard.server.common.data.TenantInfo; 45 import org.thingsboard.server.common.data.TenantInfo;
44 import org.thingsboard.server.common.data.TenantProfile; 46 import org.thingsboard.server.common.data.TenantProfile;
@@ -59,6 +61,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -59,6 +61,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
59 import org.thingsboard.server.common.data.id.EntityId; 61 import org.thingsboard.server.common.data.id.EntityId;
60 import org.thingsboard.server.common.data.id.EntityIdFactory; 62 import org.thingsboard.server.common.data.id.EntityIdFactory;
61 import org.thingsboard.server.common.data.id.EntityViewId; 63 import org.thingsboard.server.common.data.id.EntityViewId;
  64 +import org.thingsboard.server.common.data.id.TbResourceId;
62 import org.thingsboard.server.common.data.id.RuleChainId; 65 import org.thingsboard.server.common.data.id.RuleChainId;
63 import org.thingsboard.server.common.data.id.RuleNodeId; 66 import org.thingsboard.server.common.data.id.RuleNodeId;
64 import org.thingsboard.server.common.data.id.TenantId; 67 import org.thingsboard.server.common.data.id.TenantId;
@@ -77,7 +80,6 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; @@ -77,7 +80,6 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
77 import org.thingsboard.server.common.data.plugin.ComponentType; 80 import org.thingsboard.server.common.data.plugin.ComponentType;
78 import org.thingsboard.server.common.data.rule.RuleChain; 81 import org.thingsboard.server.common.data.rule.RuleChain;
79 import org.thingsboard.server.common.data.rule.RuleNode; 82 import org.thingsboard.server.common.data.rule.RuleNode;
80 -import org.thingsboard.server.common.data.widget.WidgetType;  
81 import org.thingsboard.server.common.data.widget.WidgetTypeDetails; 83 import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
82 import org.thingsboard.server.common.data.widget.WidgetsBundle; 84 import org.thingsboard.server.common.data.widget.WidgetsBundle;
83 import org.thingsboard.server.common.msg.TbMsg; 85 import org.thingsboard.server.common.msg.TbMsg;
@@ -99,6 +101,7 @@ import org.thingsboard.server.dao.model.ModelConstants; @@ -99,6 +101,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
99 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; 101 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
100 import org.thingsboard.server.dao.oauth2.OAuth2Service; 102 import org.thingsboard.server.dao.oauth2.OAuth2Service;
101 import org.thingsboard.server.dao.relation.RelationService; 103 import org.thingsboard.server.dao.relation.RelationService;
  104 +import org.thingsboard.server.dao.resource.TbResourceService;
102 import org.thingsboard.server.dao.rule.RuleChainService; 105 import org.thingsboard.server.dao.rule.RuleChainService;
103 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 106 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
104 import org.thingsboard.server.dao.tenant.TenantProfileService; 107 import org.thingsboard.server.dao.tenant.TenantProfileService;
@@ -227,6 +230,9 @@ public abstract class BaseController { @@ -227,6 +230,9 @@ public abstract class BaseController {
227 protected PartitionService partitionService; 230 protected PartitionService partitionService;
228 231
229 @Autowired 232 @Autowired
  233 + protected TbResourceService resourceService;
  234 +
  235 + @Autowired
230 protected TbQueueProducerProvider producerProvider; 236 protected TbQueueProducerProvider producerProvider;
231 237
232 @Autowired 238 @Autowired
@@ -461,6 +467,9 @@ public abstract class BaseController { @@ -461,6 +467,9 @@ public abstract class BaseController {
461 case WIDGET_TYPE: 467 case WIDGET_TYPE:
462 checkWidgetTypeId(new WidgetTypeId(entityId.getId()), operation); 468 checkWidgetTypeId(new WidgetTypeId(entityId.getId()), operation);
463 return; 469 return;
  470 + case TB_RESOURCE:
  471 + checkResourceId(new TbResourceId(entityId.getId()), operation);
  472 + return;
464 default: 473 default:
465 throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); 474 throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType());
466 } 475 }
@@ -668,6 +677,30 @@ public abstract class BaseController { @@ -668,6 +677,30 @@ public abstract class BaseController {
668 return ruleNode; 677 return ruleNode;
669 } 678 }
670 679
  680 + TbResource checkResourceId(TbResourceId resourceId, Operation operation) throws ThingsboardException {
  681 + try {
  682 + validateId(resourceId, "Incorrect resourceId " + resourceId);
  683 + TbResource resource = resourceService.findResourceById(getCurrentUser().getTenantId(), resourceId);
  684 + checkNotNull(resource);
  685 + accessControlService.checkPermission(getCurrentUser(), Resource.TB_RESOURCE, operation, resourceId, resource);
  686 + return resource;
  687 + } catch (Exception e) {
  688 + throw handleException(e, false);
  689 + }
  690 + }
  691 +
  692 + TbResourceInfo checkResourceInfoId(TbResourceId resourceId, Operation operation) throws ThingsboardException {
  693 + try {
  694 + validateId(resourceId, "Incorrect resourceId " + resourceId);
  695 + TbResourceInfo resourceInfo = resourceService.findResourceInfoById(getCurrentUser().getTenantId(), resourceId);
  696 + checkNotNull(resourceInfo);
  697 + accessControlService.checkPermission(getCurrentUser(), Resource.TB_RESOURCE, operation, resourceId, resourceInfo);
  698 + return resourceInfo;
  699 + } catch (Exception e) {
  700 + throw handleException(e, false);
  701 + }
  702 + }
  703 +
671 @SuppressWarnings("unchecked") 704 @SuppressWarnings("unchecked")
672 protected <I extends EntityId> I emptyId(EntityType entityType) { 705 protected <I extends EntityId> I emptyId(EntityType entityType) {
673 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); 706 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
@@ -884,8 +917,8 @@ public abstract class BaseController { @@ -884,8 +917,8 @@ public abstract class BaseController {
884 917
885 protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException { 918 protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException {
886 String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null; 919 String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null;
887 - if(dashboardId != null && !dashboardId.equals("null")) {  
888 - if(dashboardService.findDashboardById(getTenantId(), new DashboardId(UUID.fromString(dashboardId))) == null) { 920 + if (dashboardId != null && !dashboardId.equals("null")) {
  921 + if (dashboardService.findDashboardById(getTenantId(), new DashboardId(UUID.fromString(dashboardId))) == null) {
889 additionalInfo.remove(requiredFields); 922 additionalInfo.remove(requiredFields);
890 } 923 }
891 } 924 }
application/src/main/java/org/thingsboard/server/controller/TbResourceController.java renamed from application/src/main/java/org/thingsboard/server/controller/ResourceController.java
@@ -18,20 +18,23 @@ package org.thingsboard.server.controller; @@ -18,20 +18,23 @@ package org.thingsboard.server.controller;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.security.access.prepost.PreAuthorize; 19 import org.springframework.security.access.prepost.PreAuthorize;
20 import org.springframework.web.bind.annotation.PathVariable; 20 import org.springframework.web.bind.annotation.PathVariable;
  21 +import org.springframework.web.bind.annotation.RequestBody;
21 import org.springframework.web.bind.annotation.RequestMapping; 22 import org.springframework.web.bind.annotation.RequestMapping;
22 import org.springframework.web.bind.annotation.RequestMethod; 23 import org.springframework.web.bind.annotation.RequestMethod;
23 import org.springframework.web.bind.annotation.RequestParam; 24 import org.springframework.web.bind.annotation.RequestParam;
24 import org.springframework.web.bind.annotation.ResponseBody; 25 import org.springframework.web.bind.annotation.ResponseBody;
25 import org.springframework.web.bind.annotation.RestController; 26 import org.springframework.web.bind.annotation.RestController;
26 -import org.thingsboard.server.common.data.Resource;  
27 -import org.thingsboard.server.common.data.ResourceType; 27 +import org.thingsboard.server.common.data.TbResource;
  28 +import org.thingsboard.server.common.data.TbResourceInfo;
28 import org.thingsboard.server.common.data.exception.ThingsboardException; 29 import org.thingsboard.server.common.data.exception.ThingsboardException;
29 -import org.thingsboard.server.common.data.id.TenantId; 30 +import org.thingsboard.server.common.data.id.TbResourceId;
30 import org.thingsboard.server.common.data.lwm2m.LwM2mObject; 31 import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
31 import org.thingsboard.server.common.data.page.PageData; 32 import org.thingsboard.server.common.data.page.PageData;
32 import org.thingsboard.server.common.data.page.PageLink; 33 import org.thingsboard.server.common.data.page.PageLink;
33 -import org.thingsboard.server.dao.resource.ResourceService; 34 +import org.thingsboard.server.dao.resource.TbResourceService;
34 import org.thingsboard.server.queue.util.TbCoreComponent; 35 import org.thingsboard.server.queue.util.TbCoreComponent;
  36 +import org.thingsboard.server.service.security.permission.Operation;
  37 +import org.thingsboard.server.service.security.permission.Resource;
35 38
36 import java.util.List; 39 import java.util.List;
37 40
@@ -39,21 +42,50 @@ import java.util.List; @@ -39,21 +42,50 @@ import java.util.List;
39 @RestController 42 @RestController
40 @TbCoreComponent 43 @TbCoreComponent
41 @RequestMapping("/api") 44 @RequestMapping("/api")
42 -public class ResourceController extends BaseController { 45 +public class TbResourceController extends BaseController {
43 46
44 - private final ResourceService resourceService; 47 + public static final String RESOURCE_ID = "resourceId";
45 48
46 - public ResourceController(ResourceService resourceService) { 49 + private final TbResourceService resourceService;
  50 +
  51 + public TbResourceController(TbResourceService resourceService) {
47 this.resourceService = resourceService; 52 this.resourceService = resourceService;
48 } 53 }
49 54
50 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") 55 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
  56 + @RequestMapping(value = "/resource/info/{resourceId}", method = RequestMethod.GET)
  57 + @ResponseBody
  58 + public TbResourceInfo getResourceInfoById(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
  59 + checkParameter(RESOURCE_ID, strResourceId);
  60 + try {
  61 + TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
  62 + return checkResourceInfoId(resourceId, Operation.READ);
  63 + } catch (Exception e) {
  64 + throw handleException(e);
  65 + }
  66 + }
  67 +
  68 + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
  69 + @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.GET)
  70 + @ResponseBody
  71 + public TbResource getResourceById(@PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException {
  72 + checkParameter(RESOURCE_ID, strResourceId);
  73 + try {
  74 + TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
  75 + return checkResourceId(resourceId, Operation.READ);
  76 + } catch (Exception e) {
  77 + throw handleException(e);
  78 + }
  79 + }
  80 +
  81 + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
51 @RequestMapping(value = "/resource", method = RequestMethod.POST) 82 @RequestMapping(value = "/resource", method = RequestMethod.POST)
52 @ResponseBody 83 @ResponseBody
53 - public Resource saveResource(Resource resource) throws ThingsboardException { 84 + public TbResource saveResource(@RequestBody TbResource resource) throws ThingsboardException {
54 try { 85 try {
55 resource.setTenantId(getTenantId()); 86 resource.setTenantId(getTenantId());
56 - Resource savedResource = checkNotNull(resourceService.saveResource(resource)); 87 + checkEntity(resource.getId(), resource, Resource.TB_RESOURCE);
  88 + TbResource savedResource = checkNotNull(resourceService.saveResource(resource));
57 tbClusterService.onResourceChange(savedResource, null); 89 tbClusterService.onResourceChange(savedResource, null);
58 return savedResource; 90 return savedResource;
59 } catch (Exception e) { 91 } catch (Exception e) {
@@ -64,15 +96,14 @@ public class ResourceController extends BaseController { @@ -64,15 +96,14 @@ public class ResourceController extends BaseController {
64 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") 96 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
65 @RequestMapping(value = "/resource", method = RequestMethod.GET) 97 @RequestMapping(value = "/resource", method = RequestMethod.GET)
66 @ResponseBody 98 @ResponseBody
67 - public PageData<Resource> getResources(@RequestParam(required = false) boolean system,  
68 - @RequestParam int pageSize,  
69 - @RequestParam int page,  
70 - @RequestParam(required = false) String textSearch,  
71 - @RequestParam(required = false) String sortProperty,  
72 - @RequestParam(required = false) String sortOrder) throws ThingsboardException { 99 + public PageData<TbResourceInfo> getResources(@RequestParam int pageSize,
  100 + @RequestParam int page,
  101 + @RequestParam(required = false) String textSearch,
  102 + @RequestParam(required = false) String sortProperty,
  103 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
73 try { 104 try {
74 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 105 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
75 - return checkNotNull(resourceService.findResourcesByTenantId(system ? TenantId.SYS_TENANT_ID : getTenantId(), pageLink)); 106 + return checkNotNull(resourceService.findResourcesByTenantId(getTenantId(), pageLink));
76 } catch (Exception e) { 107 } catch (Exception e) {
77 throw handleException(e); 108 throw handleException(e);
78 } 109 }
@@ -82,10 +113,10 @@ public class ResourceController extends BaseController { @@ -82,10 +113,10 @@ public class ResourceController extends BaseController {
82 @RequestMapping(value = "/resource/lwm2m/page", method = RequestMethod.GET) 113 @RequestMapping(value = "/resource/lwm2m/page", method = RequestMethod.GET)
83 @ResponseBody 114 @ResponseBody
84 public List<LwM2mObject> getLwm2mListObjectsPage(@RequestParam int pageSize, 115 public List<LwM2mObject> getLwm2mListObjectsPage(@RequestParam int pageSize,
85 - @RequestParam int page,  
86 - @RequestParam(required = false) String textSearch,  
87 - @RequestParam(required = false) String sortProperty,  
88 - @RequestParam(required = false) String sortOrder) throws ThingsboardException { 116 + @RequestParam int page,
  117 + @RequestParam(required = false) String textSearch,
  118 + @RequestParam(required = false) String sortProperty,
  119 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
89 try { 120 try {
90 PageLink pageLink = new PageLink(pageSize, page, textSearch); 121 PageLink pageLink = new PageLink(pageSize, page, textSearch);
91 return checkNotNull(resourceService.findLwM2mObjectPage(getTenantId(), sortProperty, sortOrder, pageLink)); 122 return checkNotNull(resourceService.findLwM2mObjectPage(getTenantId(), sortProperty, sortOrder, pageLink));
@@ -95,7 +126,7 @@ public class ResourceController extends BaseController { @@ -95,7 +126,7 @@ public class ResourceController extends BaseController {
95 } 126 }
96 127
97 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 128 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
98 - @RequestMapping(value = "/resource/lwm2m", method = RequestMethod.GET) 129 + @RequestMapping(value = "/resource/lwm2m", method = RequestMethod.GET)
99 @ResponseBody 130 @ResponseBody
100 public List<LwM2mObject> getLwm2mListObjects(@RequestParam String sortOrder, 131 public List<LwM2mObject> getLwm2mListObjects(@RequestParam String sortOrder,
101 @RequestParam String sortProperty, 132 @RequestParam String sortProperty,
@@ -108,14 +139,15 @@ public class ResourceController extends BaseController { @@ -108,14 +139,15 @@ public class ResourceController extends BaseController {
108 } 139 }
109 140
110 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") 141 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
111 - @RequestMapping(value = "/resource/{resourceType}/{resourceId}", method = RequestMethod.DELETE) 142 + @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.DELETE)
112 @ResponseBody 143 @ResponseBody
113 - public void deleteResource(@PathVariable("resourceType") ResourceType resourceType,  
114 - @PathVariable("resourceId") String resourceId) throws ThingsboardException { 144 + public void deleteResource(@PathVariable("resourceId") String strResourceId) throws ThingsboardException {
  145 + checkParameter("resourceId", strResourceId);
115 try { 146 try {
116 - Resource resource = checkNotNull(resourceService.getResource(getTenantId(), resourceType, resourceId));  
117 - resourceService.deleteResource(getTenantId(), resourceType, resourceId);  
118 - tbClusterService.onResourceDeleted(resource, null); 147 + TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
  148 + TbResource tbResource = checkResourceId(resourceId, Operation.DELETE);
  149 + resourceService.deleteResource(getTenantId(), resourceId);
  150 + tbClusterService.onResourceDeleted(tbResource, null);
119 } catch (Exception e) { 151 } catch (Exception e) {
120 throw handleException(e); 152 throw handleException(e);
121 } 153 }
@@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Value; @@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Value;
22 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
23 import org.springframework.util.StringUtils; 23 import org.springframework.util.StringUtils;
24 import org.thingsboard.server.common.data.Dashboard; 24 import org.thingsboard.server.common.data.Dashboard;
25 -import org.thingsboard.server.common.data.Resource;  
26 import org.thingsboard.server.common.data.ResourceType; 25 import org.thingsboard.server.common.data.ResourceType;
  26 +import org.thingsboard.server.common.data.TbResource;
27 import org.thingsboard.server.common.data.id.CustomerId; 27 import org.thingsboard.server.common.data.id.CustomerId;
28 import org.thingsboard.server.common.data.id.EntityId; 28 import org.thingsboard.server.common.data.id.EntityId;
29 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
@@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
35 import org.thingsboard.server.dao.dashboard.DashboardService; 35 import org.thingsboard.server.dao.dashboard.DashboardService;
36 import org.thingsboard.server.dao.exception.DataValidationException; 36 import org.thingsboard.server.dao.exception.DataValidationException;
37 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; 37 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
38 -import org.thingsboard.server.dao.resource.ResourceService; 38 +import org.thingsboard.server.dao.resource.TbResourceService;
39 import org.thingsboard.server.dao.rule.RuleChainService; 39 import org.thingsboard.server.dao.rule.RuleChainService;
40 import org.thingsboard.server.dao.widget.WidgetTypeService; 40 import org.thingsboard.server.dao.widget.WidgetTypeService;
41 import org.thingsboard.server.dao.widget.WidgetsBundleService; 41 import org.thingsboard.server.dao.widget.WidgetsBundleService;
@@ -95,7 +95,7 @@ public class InstallScripts { @@ -95,7 +95,7 @@ public class InstallScripts {
95 private OAuth2ConfigTemplateService oAuth2TemplateService; 95 private OAuth2ConfigTemplateService oAuth2TemplateService;
96 96
97 @Autowired 97 @Autowired
98 - private ResourceService resourceService; 98 + private TbResourceService resourceService;
99 99
100 public Path getTenantRuleChainsDir() { 100 public Path getTenantRuleChainsDir() {
101 return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, RULE_CHAINS_DIR); 101 return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, RULE_CHAINS_DIR);
@@ -204,13 +204,10 @@ public class InstallScripts { @@ -204,13 +204,10 @@ public class InstallScripts {
204 path -> { 204 path -> {
205 try { 205 try {
206 byte[] fileBytes = Files.readAllBytes(path); 206 byte[] fileBytes = Files.readAllBytes(path);
207 - String source = new String(fileBytes);  
208 - Resource resource = new Resource(); 207 + TbResource resource = new TbResource();
209 resource.setTenantId(TenantId.SYS_TENANT_ID); 208 resource.setTenantId(TenantId.SYS_TENANT_ID);
210 resource.setResourceType(ResourceType.LWM2M_MODEL); 209 resource.setResourceType(ResourceType.LWM2M_MODEL);
211 - resource.setResourceId(getValueByTag(source, "ObjectID") + "_" + getValueByTag(source, "ObjectVersion"));  
212 - resource.setTextSearch(resource.getResourceId() + ":" + getValueByTag(source, "Name"));  
213 - resource.setValue(Base64.getEncoder().encodeToString(fileBytes)); 210 + resource.setData(Base64.getEncoder().encodeToString(fileBytes));
214 resourceService.saveResource(resource); 211 resourceService.saveResource(resource);
215 } catch (Exception e) { 212 } catch (Exception e) {
216 throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", path.toString())); 213 throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", path.toString()));
@@ -219,28 +216,6 @@ public class InstallScripts { @@ -219,28 +216,6 @@ public class InstallScripts {
219 ); 216 );
220 } 217 }
221 } 218 }
222 -  
223 - Path jksPath = Paths.get(getDataDir(), CREDENTIALS_DIR, "serverKeyStore.jks");  
224 - try {  
225 - Resource resource = new Resource();  
226 - resource.setTenantId(TenantId.SYS_TENANT_ID);  
227 - resource.setResourceType(ResourceType.JKS);  
228 - resource.setResourceId(jksPath.getFileName().toString());  
229 - resource.setTextSearch(jksPath.getFileName().toString());  
230 - resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath)));  
231 - resourceService.saveResource(resource);  
232 - } catch (Exception e) {  
233 - log.error("Unable to load lwm2m serverKeyStore [{}]", jksPath.toString());  
234 - throw new RuntimeException("Unable to load lwm2m serverKeyStore", e);  
235 - }  
236 - }  
237 -  
238 - private String getValueByTag(String source, String tag) {  
239 - int lenTag = ("<" + tag + ">").length();  
240 - int indStart = source.indexOf("<" + tag + ">");  
241 - int indEnd = source.indexOf("</" + tag + ">");  
242 - return (indStart > 0 && indEnd > 0) ? source.substring(indStart + lenTag, indEnd) : null;  
243 -  
244 } 219 }
245 220
246 public void loadDashboards(TenantId tenantId, CustomerId customerId) throws Exception { 221 public void loadDashboards(TenantId tenantId, CustomerId customerId) throws Exception {
@@ -450,14 +450,17 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService @@ -450,14 +450,17 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
450 try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { 450 try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
451 log.info("Updating schema ..."); 451 log.info("Updating schema ...");
452 try { 452 try {
453 - conn.createStatement().execute("CREATE TABLE IF NOT EXISTS resource (" +  
454 - " tenant_id uuid NOT NULL," +  
455 - " resource_type varchar(32) NOT NULL," +  
456 - " resource_id varchar(255) NOT NULL," +  
457 - " text_search varchar(255)," +  
458 - " resource_value varchar," +  
459 - " CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_id)" +  
460 - " );"); 453 + conn.createStatement().execute("CREATE TABLE IF NOT EXISTS resource ( " +
  454 + "id uuid NOT NULL CONSTRAINT resource_pkey PRIMARY KEY, " +
  455 + "created_time bigint NOT NULL, " +
  456 + "tenant_id uuid NOT NULL, " +
  457 + "title varchar(255) NOT NULL, " +
  458 + "resource_type varchar(32) NOT NULL, " +
  459 + "resource_key varchar(255) NOT NULL, " +
  460 + "search_text varchar(255), " +
  461 + "data varchar, " +
  462 + "CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)" +
  463 + ");");
461 464
462 conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3003000;"); 465 conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3003000;");
463 installScripts.loadSystemLwm2mResources(); 466 installScripts.loadSystemLwm2mResources();
@@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.Device; @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.Device;
26 import org.thingsboard.server.common.data.DeviceProfile; 26 import org.thingsboard.server.common.data.DeviceProfile;
27 import org.thingsboard.server.common.data.EntityType; 27 import org.thingsboard.server.common.data.EntityType;
28 import org.thingsboard.server.common.data.HasName; 28 import org.thingsboard.server.common.data.HasName;
29 -import org.thingsboard.server.common.data.Resource; 29 +import org.thingsboard.server.common.data.TbResource;
30 import org.thingsboard.server.common.data.Tenant; 30 import org.thingsboard.server.common.data.Tenant;
31 import org.thingsboard.server.common.data.TenantProfile; 31 import org.thingsboard.server.common.data.TenantProfile;
32 import org.thingsboard.server.common.data.id.DeviceId; 32 import org.thingsboard.server.common.data.id.DeviceId;
@@ -249,28 +249,27 @@ public class DefaultTbClusterService implements TbClusterService { @@ -249,28 +249,27 @@ public class DefaultTbClusterService implements TbClusterService {
249 } 249 }
250 250
251 @Override 251 @Override
252 - public void onResourceChange(Resource resource, TbQueueCallback callback) { 252 + public void onResourceChange(TbResource resource, TbQueueCallback callback) {
253 TenantId tenantId = resource.getTenantId(); 253 TenantId tenantId = resource.getTenantId();
254 - log.trace("[{}][{}][{}] Processing change resource", tenantId, resource.getResourceType(), resource.getResourceId()); 254 + log.trace("[{}][{}][{}] Processing change resource", tenantId, resource.getResourceType(), resource.getResourceKey());
255 TransportProtos.ResourceUpdateMsg resourceUpdateMsg = TransportProtos.ResourceUpdateMsg.newBuilder() 255 TransportProtos.ResourceUpdateMsg resourceUpdateMsg = TransportProtos.ResourceUpdateMsg.newBuilder()
256 .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) 256 .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
257 .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) 257 .setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
258 .setResourceType(resource.getResourceType().name()) 258 .setResourceType(resource.getResourceType().name())
259 - .setResourceId(resource.getResourceId()) 259 + .setResourceKey(resource.getResourceKey())
260 .build(); 260 .build();
261 ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceUpdateMsg(resourceUpdateMsg).build(); 261 ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceUpdateMsg(resourceUpdateMsg).build();
262 broadcast(transportMsg, callback); 262 broadcast(transportMsg, callback);
263 } 263 }
264 264
265 @Override 265 @Override
266 - public void onResourceDeleted(Resource resource, TbQueueCallback callback) {  
267 - TenantId tenantId = resource.getTenantId();  
268 - log.trace("[{}][{}][{}] Processing delete resource", tenantId, resource.getResourceType(), resource.getResourceId()); 266 + public void onResourceDeleted(TbResource resource, TbQueueCallback callback) {
  267 + log.trace("[{}] Processing delete resource", resource);
269 TransportProtos.ResourceDeleteMsg resourceUpdateMsg = TransportProtos.ResourceDeleteMsg.newBuilder() 268 TransportProtos.ResourceDeleteMsg resourceUpdateMsg = TransportProtos.ResourceDeleteMsg.newBuilder()
270 - .setTenantIdMSB(tenantId.getId().getMostSignificantBits())  
271 - .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) 269 + .setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits())
  270 + .setTenantIdLSB(resource.getTenantId().getId().getLeastSignificantBits())
272 .setResourceType(resource.getResourceType().name()) 271 .setResourceType(resource.getResourceType().name())
273 - .setResourceId(resource.getResourceId()) 272 + .setResourceKey(resource.getResourceKey())
274 .build(); 273 .build();
275 ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceDeleteMsg(resourceUpdateMsg).build(); 274 ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setResourceDeleteMsg(resourceUpdateMsg).build();
276 broadcast(transportMsg, callback); 275 broadcast(transportMsg, callback);
@@ -19,7 +19,7 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; @@ -19,7 +19,7 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
19 import org.thingsboard.server.common.data.ApiUsageState; 19 import org.thingsboard.server.common.data.ApiUsageState;
20 import org.thingsboard.server.common.data.Device; 20 import org.thingsboard.server.common.data.Device;
21 import org.thingsboard.server.common.data.DeviceProfile; 21 import org.thingsboard.server.common.data.DeviceProfile;
22 -import org.thingsboard.server.common.data.Resource; 22 +import org.thingsboard.server.common.data.TbResource;
23 import org.thingsboard.server.common.data.Tenant; 23 import org.thingsboard.server.common.data.Tenant;
24 import org.thingsboard.server.common.data.TenantProfile; 24 import org.thingsboard.server.common.data.TenantProfile;
25 import org.thingsboard.server.common.data.id.EntityId; 25 import org.thingsboard.server.common.data.id.EntityId;
@@ -73,7 +73,7 @@ public interface TbClusterService { @@ -73,7 +73,7 @@ public interface TbClusterService {
73 73
74 void onDeviceDeleted(Device device, TbQueueCallback callback); 74 void onDeviceDeleted(Device device, TbQueueCallback callback);
75 75
76 - void onResourceChange(Resource resource, TbQueueCallback callback); 76 + void onResourceChange(TbResource resource, TbQueueCallback callback);
77 77
78 - void onResourceDeleted(Resource resource, TbQueueCallback callback); 78 + void onResourceDeleted(TbResource resource, TbQueueCallback callback);
79 } 79 }
@@ -36,7 +36,8 @@ public enum Resource { @@ -36,7 +36,8 @@ public enum Resource {
36 OAUTH2_CONFIGURATION_TEMPLATE(), 36 OAUTH2_CONFIGURATION_TEMPLATE(),
37 TENANT_PROFILE(EntityType.TENANT_PROFILE), 37 TENANT_PROFILE(EntityType.TENANT_PROFILE),
38 DEVICE_PROFILE(EntityType.DEVICE_PROFILE), 38 DEVICE_PROFILE(EntityType.DEVICE_PROFILE),
39 - API_USAGE_STATE(EntityType.API_USAGE_STATE); 39 + API_USAGE_STATE(EntityType.API_USAGE_STATE),
  40 + TB_RESOURCE(EntityType.TB_RESOURCE);
40 41
41 private final EntityType entityType; 42 private final EntityType entityType;
42 43
@@ -38,6 +38,7 @@ public class SysAdminPermissions extends AbstractPermissions { @@ -38,6 +38,7 @@ public class SysAdminPermissions extends AbstractPermissions {
38 put(Resource.OAUTH2_CONFIGURATION_INFO, PermissionChecker.allowAllPermissionChecker); 38 put(Resource.OAUTH2_CONFIGURATION_INFO, PermissionChecker.allowAllPermissionChecker);
39 put(Resource.OAUTH2_CONFIGURATION_TEMPLATE, PermissionChecker.allowAllPermissionChecker); 39 put(Resource.OAUTH2_CONFIGURATION_TEMPLATE, PermissionChecker.allowAllPermissionChecker);
40 put(Resource.TENANT_PROFILE, PermissionChecker.allowAllPermissionChecker); 40 put(Resource.TENANT_PROFILE, PermissionChecker.allowAllPermissionChecker);
  41 + put(Resource.TB_RESOURCE, systemEntityPermissionChecker);
41 } 42 }
42 43
43 private static final PermissionChecker systemEntityPermissionChecker = new PermissionChecker() { 44 private static final PermissionChecker systemEntityPermissionChecker = new PermissionChecker() {
@@ -41,6 +41,7 @@ public class TenantAdminPermissions extends AbstractPermissions { @@ -41,6 +41,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
41 put(Resource.WIDGET_TYPE, widgetsPermissionChecker); 41 put(Resource.WIDGET_TYPE, widgetsPermissionChecker);
42 put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker); 42 put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker);
43 put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker); 43 put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker);
  44 + put(Resource.TB_RESOURCE, tbResourcePermissionChecker);
44 } 45 }
45 46
46 public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() { 47 public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() {
@@ -101,4 +102,19 @@ public class TenantAdminPermissions extends AbstractPermissions { @@ -101,4 +102,19 @@ public class TenantAdminPermissions extends AbstractPermissions {
101 } 102 }
102 103
103 }; 104 };
  105 +
  106 + private static final PermissionChecker tbResourcePermissionChecker = new PermissionChecker() {
  107 +
  108 + @Override
  109 + public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
  110 + if (entity.getTenantId() == null || entity.getTenantId().isNullUid()) {
  111 + return operation == Operation.READ;
  112 + }
  113 + if (!user.getTenantId().equals(entity.getTenantId())) {
  114 + return false;
  115 + }
  116 + return true;
  117 + }
  118 +
  119 + };
104 } 120 }
@@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.DataConstants; @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.DataConstants;
31 import org.thingsboard.server.common.data.Device; 31 import org.thingsboard.server.common.data.Device;
32 import org.thingsboard.server.common.data.DeviceProfile; 32 import org.thingsboard.server.common.data.DeviceProfile;
33 import org.thingsboard.server.common.data.EntityType; 33 import org.thingsboard.server.common.data.EntityType;
34 -import org.thingsboard.server.common.data.Resource; 34 +import org.thingsboard.server.common.data.TbResource;
35 import org.thingsboard.server.common.data.ResourceType; 35 import org.thingsboard.server.common.data.ResourceType;
36 import org.thingsboard.server.common.data.TenantProfile; 36 import org.thingsboard.server.common.data.TenantProfile;
37 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; 37 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
@@ -56,7 +56,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; @@ -56,7 +56,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
56 import org.thingsboard.server.dao.device.provision.ProvisionRequest; 56 import org.thingsboard.server.dao.device.provision.ProvisionRequest;
57 import org.thingsboard.server.dao.device.provision.ProvisionResponse; 57 import org.thingsboard.server.dao.device.provision.ProvisionResponse;
58 import org.thingsboard.server.dao.relation.RelationService; 58 import org.thingsboard.server.dao.relation.RelationService;
59 -import org.thingsboard.server.dao.resource.ResourceService; 59 +import org.thingsboard.server.dao.resource.TbResourceService;
60 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 60 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
61 import org.thingsboard.server.gen.transport.TransportProtos; 61 import org.thingsboard.server.gen.transport.TransportProtos;
62 import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; 62 import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto;
@@ -108,7 +108,7 @@ public class DefaultTransportApiService implements TransportApiService { @@ -108,7 +108,7 @@ public class DefaultTransportApiService implements TransportApiService {
108 private final TbClusterService tbClusterService; 108 private final TbClusterService tbClusterService;
109 private final DataDecodingEncodingService dataDecodingEncodingService; 109 private final DataDecodingEncodingService dataDecodingEncodingService;
110 private final DeviceProvisionService deviceProvisionService; 110 private final DeviceProvisionService deviceProvisionService;
111 - private final ResourceService resourceService; 111 + private final TbResourceService resourceService;
112 112
113 private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); 113 private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>();
114 114
@@ -117,7 +117,7 @@ public class DefaultTransportApiService implements TransportApiService { @@ -117,7 +117,7 @@ public class DefaultTransportApiService implements TransportApiService {
117 RelationService relationService, DeviceCredentialsService deviceCredentialsService, 117 RelationService relationService, DeviceCredentialsService deviceCredentialsService,
118 DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, 118 DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService,
119 TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, 119 TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService,
120 - DeviceProvisionService deviceProvisionService, ResourceService resourceService) { 120 + DeviceProvisionService deviceProvisionService, TbResourceService resourceService) {
121 this.deviceProfileCache = deviceProfileCache; 121 this.deviceProfileCache = deviceProfileCache;
122 this.tenantProfileCache = tenantProfileCache; 122 this.tenantProfileCache = tenantProfileCache;
123 this.apiUsageStateService = apiUsageStateService; 123 this.apiUsageStateService = apiUsageStateService;
@@ -365,12 +365,12 @@ public class DefaultTransportApiService implements TransportApiService { @@ -365,12 +365,12 @@ public class DefaultTransportApiService implements TransportApiService {
365 private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) { 365 private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) {
366 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); 366 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
367 ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType()); 367 ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType());
368 - String resourceId = requestMsg.getResourceId(); 368 + String resourceKey = requestMsg.getResourceKey();
369 TransportProtos.GetResourceResponseMsg.Builder builder = TransportProtos.GetResourceResponseMsg.newBuilder(); 369 TransportProtos.GetResourceResponseMsg.Builder builder = TransportProtos.GetResourceResponseMsg.newBuilder();
370 - Resource resource = resourceService.getResource(tenantId, resourceType, resourceId); 370 + TbResource resource = resourceService.getResource(tenantId, resourceType, resourceKey);
371 371
372 if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) { 372 if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) {
373 - resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceId); 373 + resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceKey);
374 } 374 }
375 375
376 if (resource != null) { 376 if (resource != null) {
common/dao-api/src/main/java/org/thingsboard/server/dao/resource/TbResourceService.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java
@@ -15,24 +15,30 @@ @@ -15,24 +15,30 @@
15 */ 15 */
16 package org.thingsboard.server.dao.resource; 16 package org.thingsboard.server.dao.resource;
17 17
18 -import org.thingsboard.server.common.data.Resource; 18 +import org.eclipse.leshan.core.model.InvalidDDFFileException;
  19 +import org.thingsboard.server.common.data.TbResource;
  20 +import org.thingsboard.server.common.data.TbResourceInfo;
19 import org.thingsboard.server.common.data.ResourceType; 21 import org.thingsboard.server.common.data.ResourceType;
  22 +import org.thingsboard.server.common.data.id.TbResourceId;
20 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.lwm2m.LwM2mObject; 24 import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
22 import org.thingsboard.server.common.data.page.PageData; 25 import org.thingsboard.server.common.data.page.PageData;
23 import org.thingsboard.server.common.data.page.PageLink; 26 import org.thingsboard.server.common.data.page.PageLink;
24 27
  28 +import java.io.IOException;
25 import java.util.List; 29 import java.util.List;
26 30
27 31
28 -public interface ResourceService {  
29 - Resource saveResource(Resource resource); 32 +public interface TbResourceService {
  33 + TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException;
30 34
31 - Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); 35 + TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
32 36
33 - PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink); 37 + TbResource findResourceById(TenantId tenantId, TbResourceId resourceId);
34 38
35 - List<Resource> findAllByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType); 39 + TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId);
  40 +
  41 + PageData<TbResourceInfo> findResourcesByTenantId(TenantId tenantId, PageLink pageLink);
36 42
37 List<LwM2mObject> findLwM2mObject(TenantId tenantId, 43 List<LwM2mObject> findLwM2mObject(TenantId tenantId,
38 String sortOrder, 44 String sortOrder,
@@ -44,7 +50,7 @@ public interface ResourceService { @@ -44,7 +50,7 @@ public interface ResourceService {
44 String sortOrder, 50 String sortOrder,
45 PageLink pageLink); 51 PageLink pageLink);
46 52
47 - void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); 53 + void deleteResource(TenantId tenantId, TbResourceId resourceId);
48 54
49 void deleteResourcesByTenantId(TenantId tenantId); 55 void deleteResourcesByTenantId(TenantId tenantId);
50 } 56 }
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
19 * @author Andrew Shvayka 19 * @author Andrew Shvayka
20 */ 20 */
21 public enum EntityType { 21 public enum EntityType {
22 - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE; 22 + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE;
23 } 23 }
common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/Resource.java
@@ -16,31 +16,54 @@ @@ -16,31 +16,54 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 import lombok.Data; 18 import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
19 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
20 -import org.thingsboard.server.common.data.id.TenantId;  
21 -  
22 -import java.io.Serializable; 21 +import org.thingsboard.server.common.data.id.TbResourceId;
23 22
24 @Slf4j 23 @Slf4j
25 @Data 24 @Data
26 -public class Resource implements HasTenantId, Serializable { 25 +@EqualsAndHashCode(callSuper = true)
  26 +public class TbResource extends TbResourceInfo {
27 27
28 private static final long serialVersionUID = 7379609705527272306L; 28 private static final long serialVersionUID = 7379609705527272306L;
29 29
30 - private TenantId tenantId;  
31 - private ResourceType resourceType;  
32 - private String resourceId;  
33 - private String textSearch;  
34 - private String value; 30 + private String data;
  31 +
  32 + public TbResource() {
  33 + super();
  34 + }
  35 +
  36 + public TbResource(TbResourceId id) {
  37 + super(id);
  38 + }
  39 +
  40 + public TbResource(TbResourceInfo resourceInfo) {
  41 + super(resourceInfo);
  42 + }
  43 +
  44 + public TbResource(TbResource resource) {
  45 + super(resource);
  46 + this.data = resource.getData();
  47 + }
35 48
36 @Override 49 @Override
37 public String toString() { 50 public String toString() {
38 - final StringBuilder res = new StringBuilder("Resource{");  
39 - res.append("tenantId=").append(tenantId);  
40 - res.append(", resourceType='").append(resourceType).append('\'');  
41 - res.append(", resourceId='").append(resourceId).append('\'');  
42 - res.append(", textSearch='").append(textSearch).append('\'');  
43 - res.append('}');  
44 - return res.toString(); 51 + StringBuilder builder = new StringBuilder();
  52 + builder.append("Resource [tenantId=");
  53 + builder.append(getTenantId());
  54 + builder.append(", id=");
  55 + builder.append(getUuidId());
  56 + builder.append(", createdTime=");
  57 + builder.append(createdTime);
  58 + builder.append(", title=");
  59 + builder.append(getTitle());
  60 + builder.append(", resourceType=");
  61 + builder.append(getResourceType());
  62 + builder.append(", resourceKey=");
  63 + builder.append(getResourceKey());
  64 + builder.append(", data=");
  65 + builder.append(data);
  66 + builder.append("]");
  67 + return builder.toString();
45 } 68 }
46 } 69 }
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import lombok.extern.slf4j.Slf4j;
  21 +import org.thingsboard.server.common.data.id.TbResourceId;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +
  24 +@Slf4j
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasTenantId {
  28 +
  29 + private TenantId tenantId;
  30 + private String title;
  31 + private ResourceType resourceType;
  32 + private String resourceKey;
  33 + private String searchText;
  34 +
  35 + public TbResourceInfo() {
  36 + super();
  37 + }
  38 +
  39 + public TbResourceInfo(TbResourceId id) {
  40 + super(id);
  41 + }
  42 +
  43 + public TbResourceInfo(TbResourceInfo resourceInfo) {
  44 + super(resourceInfo);
  45 + this.tenantId = resourceInfo.getTenantId();
  46 + this.title = resourceInfo.getTitle();
  47 + this.resourceType = resourceInfo.getResourceType();
  48 + this.resourceKey = resourceInfo.resourceKey;
  49 + }
  50 +
  51 + @Override
  52 + public String getSearchText() {
  53 + return searchText;
  54 + }
  55 +
  56 + @Override
  57 + public String toString() {
  58 + StringBuilder builder = new StringBuilder();
  59 + builder.append("ResourceInfo [tenantId=");
  60 + builder.append(tenantId);
  61 + builder.append(", id=");
  62 + builder.append(getUuidId());
  63 + builder.append(", createdTime=");
  64 + builder.append(createdTime);
  65 + builder.append(", title=");
  66 + builder.append(title);
  67 + builder.append(", resourceType=");
  68 + builder.append(resourceType);
  69 + builder.append(", resourceKey=");
  70 + builder.append(resourceKey);
  71 + builder.append("]");
  72 + return builder.toString();
  73 + }
  74 +}
@@ -68,6 +68,8 @@ public class EntityIdFactory { @@ -68,6 +68,8 @@ public class EntityIdFactory {
68 return new TenantProfileId(uuid); 68 return new TenantProfileId(uuid);
69 case API_USAGE_STATE: 69 case API_USAGE_STATE:
70 return new ApiUsageStateId(uuid); 70 return new ApiUsageStateId(uuid);
  71 + case TB_RESOURCE:
  72 + return new TbResourceId(uuid);
71 } 73 }
72 throw new IllegalArgumentException("EntityType " + type + " is not supported!"); 74 throw new IllegalArgumentException("EntityType " + type + " is not supported!");
73 } 75 }
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.id;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonIgnore;
  20 +import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import org.thingsboard.server.common.data.EntityType;
  22 +
  23 +import java.util.UUID;
  24 +
  25 +public class TbResourceId extends UUIDBased implements EntityId {
  26 +
  27 + private static final long serialVersionUID = 1L;
  28 +
  29 + @JsonCreator
  30 + public TbResourceId(@JsonProperty("id") UUID id) {
  31 + super(id);
  32 + }
  33 +
  34 + @JsonIgnore
  35 + @Override
  36 + public EntityType getEntityType() {
  37 + return EntityType.TB_RESOURCE;
  38 + }
  39 +}
@@ -205,7 +205,7 @@ message GetResourceRequestMsg { @@ -205,7 +205,7 @@ message GetResourceRequestMsg {
205 int64 tenantIdMSB = 1; 205 int64 tenantIdMSB = 1;
206 int64 tenantIdLSB = 2; 206 int64 tenantIdLSB = 2;
207 string resourceType = 3; 207 string resourceType = 3;
208 - string resourceId = 4; 208 + string resourceKey = 4;
209 } 209 }
210 210
211 message GetResourceResponseMsg { 211 message GetResourceResponseMsg {
@@ -257,14 +257,14 @@ message ResourceUpdateMsg { @@ -257,14 +257,14 @@ message ResourceUpdateMsg {
257 int64 tenantIdMSB = 1; 257 int64 tenantIdMSB = 1;
258 int64 tenantIdLSB = 2; 258 int64 tenantIdLSB = 2;
259 string resourceType = 3; 259 string resourceType = 3;
260 - string resourceId = 4; 260 + string resourceKey = 4;
261 } 261 }
262 262
263 message ResourceDeleteMsg { 263 message ResourceDeleteMsg {
264 int64 tenantIdMSB = 1; 264 int64 tenantIdMSB = 1;
265 int64 tenantIdLSB = 2; 265 int64 tenantIdLSB = 2;
266 string resourceType = 3; 266 string resourceType = 3;
267 - string resourceId = 4; 267 + string resourceKey = 4;
268 } 268 }
269 269
270 message SessionCloseNotificationProto { 270 message SessionCloseNotificationProto {
@@ -124,7 +124,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { @@ -124,7 +124,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
124 this.tenantId, 124 this.tenantId,
125 LWM2M_MODEL, 125 LWM2M_MODEL,
126 key). 126 key).
127 - getValue(); 127 + getData();
128 return xmlB64 != null && !xmlB64.isEmpty() ? 128 return xmlB64 != null && !xmlB64.isEmpty() ?
129 lwM2mTransportContextServer.parseFromXmlToObjectModel( 129 lwM2mTransportContextServer.parseFromXmlToObjectModel(
130 Base64.getDecoder().decode(xmlB64), 130 Base64.getDecoder().decode(xmlB64),
@@ -15,13 +15,13 @@ @@ -15,13 +15,13 @@
15 */ 15 */
16 package org.thingsboard.server.common.transport; 16 package org.thingsboard.server.common.transport;
17 17
18 -import org.thingsboard.server.common.data.Resource; 18 +import org.thingsboard.server.common.data.TbResource;
19 import org.thingsboard.server.common.data.ResourceType; 19 import org.thingsboard.server.common.data.ResourceType;
20 import org.thingsboard.server.common.data.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
21 21
22 public interface TransportResourceCache { 22 public interface TransportResourceCache {
23 23
24 - Resource get(TenantId tenantId, ResourceType resourceType, String resourceId); 24 + TbResource get(TenantId tenantId, ResourceType resourceType, String resourceId);
25 25
26 void update(TenantId tenantId, ResourceType resourceType, String resourceI); 26 void update(TenantId tenantId, ResourceType resourceType, String resourceI);
27 27
@@ -19,7 +19,7 @@ import lombok.Data; @@ -19,7 +19,7 @@ import lombok.Data;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.context.annotation.Lazy; 20 import org.springframework.context.annotation.Lazy;
21 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
22 -import org.thingsboard.server.common.data.Resource; 22 +import org.thingsboard.server.common.data.TbResource;
23 import org.thingsboard.server.common.data.ResourceType; 23 import org.thingsboard.server.common.data.ResourceType;
24 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
25 import org.thingsboard.server.common.transport.TransportResourceCache; 25 import org.thingsboard.server.common.transport.TransportResourceCache;
@@ -42,8 +42,8 @@ import java.util.concurrent.locks.ReentrantLock; @@ -42,8 +42,8 @@ import java.util.concurrent.locks.ReentrantLock;
42 public class DefaultTransportResourceCache implements TransportResourceCache { 42 public class DefaultTransportResourceCache implements TransportResourceCache {
43 43
44 private final Lock resourceFetchLock = new ReentrantLock(); 44 private final Lock resourceFetchLock = new ReentrantLock();
45 - private final ConcurrentMap<ResourceKey, Resource> resources = new ConcurrentHashMap<>();  
46 - private final Set<ResourceKey> keys = ConcurrentHashMap.newKeySet(); 45 + private final ConcurrentMap<ResourceCompositeKey, TbResource> resources = new ConcurrentHashMap<>();
  46 + private final Set<ResourceCompositeKey> keys = ConcurrentHashMap.newKeySet();
47 private final DataDecodingEncodingService dataDecodingEncodingService; 47 private final DataDecodingEncodingService dataDecodingEncodingService;
48 private final TransportService transportService; 48 private final TransportService transportService;
49 49
@@ -53,26 +53,26 @@ public class DefaultTransportResourceCache implements TransportResourceCache { @@ -53,26 +53,26 @@ public class DefaultTransportResourceCache implements TransportResourceCache {
53 } 53 }
54 54
55 @Override 55 @Override
56 - public Resource get(TenantId tenantId, ResourceType resourceType, String resourceId) {  
57 - ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);  
58 - Resource resource; 56 + public TbResource get(TenantId tenantId, ResourceType resourceType, String resourceKey) {
  57 + ResourceCompositeKey compositeKey = new ResourceCompositeKey(tenantId, resourceType, resourceKey);
  58 + TbResource resource;
59 59
60 - if (keys.contains(resourceKey)) {  
61 - resource = resources.get(resourceKey); 60 + if (keys.contains(compositeKey)) {
  61 + resource = resources.get(compositeKey);
62 if (resource == null) { 62 if (resource == null) {
63 - resource = resources.get(resourceKey.getSystemKey()); 63 + resource = resources.get(compositeKey.getSystemKey());
64 } 64 }
65 } else { 65 } else {
66 resourceFetchLock.lock(); 66 resourceFetchLock.lock();
67 try { 67 try {
68 - if (keys.contains(resourceKey)) {  
69 - resource = resources.get(resourceKey); 68 + if (keys.contains(compositeKey)) {
  69 + resource = resources.get(compositeKey);
70 if (resource == null) { 70 if (resource == null) {
71 - resource = resources.get(resourceKey.getSystemKey()); 71 + resource = resources.get(compositeKey.getSystemKey());
72 } 72 }
73 } else { 73 } else {
74 - resource = fetchResource(resourceKey);  
75 - keys.add(resourceKey); 74 + resource = fetchResource(compositeKey);
  75 + keys.add(compositeKey);
76 } 76 }
77 } finally { 77 } finally {
78 resourceFetchLock.unlock(); 78 resourceFetchLock.unlock();
@@ -82,20 +82,20 @@ public class DefaultTransportResourceCache implements TransportResourceCache { @@ -82,20 +82,20 @@ public class DefaultTransportResourceCache implements TransportResourceCache {
82 return resource; 82 return resource;
83 } 83 }
84 84
85 - private Resource fetchResource(ResourceKey resourceKey) {  
86 - UUID tenantId = resourceKey.getTenantId().getId(); 85 + private TbResource fetchResource(ResourceCompositeKey compositeKey) {
  86 + UUID tenantId = compositeKey.getTenantId().getId();
87 TransportProtos.GetResourceRequestMsg.Builder builder = TransportProtos.GetResourceRequestMsg.newBuilder(); 87 TransportProtos.GetResourceRequestMsg.Builder builder = TransportProtos.GetResourceRequestMsg.newBuilder();
88 builder 88 builder
89 .setTenantIdLSB(tenantId.getLeastSignificantBits()) 89 .setTenantIdLSB(tenantId.getLeastSignificantBits())
90 .setTenantIdMSB(tenantId.getMostSignificantBits()) 90 .setTenantIdMSB(tenantId.getMostSignificantBits())
91 - .setResourceType(resourceKey.resourceType.name())  
92 - .setResourceId(resourceKey.resourceId); 91 + .setResourceType(compositeKey.resourceType.name())
  92 + .setResourceKey(compositeKey.resourceKey);
93 TransportProtos.GetResourceResponseMsg responseMsg = transportService.getResource(builder.build()); 93 TransportProtos.GetResourceResponseMsg responseMsg = transportService.getResource(builder.build());
94 94
95 - Optional<Resource> optionalResource = dataDecodingEncodingService.decode(responseMsg.getResource().toByteArray()); 95 + Optional<TbResource> optionalResource = dataDecodingEncodingService.decode(responseMsg.getResource().toByteArray());
96 if (optionalResource.isPresent()) { 96 if (optionalResource.isPresent()) {
97 - Resource resource = optionalResource.get();  
98 - resources.put(new ResourceKey(resource.getTenantId(), resource.getResourceType(), resource.getResourceId()), resource); 97 + TbResource resource = optionalResource.get();
  98 + resources.put(new ResourceCompositeKey(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey()), resource);
99 return resource; 99 return resource;
100 } 100 }
101 101
@@ -103,28 +103,28 @@ public class DefaultTransportResourceCache implements TransportResourceCache { @@ -103,28 +103,28 @@ public class DefaultTransportResourceCache implements TransportResourceCache {
103 } 103 }
104 104
105 @Override 105 @Override
106 - public void update(TenantId tenantId, ResourceType resourceType, String resourceId) {  
107 - ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);  
108 - if (keys.contains(resourceKey) || resources.containsKey(resourceKey)) {  
109 - fetchResource(resourceKey); 106 + public void update(TenantId tenantId, ResourceType resourceType, String resourceKey) {
  107 + ResourceCompositeKey compositeKey = new ResourceCompositeKey(tenantId, resourceType, resourceKey);
  108 + if (keys.contains(compositeKey) || resources.containsKey(compositeKey)) {
  109 + fetchResource(compositeKey);
110 } 110 }
111 } 111 }
112 112
113 @Override 113 @Override
114 - public void evict(TenantId tenantId, ResourceType resourceType, String resourceId) {  
115 - ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);  
116 - keys.remove(resourceKey);  
117 - resources.remove(resourceKey); 114 + public void evict(TenantId tenantId, ResourceType resourceType, String resourceKey) {
  115 + ResourceCompositeKey compositeKey = new ResourceCompositeKey(tenantId, resourceType, resourceKey);
  116 + keys.remove(compositeKey);
  117 + resources.remove(compositeKey);
118 } 118 }
119 119
120 @Data 120 @Data
121 - private static class ResourceKey { 121 + private static class ResourceCompositeKey {
122 private final TenantId tenantId; 122 private final TenantId tenantId;
123 private final ResourceType resourceType; 123 private final ResourceType resourceType;
124 - private final String resourceId; 124 + private final String resourceKey;
125 125
126 - public ResourceKey getSystemKey() {  
127 - return new ResourceKey(TenantId.SYS_TENANT_ID, resourceType, resourceId); 126 + public ResourceCompositeKey getSystemKey() {
  127 + return new ResourceCompositeKey(TenantId.SYS_TENANT_ID, resourceType, resourceKey);
128 } 128 }
129 } 129 }
130 } 130 }
@@ -708,13 +708,13 @@ public class DefaultTransportService implements TransportService { @@ -708,13 +708,13 @@ public class DefaultTransportService implements TransportService {
708 TransportProtos.ResourceUpdateMsg msg = toSessionMsg.getResourceUpdateMsg(); 708 TransportProtos.ResourceUpdateMsg msg = toSessionMsg.getResourceUpdateMsg();
709 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); 709 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
710 ResourceType resourceType = ResourceType.valueOf(msg.getResourceType()); 710 ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
711 - String resourceId = msg.getResourceId(); 711 + String resourceId = msg.getResourceKey();
712 transportResourceCache.update(tenantId, resourceType, resourceId); 712 transportResourceCache.update(tenantId, resourceType, resourceId);
713 } else if (toSessionMsg.hasResourceDeleteMsg()) { 713 } else if (toSessionMsg.hasResourceDeleteMsg()) {
714 TransportProtos.ResourceDeleteMsg msg = toSessionMsg.getResourceDeleteMsg(); 714 TransportProtos.ResourceDeleteMsg msg = toSessionMsg.getResourceDeleteMsg();
715 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); 715 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
716 ResourceType resourceType = ResourceType.valueOf(msg.getResourceType()); 716 ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
717 - String resourceId = msg.getResourceId(); 717 + String resourceId = msg.getResourceKey();
718 transportResourceCache.evict(tenantId, resourceType, resourceId); 718 transportResourceCache.evict(tenantId, resourceType, resourceId);
719 } else { 719 } else {
720 //TODO: should we notify the device actor about missed session? 720 //TODO: should we notify the device actor about missed session?
@@ -462,9 +462,9 @@ public class ModelConstants { @@ -462,9 +462,9 @@ public class ModelConstants {
462 public static final String RESOURCE_TABLE_NAME = "resource"; 462 public static final String RESOURCE_TABLE_NAME = "resource";
463 public static final String RESOURCE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; 463 public static final String RESOURCE_TENANT_ID_COLUMN = TENANT_ID_COLUMN;
464 public static final String RESOURCE_TYPE_COLUMN = "resource_type"; 464 public static final String RESOURCE_TYPE_COLUMN = "resource_type";
465 - public static final String RESOURCE_ID_COLUMN = "resource_id";  
466 - public static final String TEXT_SEARCH_COLUMN = "text_search";  
467 - public static final String RESOURCE_VALUE_COLUMN = "resource_value"; 465 + public static final String RESOURCE_KEY_COLUMN = "resource_key";
  466 + public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY;
  467 + public static final String RESOURCE_DATA_COLUMN = "data";
468 468
469 469
470 /** 470 /**
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.ResourceType;
  21 +import org.thingsboard.server.common.data.TbResource;
  22 +import org.thingsboard.server.common.data.id.TbResourceId;
  23 +import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  25 +import org.thingsboard.server.dao.model.SearchTextEntity;
  26 +
  27 +import javax.persistence.Column;
  28 +import javax.persistence.Entity;
  29 +import javax.persistence.Table;
  30 +import java.util.UUID;
  31 +
  32 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN;
  33 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN;
  34 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME;
  35 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN;
  36 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TITLE_COLUMN;
  37 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TYPE_COLUMN;
  38 +import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
  39 +
  40 +@Data
  41 +@EqualsAndHashCode(callSuper = true)
  42 +@Entity
  43 +@Table(name = RESOURCE_TABLE_NAME)
  44 +public class TbResourceEntity extends BaseSqlEntity<TbResource> implements SearchTextEntity<TbResource> {
  45 +
  46 + @Column(name = RESOURCE_TENANT_ID_COLUMN, columnDefinition = "uuid")
  47 + private UUID tenantId;
  48 +
  49 + @Column(name = RESOURCE_TITLE_COLUMN)
  50 + private String title;
  51 +
  52 + @Column(name = RESOURCE_TYPE_COLUMN)
  53 + private String resourceType;
  54 +
  55 + @Column(name = RESOURCE_KEY_COLUMN)
  56 + private String resourceKey;
  57 +
  58 + @Column(name = SEARCH_TEXT_PROPERTY)
  59 + private String searchText;
  60 +
  61 + @Column(name = RESOURCE_DATA_COLUMN)
  62 + private String data;
  63 +
  64 + public TbResourceEntity() {
  65 + }
  66 +
  67 + public TbResourceEntity(TbResource resource) {
  68 + this.setUuid(resource.getId().getId());
  69 + this.tenantId = resource.getTenantId().getId();
  70 + this.title = resource.getTitle();
  71 + this.resourceType = resource.getResourceType().name();
  72 + this.resourceKey = resource.getResourceKey();
  73 + this.searchText = resource.getSearchText();
  74 + this.data = resource.getData();
  75 + }
  76 +
  77 + @Override
  78 + public TbResource toData() {
  79 + TbResource resource = new TbResource();
  80 + resource.setId(new TbResourceId(id));
  81 + resource.setCreatedTime(createdTime);
  82 + resource.setTenantId(new TenantId(tenantId));
  83 + resource.setTitle(title);
  84 + resource.setResourceType(ResourceType.valueOf(resourceType));
  85 + resource.setResourceKey(resourceKey);
  86 + resource.setSearchText(searchText);
  87 + resource.setData(data);
  88 + return resource;
  89 + }
  90 +
  91 + @Override
  92 + public String getSearchTextSource() {
  93 + return title;
  94 + }
  95 +}
dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java renamed from dao/src/main/java/org/thingsboard/server/dao/model/sql/ResourceEntity.java
@@ -16,68 +16,75 @@ @@ -16,68 +16,75 @@
16 package org.thingsboard.server.dao.model.sql; 16 package org.thingsboard.server.dao.model.sql;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 -import org.thingsboard.server.common.data.Resource; 19 +import lombok.EqualsAndHashCode;
20 import org.thingsboard.server.common.data.ResourceType; 20 import org.thingsboard.server.common.data.ResourceType;
  21 +import org.thingsboard.server.common.data.TbResourceInfo;
  22 +import org.thingsboard.server.common.data.id.TbResourceId;
21 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
22 -import org.thingsboard.server.dao.model.ToData; 24 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  25 +import org.thingsboard.server.dao.model.SearchTextEntity;
23 26
24 import javax.persistence.Column; 27 import javax.persistence.Column;
25 import javax.persistence.Entity; 28 import javax.persistence.Entity;
26 -import javax.persistence.Id;  
27 -import javax.persistence.IdClass;  
28 import javax.persistence.Table; 29 import javax.persistence.Table;
29 import java.util.UUID; 30 import java.util.UUID;
30 31
31 -import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_ID_COLUMN; 32 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN;
32 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME; 33 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME;
33 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN; 34 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN;
  35 +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TITLE_COLUMN;
34 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TYPE_COLUMN; 36 import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TYPE_COLUMN;
35 -import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_VALUE_COLUMN;  
36 -import static org.thingsboard.server.dao.model.ModelConstants.TEXT_SEARCH_COLUMN; 37 +import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
37 38
38 @Data 39 @Data
  40 +@EqualsAndHashCode(callSuper = true)
39 @Entity 41 @Entity
40 @Table(name = RESOURCE_TABLE_NAME) 42 @Table(name = RESOURCE_TABLE_NAME)
41 -@IdClass(ResourceCompositeKey.class)  
42 -public class ResourceEntity implements ToData<Resource> { 43 +public class TbResourceInfoEntity extends BaseSqlEntity<TbResourceInfo> implements SearchTextEntity<TbResourceInfo> {
43 44
44 - @Id  
45 @Column(name = RESOURCE_TENANT_ID_COLUMN, columnDefinition = "uuid") 45 @Column(name = RESOURCE_TENANT_ID_COLUMN, columnDefinition = "uuid")
46 private UUID tenantId; 46 private UUID tenantId;
47 47
48 - @Id 48 + @Column(name = RESOURCE_TITLE_COLUMN)
  49 + private String title;
  50 +
49 @Column(name = RESOURCE_TYPE_COLUMN) 51 @Column(name = RESOURCE_TYPE_COLUMN)
50 private String resourceType; 52 private String resourceType;
51 53
52 - @Id  
53 - @Column(name = RESOURCE_ID_COLUMN)  
54 - private String resourceId;  
55 -  
56 - @Column(name = TEXT_SEARCH_COLUMN)  
57 - private String textSearch; 54 + @Column(name = RESOURCE_KEY_COLUMN)
  55 + private String resourceKey;
58 56
59 - @Column(name = RESOURCE_VALUE_COLUMN)  
60 - private String value; 57 + @Column(name = SEARCH_TEXT_PROPERTY)
  58 + private String searchText;
61 59
62 - public ResourceEntity() { 60 + public TbResourceInfoEntity() {
63 } 61 }
64 62
65 - public ResourceEntity(Resource resource) { 63 + public TbResourceInfoEntity(TbResourceInfo resource) {
  64 + this.setUuid(resource.getId().getId());
  65 + this.setCreatedTime(resource.getCreatedTime());
66 this.tenantId = resource.getTenantId().getId(); 66 this.tenantId = resource.getTenantId().getId();
  67 + this.title = resource.getTitle();
67 this.resourceType = resource.getResourceType().name(); 68 this.resourceType = resource.getResourceType().name();
68 - this.resourceId = resource.getResourceId();  
69 - this.textSearch = resource.getTextSearch();  
70 - this.value = resource.getValue(); 69 + this.resourceKey = resource.getResourceKey();
  70 + this.searchText = resource.getSearchText();
71 } 71 }
72 72
73 @Override 73 @Override
74 - public Resource toData() {  
75 - Resource resource = new Resource(); 74 + public TbResourceInfo toData() {
  75 + TbResourceInfo resource = new TbResourceInfo();
  76 + resource.setId(new TbResourceId(id));
  77 + resource.setCreatedTime(createdTime);
76 resource.setTenantId(new TenantId(tenantId)); 78 resource.setTenantId(new TenantId(tenantId));
  79 + resource.setTitle(title);
77 resource.setResourceType(ResourceType.valueOf(resourceType)); 80 resource.setResourceType(ResourceType.valueOf(resourceType));
78 - resource.setResourceId(resourceId);  
79 - resource.setTextSearch(textSearch);  
80 - resource.setValue(value); 81 + resource.setResourceKey(resourceKey);
  82 + resource.setSearchText(searchText);
81 return resource; 83 return resource;
82 } 84 }
  85 +
  86 + @Override
  87 + public String getSearchTextSource() {
  88 + return title;
  89 + }
83 } 90 }
dao/src/main/java/org/thingsboard/server/dao/resource/BaseTbResourceService.java renamed from dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java
@@ -21,8 +21,10 @@ import org.eclipse.leshan.core.model.DefaultDDFFileValidator; @@ -21,8 +21,10 @@ import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
21 import org.eclipse.leshan.core.model.InvalidDDFFileException; 21 import org.eclipse.leshan.core.model.InvalidDDFFileException;
22 import org.eclipse.leshan.core.model.ObjectModel; 22 import org.eclipse.leshan.core.model.ObjectModel;
23 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
24 -import org.thingsboard.server.common.data.Resource;  
25 import org.thingsboard.server.common.data.ResourceType; 24 import org.thingsboard.server.common.data.ResourceType;
  25 +import org.thingsboard.server.common.data.TbResource;
  26 +import org.thingsboard.server.common.data.TbResourceInfo;
  27 +import org.thingsboard.server.common.data.id.TbResourceId;
26 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
27 import org.thingsboard.server.common.data.lwm2m.LwM2mInstance; 29 import org.thingsboard.server.common.data.lwm2m.LwM2mInstance;
28 import org.thingsboard.server.common.data.lwm2m.LwM2mObject; 30 import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
@@ -30,6 +32,8 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mResource; @@ -30,6 +32,8 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mResource;
30 import org.thingsboard.server.common.data.page.PageData; 32 import org.thingsboard.server.common.data.page.PageData;
31 import org.thingsboard.server.common.data.page.PageLink; 33 import org.thingsboard.server.common.data.page.PageLink;
32 import org.thingsboard.server.dao.exception.DataValidationException; 34 import org.thingsboard.server.dao.exception.DataValidationException;
  35 +import org.thingsboard.server.dao.service.PaginatedRemover;
  36 +import org.thingsboard.server.dao.service.Validator;
33 37
34 import java.io.ByteArrayInputStream; 38 import java.io.ByteArrayInputStream;
35 import java.io.IOException; 39 import java.io.IOException;
@@ -44,61 +48,88 @@ import static org.thingsboard.server.dao.service.Validator.validateId; @@ -44,61 +48,88 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
44 48
45 @Service 49 @Service
46 @Slf4j 50 @Slf4j
47 -public class BaseResourceService implements ResourceService { 51 +public class BaseTbResourceService implements TbResourceService {
48 52
49 - private final ResourceDao resourceDao; 53 + public static final String INCORRECT_RESOURCE_ID = "Incorrect resourceId ";
  54 + private final TbResourceDao resourceDao;
  55 + private final TbResourceInfoDao resourceInfoDao;
  56 + private final DDFFileParser ddfFileParser;
50 57
51 - public BaseResourceService(ResourceDao resourceDao) { 58 + public BaseTbResourceService(TbResourceDao resourceDao, TbResourceInfoDao resourceInfoDao) {
52 this.resourceDao = resourceDao; 59 this.resourceDao = resourceDao;
  60 + this.resourceInfoDao = resourceInfoDao;
  61 + this.ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
53 } 62 }
54 63
55 @Override 64 @Override
56 - public Resource saveResource(Resource resource) { 65 + public TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException {
57 log.trace("Executing saveResource [{}]", resource); 66 log.trace("Executing saveResource [{}]", resource);
  67 +
  68 + if (resource.getId() == null && ResourceType.LWM2M_MODEL.equals(resource.getResourceType())) {
  69 + List<ObjectModel> objectModels =
  70 + ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText());
  71 + if (!objectModels.isEmpty()) {
  72 + ObjectModel objectModel = objectModels.get(0);
  73 +
  74 + String resourceKey = objectModel.id + "_" + objectModel.getVersion();
  75 + String name = objectModel.name;
  76 + resource.setResourceKey(resourceKey);
  77 + resource.setTitle(name);
  78 + resource.setSearchText(resourceKey + ":" + name);
  79 + }
  80 + }
  81 +
58 validate(resource); 82 validate(resource);
  83 +
59 return resourceDao.saveResource(resource); 84 return resourceDao.saveResource(resource);
60 } 85 }
61 86
62 @Override 87 @Override
63 - public Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId) {  
64 - log.trace("Executing getResource [{}] [{}] [{}]", tenantId, resourceType, resourceId);  
65 - validate(tenantId, resourceType, resourceId);  
66 - return resourceDao.getResource(tenantId, resourceType, resourceId); 88 + public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey) {
  89 + log.trace("Executing getResource [{}] [{}] [{}]", tenantId, resourceType, resourceKey);
  90 + validate(tenantId, resourceType, resourceKey);
  91 + return resourceDao.getResource(tenantId, resourceType, resourceKey);
67 } 92 }
68 93
69 @Override 94 @Override
70 - public void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) {  
71 - log.trace("Executing deleteResource [{}] [{}] [{}]", tenantId, resourceType, resourceId);  
72 - validate(tenantId, resourceType, resourceId);  
73 - resourceDao.deleteResource(tenantId, resourceType, resourceId); 95 + public TbResource findResourceById(TenantId tenantId, TbResourceId resourceId) {
  96 + log.trace("Executing findResourceById [{}] [{}]", tenantId, resourceId);
  97 + Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
  98 + return resourceDao.findById(tenantId, resourceId.getId());
74 } 99 }
75 100
76 @Override 101 @Override
77 - public PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink) {  
78 - log.trace("Executing findByTenantId [{}]", tenantId);  
79 - validateId(tenantId, INCORRECT_TENANT_ID + tenantId);  
80 - return resourceDao.findAllByTenantId(tenantId, pageLink); 102 + public TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId) {
  103 + log.trace("Executing findResourceInfoById [{}] [{}]", tenantId, resourceId);
  104 + Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
  105 + return resourceInfoDao.findById(tenantId, resourceId.getId());
81 } 106 }
82 107
  108 + @Override
  109 + public void deleteResource(TenantId tenantId, TbResourceId resourceId) {
  110 + log.trace("Executing deleteResource [{}] [{}]", tenantId, resourceId);
  111 + Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
  112 + resourceDao.removeById(tenantId, resourceId.getId());
  113 + }
83 114
84 @Override 115 @Override
85 - public List<Resource> findAllByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType) { 116 + public PageData<TbResourceInfo> findResourcesByTenantId(TenantId tenantId, PageLink pageLink) {
86 log.trace("Executing findByTenantId [{}]", tenantId); 117 log.trace("Executing findByTenantId [{}]", tenantId);
87 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 118 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
88 - return resourceDao.findAllByTenantIdAndResourceType(tenantId, resourceType); 119 + return resourceInfoDao.findTbResourcesByTenantId(tenantId.getId(), pageLink);
89 } 120 }
90 121
91 @Override 122 @Override
92 public List<LwM2mObject> findLwM2mObjectPage(TenantId tenantId, String sortProperty, String sortOrder, PageLink pageLink) { 123 public List<LwM2mObject> findLwM2mObjectPage(TenantId tenantId, String sortProperty, String sortOrder, PageLink pageLink) {
93 log.trace("Executing findByTenantId [{}]", tenantId); 124 log.trace("Executing findByTenantId [{}]", tenantId);
94 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 125 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
95 - PageData<Resource> resourcePageData = resourceDao.findResourcesByTenantIdAndResourceType(  
96 - tenantId,  
97 - ResourceType.LWM2M_MODEL, pageLink);  
98 - return resourcePageData.getData().stream()  
99 - .map(this::toLwM2mObject)  
100 - .sorted(getComparator(sortProperty, sortOrder))  
101 - .collect(Collectors.toList()); 126 + PageData<TbResource> resourcePageData = resourceDao.findResourcesByTenantIdAndResourceType(
  127 + tenantId,
  128 + ResourceType.LWM2M_MODEL, pageLink);
  129 + return resourcePageData.getData().stream()
  130 + .map(this::toLwM2mObject)
  131 + .sorted(getComparator(sortProperty, sortOrder))
  132 + .collect(Collectors.toList());
102 } 133 }
103 134
104 @Override 135 @Override
@@ -107,9 +138,9 @@ public class BaseResourceService implements ResourceService { @@ -107,9 +138,9 @@ public class BaseResourceService implements ResourceService {
107 String[] objectIds) { 138 String[] objectIds) {
108 log.trace("Executing findByTenantId [{}]", tenantId); 139 log.trace("Executing findByTenantId [{}]", tenantId);
109 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 140 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
110 - List<Resource> resources = resourceDao.findResourcesByTenantIdAndResourceType(tenantId, ResourceType.LWM2M_MODEL,  
111 - objectIds,  
112 - null); 141 + List<TbResource> resources = resourceDao.findResourcesByTenantIdAndResourceType(tenantId, ResourceType.LWM2M_MODEL,
  142 + objectIds,
  143 + null);
113 return resources.stream() 144 return resources.stream()
114 .map(this::toLwM2mObject) 145 .map(this::toLwM2mObject)
115 .sorted(getComparator(sortProperty, sortOrder)) 146 .sorted(getComparator(sortProperty, sortOrder))
@@ -118,21 +149,21 @@ public class BaseResourceService implements ResourceService { @@ -118,21 +149,21 @@ public class BaseResourceService implements ResourceService {
118 149
119 @Override 150 @Override
120 public void deleteResourcesByTenantId(TenantId tenantId) { 151 public void deleteResourcesByTenantId(TenantId tenantId) {
121 - log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId); 152 + log.trace("Executing deleteResourcesByTenantId, tenantId [{}]", tenantId);
122 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 153 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
123 - resourceDao.removeAllByTenantId(tenantId); 154 + tenantResourcesRemover.removeEntities(tenantId, tenantId);
124 } 155 }
125 156
126 - protected void validate(Resource resource) { 157 + protected void validate(TbResource resource) {
127 if (resource == null) { 158 if (resource == null) {
128 throw new DataValidationException("Resource should be specified!"); 159 throw new DataValidationException("Resource should be specified!");
129 } 160 }
130 - if (resource.getValue() == null) { 161 + if (resource.getData() == null) {
131 throw new DataValidationException("Resource value should be specified!"); 162 throw new DataValidationException("Resource value should be specified!");
132 } 163 }
133 - validate(resource.getTenantId(), resource.getResourceType(), resource.getResourceId()); 164 + validate(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey());
134 if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && this.toLwM2mObject(resource) == null) { 165 if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && this.toLwM2mObject(resource) == null) {
135 - throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getTextSearch())); 166 + throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
136 } 167 }
137 } 168 }
138 169
@@ -146,18 +177,18 @@ public class BaseResourceService implements ResourceService { @@ -146,18 +177,18 @@ public class BaseResourceService implements ResourceService {
146 validateId(tenantId, "Incorrect tenantId "); 177 validateId(tenantId, "Incorrect tenantId ");
147 } 178 }
148 179
149 - private LwM2mObject toLwM2mObject(Resource resource) { 180 + private LwM2mObject toLwM2mObject(TbResource resource) {
150 try { 181 try {
151 DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); 182 DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
152 List<ObjectModel> objectModels = 183 List<ObjectModel> objectModels =
153 - ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getValue())), resource.getTextSearch()); 184 + ddfFileParser.parseEx(new ByteArrayInputStream(Base64.getDecoder().decode(resource.getData())), resource.getSearchText());
154 if (objectModels.size() == 0) { 185 if (objectModels.size() == 0) {
155 return null; 186 return null;
156 } else { 187 } else {
157 ObjectModel obj = objectModels.get(0); 188 ObjectModel obj = objectModels.get(0);
158 LwM2mObject lwM2mObject = new LwM2mObject(); 189 LwM2mObject lwM2mObject = new LwM2mObject();
159 lwM2mObject.setId(obj.id); 190 lwM2mObject.setId(obj.id);
160 - lwM2mObject.setKeyId(resource.getResourceId()); 191 + lwM2mObject.setKeyId(resource.getResourceKey());
161 lwM2mObject.setName(obj.name); 192 lwM2mObject.setName(obj.name);
162 lwM2mObject.setMultiple(obj.multiple); 193 lwM2mObject.setMultiple(obj.multiple);
163 lwM2mObject.setMandatory(obj.mandatory); 194 lwM2mObject.setMandatory(obj.mandatory);
@@ -170,12 +201,12 @@ public class BaseResourceService implements ResourceService { @@ -170,12 +201,12 @@ public class BaseResourceService implements ResourceService {
170 resources.add(lwM2mResource); 201 resources.add(lwM2mResource);
171 } 202 }
172 }); 203 });
173 - instance.setResources(resources.stream().toArray(LwM2mResource[]::new)); 204 + instance.setResources(resources.toArray(LwM2mResource[]::new));
174 lwM2mObject.setInstances(new LwM2mInstance[]{instance}); 205 lwM2mObject.setInstances(new LwM2mInstance[]{instance});
175 return lwM2mObject; 206 return lwM2mObject;
176 } 207 }
177 } catch (IOException | InvalidDDFFileException e) { 208 } catch (IOException | InvalidDDFFileException e) {
178 - log.error("Could not parse the XML of objectModel with name [{}]", resource.getTextSearch(), e); 209 + log.error("Could not parse the XML of objectModel with name [{}]", resource.getSearchText(), e);
179 return null; 210 return null;
180 } 211 }
181 } 212 }
@@ -190,4 +221,17 @@ public class BaseResourceService implements ResourceService { @@ -190,4 +221,17 @@ public class BaseResourceService implements ResourceService {
190 return "DESC".equals(sortOrder) ? comparator.reversed() : comparator; 221 return "DESC".equals(sortOrder) ? comparator.reversed() : comparator;
191 } 222 }
192 223
  224 + private PaginatedRemover<TenantId, TbResource> tenantResourcesRemover =
  225 + new PaginatedRemover<>() {
  226 +
  227 + @Override
  228 + protected PageData<TbResource> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
  229 + return resourceDao.findAllByTenantId(id, pageLink);
  230 + }
  231 +
  232 + @Override
  233 + protected void removeEntity(TenantId tenantId, TbResource entity) {
  234 + deleteResource(tenantId, new TbResourceId(entity.getUuidId()));
  235 + }
  236 + };
193 } 237 }
dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceDao.java renamed from dao/src/main/java/org/thingsboard/server/dao/resource/ResourceDao.java
@@ -15,33 +15,29 @@ @@ -15,33 +15,29 @@
15 */ 15 */
16 package org.thingsboard.server.dao.resource; 16 package org.thingsboard.server.dao.resource;
17 17
18 -import org.thingsboard.server.common.data.Resource;  
19 import org.thingsboard.server.common.data.ResourceType; 18 import org.thingsboard.server.common.data.ResourceType;
  19 +import org.thingsboard.server.common.data.TbResource;
20 import org.thingsboard.server.common.data.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.PageData; 21 import org.thingsboard.server.common.data.page.PageData;
22 import org.thingsboard.server.common.data.page.PageLink; 22 import org.thingsboard.server.common.data.page.PageLink;
  23 +import org.thingsboard.server.dao.Dao;
23 24
24 import java.util.List; 25 import java.util.List;
25 26
26 -public interface ResourceDao { 27 +public interface TbResourceDao extends Dao<TbResource> {
27 28
28 - Resource saveResource(Resource resource); 29 + TbResource saveResource(TbResource resource);
29 30
30 - Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); 31 + TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
31 32
32 - void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); 33 + PageData<TbResource> findAllByTenantId(TenantId tenantId, PageLink pageLink);
33 34
34 - PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink); 35 + PageData<TbResource> findResourcesByTenantIdAndResourceType(TenantId tenantId,
  36 + ResourceType resourceType,
  37 + PageLink pageLink);
35 38
36 - PageData<Resource> findResourcesByTenantIdAndResourceType(TenantId tenantId,  
37 - ResourceType resourceType,  
38 - PageLink pageLink);  
39 -  
40 - List<Resource> findAllByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType);  
41 -  
42 - List<Resource> findResourcesByTenantIdAndResourceType(TenantId tenantId,  
43 - ResourceType resourceType,  
44 - String[] objectIds,  
45 - String searchText);  
46 - void removeAllByTenantId(TenantId tenantId); 39 + List<TbResource> findResourcesByTenantIdAndResourceType(TenantId tenantId,
  40 + ResourceType resourceType,
  41 + String[] objectIds,
  42 + String searchText);
47 } 43 }
dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java renamed from dao/src/main/java/org/thingsboard/server/dao/model/sql/ResourceCompositeKey.java
@@ -13,32 +13,17 @@ @@ -13,32 +13,17 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.dao.model.sql; 16 +package org.thingsboard.server.dao.resource;
17 17
18 -import lombok.AllArgsConstructor;  
19 -import lombok.Data;  
20 -import lombok.NoArgsConstructor;  
21 -import org.thingsboard.server.common.data.Resource; 18 +import org.thingsboard.server.common.data.TbResourceInfo;
  19 +import org.thingsboard.server.common.data.page.PageData;
  20 +import org.thingsboard.server.common.data.page.PageLink;
  21 +import org.thingsboard.server.dao.Dao;
22 22
23 -import javax.persistence.Transient;  
24 -import java.io.Serializable;  
25 import java.util.UUID; 23 import java.util.UUID;
26 24
27 -@NoArgsConstructor  
28 -@AllArgsConstructor  
29 -@Data  
30 -public class ResourceCompositeKey implements Serializable { 25 +public interface TbResourceInfoDao extends Dao<TbResourceInfo> {
31 26
32 - @Transient  
33 - private static final long serialVersionUID = -3789469030818742769L; 27 + PageData<TbResourceInfo> findTbResourcesByTenantId(UUID tenantId, PageLink pageLink);
34 28
35 - private UUID tenantId;  
36 - private String resourceType;  
37 - private String resourceId;  
38 -  
39 - public ResourceCompositeKey(Resource resource) {  
40 - this.tenantId = resource.getTenantId().getId();  
41 - this.resourceType = resource.getResourceType().name();  
42 - this.resourceId = resource.getResourceId();  
43 - }  
44 } 29 }
dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceDao.java renamed from dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceDaoImpl.java
@@ -16,72 +16,64 @@ @@ -16,72 +16,64 @@
16 package org.thingsboard.server.dao.sql.resource; 16 package org.thingsboard.server.dao.sql.resource;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.data.repository.CrudRepository;
19 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
20 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
21 -import org.thingsboard.server.common.data.Resource;  
22 import org.thingsboard.server.common.data.ResourceType; 22 import org.thingsboard.server.common.data.ResourceType;
  23 +import org.thingsboard.server.common.data.TbResource;
23 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.page.PageData; 25 import org.thingsboard.server.common.data.page.PageData;
25 import org.thingsboard.server.common.data.page.PageLink; 26 import org.thingsboard.server.common.data.page.PageLink;
26 import org.thingsboard.server.dao.DaoUtil; 27 import org.thingsboard.server.dao.DaoUtil;
27 -import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;  
28 -import org.thingsboard.server.dao.model.sql.ResourceEntity;  
29 -import org.thingsboard.server.dao.resource.ResourceDao; 28 +import org.thingsboard.server.dao.model.sql.TbResourceEntity;
  29 +import org.thingsboard.server.dao.resource.TbResourceDao;
  30 +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
30 31
31 import java.util.List; 32 import java.util.List;
32 import java.util.Objects; 33 import java.util.Objects;
  34 +import java.util.UUID;
33 35
34 @Slf4j 36 @Slf4j
35 @Component 37 @Component
36 -public class ResourceDaoImpl implements ResourceDao { 38 +public class JpaTbResourceDao extends JpaAbstractSearchTextDao<TbResourceEntity, TbResource> implements TbResourceDao {
37 39
38 - private final ResourceRepository resourceRepository; 40 + private final TbResourceRepository resourceRepository;
39 41
40 - public ResourceDaoImpl(ResourceRepository resourceRepository) { 42 + public JpaTbResourceDao(TbResourceRepository resourceRepository) {
41 this.resourceRepository = resourceRepository; 43 this.resourceRepository = resourceRepository;
42 } 44 }
43 45
44 @Override 46 @Override
45 - @Transactional  
46 - public Resource saveResource(Resource resource) {  
47 - return DaoUtil.getData(resourceRepository.save(new ResourceEntity(resource))); 47 + protected Class<TbResourceEntity> getEntityClass() {
  48 + return TbResourceEntity.class;
48 } 49 }
49 50
50 @Override 51 @Override
51 - public Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId) {  
52 - ResourceCompositeKey key = new ResourceCompositeKey();  
53 - key.setTenantId(tenantId.getId());  
54 - key.setResourceType(resourceType.name());  
55 - key.setResourceId(resourceId);  
56 -  
57 - return DaoUtil.getData(resourceRepository.findById(key)); 52 + protected CrudRepository<TbResourceEntity, UUID> getCrudRepository() {
  53 + return resourceRepository;
58 } 54 }
59 55
60 @Override 56 @Override
61 @Transactional 57 @Transactional
62 - public void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId) {  
63 - ResourceCompositeKey key = new ResourceCompositeKey();  
64 - key.setTenantId(tenantId.getId());  
65 - key.setResourceType(resourceType.name());  
66 - key.setResourceId(resourceId);  
67 -  
68 - resourceRepository.deleteById(key); 58 + public TbResource saveResource(TbResource resource) {
  59 + return DaoUtil.getData(resourceRepository.save(new TbResourceEntity(resource)));
69 } 60 }
70 61
71 @Override 62 @Override
72 - public PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink) {  
73 - return DaoUtil.toPageData(resourceRepository.findAllByTenantId(tenantId.getId(), DaoUtil.toPageable(pageLink))); 63 + public TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey) {
  64 +
  65 + return DaoUtil.getData(resourceRepository.findByTenantIdAndResourceTypeAndResourceKey(tenantId.getId(), resourceType.name(), resourceKey));
74 } 66 }
75 67
76 @Override 68 @Override
77 - public List<Resource> findAllByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType) {  
78 - return DaoUtil.convertDataList(resourceRepository.findAllByTenantIdAndResourceType(tenantId.getId(), resourceType.name())); 69 + public PageData<TbResource> findAllByTenantId(TenantId tenantId, PageLink pageLink) {
  70 + return DaoUtil.toPageData(resourceRepository.findAllByTenantId(tenantId.getId(), DaoUtil.toPageable(pageLink)));
79 } 71 }
80 72
81 @Override 73 @Override
82 - public PageData<Resource> findResourcesByTenantIdAndResourceType(TenantId tenantId,  
83 - ResourceType resourceType,  
84 - PageLink pageLink) { 74 + public PageData<TbResource> findResourcesByTenantIdAndResourceType(TenantId tenantId,
  75 + ResourceType resourceType,
  76 + PageLink pageLink) {
85 return DaoUtil.toPageData(resourceRepository.findResourcesPage( 77 return DaoUtil.toPageData(resourceRepository.findResourcesPage(
86 tenantId.getId(), 78 tenantId.getId(),
87 TenantId.SYS_TENANT_ID.getId(), 79 TenantId.SYS_TENANT_ID.getId(),
@@ -92,9 +84,9 @@ public class ResourceDaoImpl implements ResourceDao { @@ -92,9 +84,9 @@ public class ResourceDaoImpl implements ResourceDao {
92 } 84 }
93 85
94 @Override 86 @Override
95 - public List<Resource> findResourcesByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType,  
96 - String[] objectIds,  
97 - String searchText) { 87 + public List<TbResource> findResourcesByTenantIdAndResourceType(TenantId tenantId, ResourceType resourceType,
  88 + String[] objectIds,
  89 + String searchText) {
98 return objectIds == null ? 90 return objectIds == null ?
99 DaoUtil.convertDataList(resourceRepository.findResources( 91 DaoUtil.convertDataList(resourceRepository.findResources(
100 tenantId.getId(), 92 tenantId.getId(),
@@ -107,8 +99,4 @@ public class ResourceDaoImpl implements ResourceDao { @@ -107,8 +99,4 @@ public class ResourceDaoImpl implements ResourceDao {
107 resourceType.name(), objectIds)); 99 resourceType.name(), objectIds));
108 } 100 }
109 101
110 - @Override  
111 - public void removeAllByTenantId(TenantId tenantId) {  
112 - resourceRepository.removeAllByTenantId(tenantId.getId());  
113 - }  
114 } 102 }
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.resource;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.data.repository.CrudRepository;
  21 +import org.springframework.stereotype.Component;
  22 +import org.thingsboard.server.common.data.TbResourceInfo;
  23 +import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.data.page.PageData;
  25 +import org.thingsboard.server.common.data.page.PageLink;
  26 +import org.thingsboard.server.dao.DaoUtil;
  27 +import org.thingsboard.server.dao.model.sql.TbResourceInfoEntity;
  28 +import org.thingsboard.server.dao.resource.TbResourceInfoDao;
  29 +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
  30 +
  31 +import java.util.Objects;
  32 +import java.util.UUID;
  33 +
  34 +@Slf4j
  35 +@Component
  36 +public class JpaTbResourceInfoDao extends JpaAbstractSearchTextDao<TbResourceInfoEntity, TbResourceInfo> implements TbResourceInfoDao {
  37 +
  38 + @Autowired
  39 + private TbResourceInfoRepository resourceInfoRepository;
  40 +
  41 + @Override
  42 + protected Class<TbResourceInfoEntity> getEntityClass() {
  43 + return TbResourceInfoEntity.class;
  44 + }
  45 +
  46 + @Override
  47 + protected CrudRepository<TbResourceInfoEntity, UUID> getCrudRepository() {
  48 + return resourceInfoRepository;
  49 + }
  50 +
  51 + @Override
  52 + public PageData<TbResourceInfo> findTbResourcesByTenantId(UUID tenantId, PageLink pageLink) {
  53 + return DaoUtil.toPageData(resourceInfoRepository
  54 + .findByTenantId(
  55 + tenantId,
  56 + TenantId.NULL_UUID,
  57 + Objects.toString(pageLink.getTextSearch(), ""),
  58 + DaoUtil.toPageable(pageLink))); }
  59 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.resource;
  17 +
  18 +import org.springframework.data.domain.Page;
  19 +import org.springframework.data.domain.Pageable;
  20 +import org.springframework.data.jpa.repository.Query;
  21 +import org.springframework.data.repository.CrudRepository;
  22 +import org.springframework.data.repository.query.Param;
  23 +import org.thingsboard.server.dao.model.sql.TbResourceInfoEntity;
  24 +
  25 +import java.util.UUID;
  26 +
  27 +public interface TbResourceInfoRepository extends CrudRepository<TbResourceInfoEntity, UUID> {
  28 +
  29 + @Query("SELECT tr FROM TbResourceInfoEntity tr WHERE tr.tenantId = :tenantId " +
  30 + "AND LOWER(tr.searchText) LIKE LOWER(CONCAT(:searchText, '%'))" +
  31 + "AND (tr.tenantId = :tenantId " +
  32 + "OR (tr.tenantId = :systemAdminId " +
  33 + "AND NOT EXISTS " +
  34 + "(SELECT sr FROM TbResourceEntity sr " +
  35 + "WHERE sr.tenantId = :tenantId " +
  36 + "AND tr.resourceType = sr.resourceType " +
  37 + "AND tr.resourceKey = sr.resourceKey)))")
  38 + Page<TbResourceInfoEntity> findByTenantId(@Param("tenantId") UUID tenantId,
  39 + @Param("systemAdminId") UUID sysadminId,
  40 + @Param("searchText") String searchText,
  41 + Pageable pageable);
  42 +}
dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceRepository.java renamed from dao/src/main/java/org/thingsboard/server/dao/sql/resource/ResourceRepository.java
@@ -20,65 +20,63 @@ import org.springframework.data.domain.Pageable; @@ -20,65 +20,63 @@ import org.springframework.data.domain.Pageable;
20 import org.springframework.data.jpa.repository.Query; 20 import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.CrudRepository; 21 import org.springframework.data.repository.CrudRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 -import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;  
24 -import org.thingsboard.server.dao.model.sql.ResourceEntity; 23 +import org.thingsboard.server.dao.model.sql.TbResourceEntity;
25 24
26 import java.util.List; 25 import java.util.List;
27 import java.util.UUID; 26 import java.util.UUID;
28 27
29 -public interface ResourceRepository extends CrudRepository<ResourceEntity, ResourceCompositeKey> { 28 +public interface TbResourceRepository extends CrudRepository<TbResourceEntity, UUID> {
30 29
  30 + TbResourceEntity findByTenantIdAndResourceTypeAndResourceKey(UUID tenantId, String resourceType, String resourceKey);
31 31
32 - Page<ResourceEntity> findAllByTenantId(UUID tenantId, Pageable pageable); 32 + Page<TbResourceEntity> findAllByTenantId(UUID tenantId, Pageable pageable);
33 33
34 - @Query("SELECT tr FROM ResourceEntity tr " + 34 + @Query("SELECT tr FROM TbResourceEntity tr " +
35 "WHERE tr.resourceType = :resourceType " + 35 "WHERE tr.resourceType = :resourceType " +
36 - "AND LOWER(tr.textSearch) LIKE LOWER(CONCAT('%', :searchText, '%')) " + 36 + "AND LOWER(tr.searchText) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
37 "AND (tr.tenantId = :tenantId " + 37 "AND (tr.tenantId = :tenantId " +
38 "OR (tr.tenantId = :systemAdminId " + 38 "OR (tr.tenantId = :systemAdminId " +
39 "AND NOT EXISTS " + 39 "AND NOT EXISTS " +
40 - "(SELECT sr FROM ResourceEntity sr " + 40 + "(SELECT sr FROM TbResourceEntity sr " +
41 "WHERE sr.tenantId = :tenantId " + 41 "WHERE sr.tenantId = :tenantId " +
42 "AND sr.resourceType = :resourceType " + 42 "AND sr.resourceType = :resourceType " +
43 - "AND tr.resourceId = sr.resourceId)))")  
44 - Page<ResourceEntity> findResourcesPage( 43 + "AND tr.resourceKey = sr.resourceKey)))")
  44 + Page<TbResourceEntity> findResourcesPage(
45 @Param("tenantId") UUID tenantId, 45 @Param("tenantId") UUID tenantId,
46 @Param("systemAdminId") UUID sysAdminId, 46 @Param("systemAdminId") UUID sysAdminId,
47 @Param("resourceType") String resourceType, 47 @Param("resourceType") String resourceType,
48 @Param("searchText") String search, 48 @Param("searchText") String search,
49 Pageable pageable); 49 Pageable pageable);
50 50
51 - List<ResourceEntity> findAllByTenantIdAndResourceType(UUID tenantId, String resourceType);  
52 -  
53 void removeAllByTenantId(UUID tenantId); 51 void removeAllByTenantId(UUID tenantId);
54 52
55 - @Query("SELECT tr FROM ResourceEntity tr " + 53 + @Query("SELECT tr FROM TbResourceEntity tr " +
56 "WHERE tr.resourceType = :resourceType " + 54 "WHERE tr.resourceType = :resourceType " +
57 - "AND LOWER(tr.textSearch) LIKE LOWER(CONCAT('%', :searchText, '%')) " + 55 + "AND LOWER(tr.searchText) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
58 "AND (tr.tenantId = :tenantId " + 56 "AND (tr.tenantId = :tenantId " +
59 "OR (tr.tenantId = :systemAdminId " + 57 "OR (tr.tenantId = :systemAdminId " +
60 "AND NOT EXISTS " + 58 "AND NOT EXISTS " +
61 - "(SELECT sr FROM ResourceEntity sr " + 59 + "(SELECT sr FROM TbResourceEntity sr " +
62 "WHERE sr.tenantId = :tenantId " + 60 "WHERE sr.tenantId = :tenantId " +
63 "AND sr.resourceType = :resourceType " + 61 "AND sr.resourceType = :resourceType " +
64 - "AND tr.resourceId = sr.resourceId)))")  
65 - List<ResourceEntity> findResources(@Param("tenantId") UUID tenantId,  
66 - @Param("systemAdminId") UUID sysAdminId,  
67 - @Param("resourceType") String resourceType,  
68 - @Param("searchText") String search); 62 + "AND tr.resourceKey = sr.resourceKey)))")
  63 + List<TbResourceEntity> findResources(@Param("tenantId") UUID tenantId,
  64 + @Param("systemAdminId") UUID sysAdminId,
  65 + @Param("resourceType") String resourceType,
  66 + @Param("searchText") String search);
69 67
70 - @Query("SELECT tr FROM ResourceEntity tr " + 68 + @Query("SELECT tr FROM TbResourceEntity tr " +
71 "WHERE tr.resourceType = :resourceType " + 69 "WHERE tr.resourceType = :resourceType " +
72 - "AND tr.resourceId in (:resourceIds) " + 70 + "AND tr.resourceKey in (:resourceIds) " +
73 "AND (tr.tenantId = :tenantId " + 71 "AND (tr.tenantId = :tenantId " +
74 "OR (tr.tenantId = :systemAdminId " + 72 "OR (tr.tenantId = :systemAdminId " +
75 "AND NOT EXISTS " + 73 "AND NOT EXISTS " +
76 - "(SELECT sr FROM ResourceEntity sr " + 74 + "(SELECT sr FROM TbResourceEntity sr " +
77 "WHERE sr.tenantId = :tenantId " + 75 "WHERE sr.tenantId = :tenantId " +
78 "AND sr.resourceType = :resourceType " + 76 "AND sr.resourceType = :resourceType " +
79 - "AND tr.resourceId = sr.resourceId)))")  
80 - List<ResourceEntity> findResourcesByIds(@Param("tenantId") UUID tenantId,  
81 - @Param("systemAdminId") UUID sysAdminId,  
82 - @Param("resourceType") String resourceType,  
83 - @Param("resourceIds") String[] objectIds); 77 + "AND tr.resourceKey = sr.resourceKey)))")
  78 + List<TbResourceEntity> findResourcesByIds(@Param("tenantId") UUID tenantId,
  79 + @Param("systemAdminId") UUID sysAdminId,
  80 + @Param("resourceType") String resourceType,
  81 + @Param("resourceIds") String[] objectIds);
84 } 82 }
@@ -35,7 +35,7 @@ import org.thingsboard.server.dao.device.DeviceService; @@ -35,7 +35,7 @@ import org.thingsboard.server.dao.device.DeviceService;
35 import org.thingsboard.server.dao.entity.AbstractEntityService; 35 import org.thingsboard.server.dao.entity.AbstractEntityService;
36 import org.thingsboard.server.dao.entityview.EntityViewService; 36 import org.thingsboard.server.dao.entityview.EntityViewService;
37 import org.thingsboard.server.dao.exception.DataValidationException; 37 import org.thingsboard.server.dao.exception.DataValidationException;
38 -import org.thingsboard.server.dao.resource.ResourceService; 38 +import org.thingsboard.server.dao.resource.TbResourceService;
39 import org.thingsboard.server.dao.rule.RuleChainService; 39 import org.thingsboard.server.dao.rule.RuleChainService;
40 import org.thingsboard.server.dao.service.DataValidator; 40 import org.thingsboard.server.dao.service.DataValidator;
41 import org.thingsboard.server.dao.service.PaginatedRemover; 41 import org.thingsboard.server.dao.service.PaginatedRemover;
@@ -90,7 +90,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe @@ -90,7 +90,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
90 private RuleChainService ruleChainService; 90 private RuleChainService ruleChainService;
91 91
92 @Autowired 92 @Autowired
93 - private ResourceService resourceService; 93 + private TbResourceService resourceService;
94 94
95 @Override 95 @Override
96 public Tenant findTenantById(TenantId tenantId) { 96 public Tenant findTenantById(TenantId tenantId) {
@@ -426,10 +426,13 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( @@ -426,10 +426,13 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
426 ); 426 );
427 427
428 CREATE TABLE IF NOT EXISTS resource ( 428 CREATE TABLE IF NOT EXISTS resource (
  429 + id uuid NOT NULL CONSTRAINT resource_pkey PRIMARY KEY,
  430 + created_time bigint NOT NULL,
429 tenant_id uuid NOT NULL, 431 tenant_id uuid NOT NULL,
  432 + title varchar(255) NOT NULL,
430 resource_type varchar(32) NOT NULL, 433 resource_type varchar(32) NOT NULL,
431 - resource_id varchar(255) NOT NULL,  
432 - text_search varchar(255),  
433 - resource_value varchar,  
434 - CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_id) 434 + resource_key varchar(255) NOT NULL,
  435 + search_text varchar(255),
  436 + data varchar,
  437 + CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
435 ); 438 );
@@ -452,12 +452,15 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( @@ -452,12 +452,15 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
452 ); 452 );
453 453
454 CREATE TABLE IF NOT EXISTS resource ( 454 CREATE TABLE IF NOT EXISTS resource (
  455 + id uuid NOT NULL CONSTRAINT resource_pkey PRIMARY KEY,
  456 + created_time bigint NOT NULL,
455 tenant_id uuid NOT NULL, 457 tenant_id uuid NOT NULL,
  458 + title varchar(255) NOT NULL,
456 resource_type varchar(32) NOT NULL, 459 resource_type varchar(32) NOT NULL,
457 - resource_id varchar(255) NOT NULL,  
458 - text_search varchar(255),  
459 - resource_value varchar,  
460 - CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_id) 460 + resource_key varchar(255) NOT NULL,
  461 + search_text varchar(255),
  462 + data varchar,
  463 + CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
461 ); 464 );
462 465
463 CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) 466 CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint)