Commit 0a2477da79a342d6943fcc4574d89d62c1d7ef45

Authored by Andrew Shvayka
Committed by GitHub
2 parents 43fe84a2 648e8ec2

Merge pull request #4238 from thingsboard/add-models

Add models
Showing 30 changed files with 395 additions and 126 deletions
@@ -23,12 +23,12 @@ import org.springframework.web.bind.annotation.RequestMethod; @@ -23,12 +23,12 @@ import org.springframework.web.bind.annotation.RequestMethod;
23 import org.springframework.web.bind.annotation.RequestParam; 23 import org.springframework.web.bind.annotation.RequestParam;
24 import org.springframework.web.bind.annotation.ResponseBody; 24 import org.springframework.web.bind.annotation.ResponseBody;
25 import org.springframework.web.bind.annotation.RestController; 25 import org.springframework.web.bind.annotation.RestController;
  26 +import org.thingsboard.server.common.data.Resource;
  27 +import org.thingsboard.server.common.data.ResourceType;
26 import org.thingsboard.server.common.data.exception.ThingsboardException; 28 import org.thingsboard.server.common.data.exception.ThingsboardException;
27 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.page.PageData; 30 import org.thingsboard.server.common.data.page.PageData;
29 import org.thingsboard.server.common.data.page.PageLink; 31 import org.thingsboard.server.common.data.page.PageLink;
30 -import org.thingsboard.server.common.data.Resource;  
31 -import org.thingsboard.server.common.data.ResourceType;  
32 import org.thingsboard.server.dao.resource.ResourceService; 32 import org.thingsboard.server.dao.resource.ResourceService;
33 import org.thingsboard.server.queue.util.TbCoreComponent; 33 import org.thingsboard.server.queue.util.TbCoreComponent;
34 34
@@ -17,19 +17,23 @@ package org.thingsboard.server.service.install; @@ -17,19 +17,23 @@ package org.thingsboard.server.service.install;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
  20 +import org.eclipse.leshan.core.model.DDFFileParser;
  21 +import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
  22 +import org.eclipse.leshan.core.model.InvalidDDFFileException;
  23 +import org.eclipse.leshan.core.model.ObjectModel;
20 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.beans.factory.annotation.Value; 25 import org.springframework.beans.factory.annotation.Value;
22 import org.springframework.stereotype.Component; 26 import org.springframework.stereotype.Component;
23 import org.springframework.util.StringUtils; 27 import org.springframework.util.StringUtils;
24 import org.thingsboard.server.common.data.Dashboard; 28 import org.thingsboard.server.common.data.Dashboard;
  29 +import org.thingsboard.server.common.data.Resource;
  30 +import org.thingsboard.server.common.data.ResourceType;
25 import org.thingsboard.server.common.data.id.CustomerId; 31 import org.thingsboard.server.common.data.id.CustomerId;
26 import org.thingsboard.server.common.data.id.EntityId; 32 import org.thingsboard.server.common.data.id.EntityId;
27 import org.thingsboard.server.common.data.id.TenantId; 33 import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; 34 import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate;
29 import org.thingsboard.server.common.data.rule.RuleChain; 35 import org.thingsboard.server.common.data.rule.RuleChain;
30 import org.thingsboard.server.common.data.rule.RuleChainMetaData; 36 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
31 -import org.thingsboard.server.common.data.Resource;  
32 -import org.thingsboard.server.common.data.ResourceType;  
33 import org.thingsboard.server.common.data.widget.WidgetType; 37 import org.thingsboard.server.common.data.widget.WidgetType;
34 import org.thingsboard.server.common.data.widget.WidgetsBundle; 38 import org.thingsboard.server.common.data.widget.WidgetsBundle;
35 import org.thingsboard.server.dao.dashboard.DashboardService; 39 import org.thingsboard.server.dao.dashboard.DashboardService;
@@ -39,6 +43,8 @@ import org.thingsboard.server.dao.rule.RuleChainService; @@ -39,6 +43,8 @@ import org.thingsboard.server.dao.rule.RuleChainService;
39 import org.thingsboard.server.dao.widget.WidgetTypeService; 43 import org.thingsboard.server.dao.widget.WidgetTypeService;
40 import org.thingsboard.server.dao.widget.WidgetsBundleService; 44 import org.thingsboard.server.dao.widget.WidgetsBundleService;
41 45
  46 +import java.io.ByteArrayInputStream;
  47 +import java.io.File;
42 import java.io.IOException; 48 import java.io.IOException;
43 import java.nio.file.DirectoryStream; 49 import java.nio.file.DirectoryStream;
44 import java.nio.file.Files; 50 import java.nio.file.Files;
@@ -196,18 +202,23 @@ public class InstallScripts { @@ -196,18 +202,23 @@ public class InstallScripts {
196 } 202 }
197 203
198 public void loadSystemLwm2mResources() throws Exception { 204 public void loadSystemLwm2mResources() throws Exception {
  205 +// Path modelsDir = Paths.get("/home/nick/Igor_project/thingsboard_ce_3_2_docker/thingsboard/common/transport/lwm2m/src/main/resources/models/");
199 Path modelsDir = Paths.get(getDataDir(), MODELS_DIR); 206 Path modelsDir = Paths.get(getDataDir(), MODELS_DIR);
200 if (Files.isDirectory(modelsDir)) { 207 if (Files.isDirectory(modelsDir)) {
201 try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(modelsDir, path -> path.toString().endsWith(XML_EXT))) { 208 try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(modelsDir, path -> path.toString().endsWith(XML_EXT))) {
202 dirStream.forEach( 209 dirStream.forEach(
203 path -> { 210 path -> {
204 try { 211 try {
205 - Resource resource = new Resource();  
206 - resource.setTenantId(TenantId.SYS_TENANT_ID);  
207 - resource.setResourceType(ResourceType.LWM2M_MODEL);  
208 - resource.setResourceId(path.getFileName().toString());  
209 - resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(path)));  
210 - resourceService.saveResource(resource); 212 + byte[] fileBytes = Files.readAllBytes(path);
  213 + String key = getObjectModelLwm2mValid(fileBytes, path.getFileName().toString(), new DefaultDDFFileValidator());
  214 + if (key != null) {
  215 + Resource resource = new Resource();
  216 + resource.setTenantId(TenantId.SYS_TENANT_ID);
  217 + resource.setResourceType(ResourceType.LWM2M_MODEL);
  218 + resource.setResourceId(key);
  219 + resource.setValue(Base64.getEncoder().encodeToString(fileBytes));
  220 + resourceService.saveResource(resource);
  221 + }
211 } catch (Exception e) { 222 } catch (Exception e) {
212 log.error("Unable to load lwm2m model [{}]", path.toString()); 223 log.error("Unable to load lwm2m model [{}]", path.toString());
213 throw new RuntimeException("Unable to load lwm2m model", e); 224 throw new RuntimeException("Unable to load lwm2m model", e);
@@ -218,17 +229,43 @@ public class InstallScripts { @@ -218,17 +229,43 @@ public class InstallScripts {
218 } 229 }
219 230
220 Path jksPath = Paths.get(getDataDir(), CREDENTIALS_DIR, "serverKeyStore.jks"); 231 Path jksPath = Paths.get(getDataDir(), CREDENTIALS_DIR, "serverKeyStore.jks");
221 - try {  
222 - Resource resource = new Resource();  
223 - resource.setTenantId(TenantId.SYS_TENANT_ID);  
224 - resource.setResourceType(ResourceType.JKS);  
225 - resource.setResourceId(jksPath.getFileName().toString());  
226 - resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath)));  
227 - resourceService.saveResource(resource);  
228 - } catch (Exception e) {  
229 - log.error("Unable to load lwm2m serverKeyStore [{}]", jksPath.toString());  
230 - throw new RuntimeException("Unable to load l2m2m serverKeyStore", e);  
231 - } 232 + try {
  233 + Resource resource = new Resource();
  234 + resource.setTenantId(TenantId.SYS_TENANT_ID);
  235 + resource.setResourceType(ResourceType.JKS);
  236 + resource.setResourceId(jksPath.getFileName().toString());
  237 + resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath)));
  238 + resourceService.saveResource(resource);
  239 + } catch (Exception e) {
  240 + log.error("Unable to load lwm2m serverKeyStore [{}]", jksPath.toString());
  241 + throw new RuntimeException("Unable to load l2m2m serverKeyStore", e);
  242 + }
  243 + }
  244 +
  245 + private String getObjectModelLwm2mValid(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) {
  246 + try {
  247 + DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator);
  248 + ObjectModel objectModel = ddfFileParser.parseEx(new ByteArrayInputStream(xmlByte), streamName).get(0);
  249 + return objectModel.id + "##" + objectModel.getVersion();
  250 + } catch (IOException | InvalidDDFFileException e) {
  251 + log.error("Could not parse the XML file [{}]", streamName, e);
  252 + return null;
  253 + }
  254 +
  255 + }
  256 +
  257 + private void removeFile(Path modelsDir, String nameFile, byte[] fileBytes) {
  258 + String path = "/home/nick/Igor_project/thingsboard_ce_3_2_docker/thingsboard/common/transport/lwm2m/src/main/resources/models/";
  259 + File file = new File(path + nameFile);
  260 + if (!file.isDirectory()) {
  261 + try {
  262 + Files.write(Paths.get(path + "server/" + nameFile), fileBytes);
  263 + file.delete();
  264 + } catch (IOException e) {
  265 + e.printStackTrace();
  266 + }
  267 +
  268 + }
232 } 269 }
233 270
234 public void loadDashboards(TenantId tenantId, CustomerId customerId) throws Exception { 271 public void loadDashboards(TenantId tenantId, CustomerId customerId) throws Exception {
@@ -447,6 +447,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService @@ -447,6 +447,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
447 " );"); 447 " );");
448 448
449 conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3003000;"); 449 conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3003000;");
  450 + installScripts.loadSystemLwm2mResources();
450 } catch (Exception e) { 451 } catch (Exception e) {
451 log.error("Failed updating schema!!!", e); 452 log.error("Failed updating schema!!!", e);
452 } 453 }
@@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.page.PageLink; @@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.page.PageLink;
33 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap; 33 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap;
34 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; 34 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
35 import org.thingsboard.server.dao.service.Validator; 35 import org.thingsboard.server.dao.service.Validator;
36 -import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;  
37 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; 36 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
38 37
39 import java.math.BigInteger; 38 import java.math.BigInteger;
@@ -102,8 +101,8 @@ public class LwM2MModelsRepository { @@ -102,8 +101,8 @@ public class LwM2MModelsRepository {
102 */ 101 */
103 private List<LwM2mObject> getLwm2mObjects(Predicate<? super ObjectModel> predicate, String sortProperty, String sortOrder) { 102 private List<LwM2mObject> getLwm2mObjects(Predicate<? super ObjectModel> predicate, String sortProperty, String sortOrder) {
104 List<LwM2mObject> lwM2mObjects = new ArrayList<>(); 103 List<LwM2mObject> lwM2mObjects = new ArrayList<>();
105 - List<ObjectModel> listObjects = (predicate == null) ? this.contextServer.getModelsValue() :  
106 - contextServer.getModelsValue().stream() 104 + List<ObjectModel> listObjects = (predicate == null) ? this.contextServer.getModelsValueCommon() :
  105 + contextServer.getModelsValueCommon().stream()
107 .filter(predicate) 106 .filter(predicate)
108 .collect(Collectors.toList()); 107 .collect(Collectors.toList());
109 108
@@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.Device; @@ -26,6 +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.Tenant; 30 import org.thingsboard.server.common.data.Tenant;
30 import org.thingsboard.server.common.data.TenantProfile; 31 import org.thingsboard.server.common.data.TenantProfile;
31 import org.thingsboard.server.common.data.id.DeviceId; 32 import org.thingsboard.server.common.data.id.DeviceId;
@@ -34,7 +35,6 @@ import org.thingsboard.server.common.data.id.EntityId; @@ -34,7 +35,6 @@ import org.thingsboard.server.common.data.id.EntityId;
34 import org.thingsboard.server.common.data.id.RuleChainId; 35 import org.thingsboard.server.common.data.id.RuleChainId;
35 import org.thingsboard.server.common.data.id.TenantId; 36 import org.thingsboard.server.common.data.id.TenantId;
36 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 37 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
37 -import org.thingsboard.server.common.data.Resource;  
38 import org.thingsboard.server.common.msg.TbMsg; 38 import org.thingsboard.server.common.msg.TbMsg;
39 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 39 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
40 import org.thingsboard.server.common.msg.queue.ServiceType; 40 import org.thingsboard.server.common.msg.queue.ServiceType;
@@ -19,12 +19,12 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; @@ -19,12 +19,12 @@ 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.Tenant; 23 import org.thingsboard.server.common.data.Tenant;
23 import org.thingsboard.server.common.data.TenantProfile; 24 import org.thingsboard.server.common.data.TenantProfile;
24 import org.thingsboard.server.common.data.id.EntityId; 25 import org.thingsboard.server.common.data.id.EntityId;
25 import org.thingsboard.server.common.data.id.TenantId; 26 import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; 27 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
27 -import org.thingsboard.server.common.data.Resource;  
28 import org.thingsboard.server.common.msg.TbMsg; 28 import org.thingsboard.server.common.msg.TbMsg;
29 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; 29 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
30 import org.thingsboard.server.gen.transport.TransportProtos; 30 import org.thingsboard.server.gen.transport.TransportProtos;
@@ -31,6 +31,8 @@ import org.thingsboard.server.common.data.DataConstants; @@ -31,6 +31,8 @@ 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;
  35 +import org.thingsboard.server.common.data.ResourceType;
34 import org.thingsboard.server.common.data.TenantProfile; 36 import org.thingsboard.server.common.data.TenantProfile;
35 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; 37 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
36 import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; 38 import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
@@ -42,8 +44,6 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -42,8 +44,6 @@ import org.thingsboard.server.common.data.id.TenantId;
42 import org.thingsboard.server.common.data.relation.EntityRelation; 44 import org.thingsboard.server.common.data.relation.EntityRelation;
43 import org.thingsboard.server.common.data.security.DeviceCredentials; 45 import org.thingsboard.server.common.data.security.DeviceCredentials;
44 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 46 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
45 -import org.thingsboard.server.common.data.Resource;  
46 -import org.thingsboard.server.common.data.ResourceType;  
47 import org.thingsboard.server.common.msg.EncryptionUtil; 47 import org.thingsboard.server.common.msg.EncryptionUtil;
48 import org.thingsboard.server.common.msg.TbMsg; 48 import org.thingsboard.server.common.msg.TbMsg;
49 import org.thingsboard.server.common.msg.TbMsgDataType; 49 import org.thingsboard.server.common.msg.TbMsgDataType;
@@ -15,11 +15,13 @@ @@ -15,11 +15,13 @@
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.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.PageData; 21 import org.thingsboard.server.common.data.page.PageData;
20 import org.thingsboard.server.common.data.page.PageLink; 22 import org.thingsboard.server.common.data.page.PageLink;
21 -import org.thingsboard.server.common.data.Resource;  
22 -import org.thingsboard.server.common.data.ResourceType; 23 +
  24 +import java.util.List;
23 25
24 26
25 public interface ResourceService { 27 public interface ResourceService {
@@ -29,6 +31,8 @@ public interface ResourceService { @@ -29,6 +31,8 @@ public interface ResourceService {
29 31
30 PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink); 32 PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink);
31 33
  34 + List<Resource> findResourcesByTenantIdResourceType(TenantId tenantId, ResourceType resourceType);
  35 +
32 void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId); 36 void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId);
33 37
34 void deleteResourcesByTenantId(TenantId tenantId); 38 void deleteResourcesByTenantId(TenantId tenantId);
  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.transport.resource;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.HasTenantId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
  21 +
  22 +@Data
  23 +public class Resource implements HasTenantId {
  24 + private TenantId tenantId;
  25 + private ResourceType resourceType;
  26 + private String resourceId;
  27 + private String value;
  28 +
  29 + @Override
  30 + public String toString() {
  31 + return "Resource{" +
  32 + "tenantId=" + tenantId +
  33 + ", resourceType=" + resourceType +
  34 + ", resourceId='" + resourceId + '\'' +
  35 + '}';
  36 + }
  37 +}
  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.transport.resource;
  17 +
  18 +public enum ResourceType {
  19 + LWM2M_MODEL, JKS, PKCS_12
  20 +}
@@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap; @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.scandium.config.DtlsConnectorConfig; 19 import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
20 -import org.eclipse.leshan.core.model.StaticModel;  
21 import org.eclipse.leshan.core.util.Hex; 20 import org.eclipse.leshan.core.util.Hex;
22 import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager; 21 import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager;
23 import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer; 22 import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
@@ -94,7 +93,7 @@ public class LwM2MTransportBootstrapServerConfiguration { @@ -94,7 +93,7 @@ public class LwM2MTransportBootstrapServerConfiguration {
94 builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort)); 93 builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort));
95 94
96 /** Define model provider (Create Models )*/ 95 /** Define model provider (Create Models )*/
97 - builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValue())); 96 +// builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValueCommon()));
98 97
99 /** Create credentials */ 98 /** Create credentials */
100 this.setServerWithCredentials(builder); 99 this.setServerWithCredentials(builder);
@@ -16,13 +16,13 @@ @@ -16,13 +16,13 @@
16 package org.thingsboard.server.transport.lwm2m.server; 16 package org.thingsboard.server.transport.lwm2m.server;
17 /** 17 /**
18 * Copyright © 2016-2020 The Thingsboard Authors 18 * Copyright © 2016-2020 The Thingsboard Authors
19 - * 19 + * <p>
20 * Licensed under the Apache License, Version 2.0 (the "License"); 20 * Licensed under the Apache License, Version 2.0 (the "License");
21 * you may not use this file except in compliance with the License. 21 * you may not use this file except in compliance with the License.
22 * You may obtain a copy of the License at 22 * You may obtain a copy of the License at
23 - * 23 + * <p>
24 * http://www.apache.org/licenses/LICENSE-2.0 24 * http://www.apache.org/licenses/LICENSE-2.0
25 - * 25 + * <p>
26 * Unless required by applicable law or agreed to in writing, software 26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS, 27 * distributed under the License is distributed on an "AS IS" BASIS,
28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,16 +34,27 @@ import com.google.gson.JsonElement; @@ -34,16 +34,27 @@ import com.google.gson.JsonElement;
34 import com.google.gson.JsonObject; 34 import com.google.gson.JsonObject;
35 import lombok.Getter; 35 import lombok.Getter;
36 import lombok.extern.slf4j.Slf4j; 36 import lombok.extern.slf4j.Slf4j;
  37 +import org.eclipse.leshan.core.model.DDFFileParser;
  38 +import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
  39 +import org.eclipse.leshan.core.model.InvalidDDFFileException;
  40 +import org.eclipse.leshan.core.model.ObjectModel;
37 import org.springframework.stereotype.Component; 41 import org.springframework.stereotype.Component;
38 import org.thingsboard.server.common.transport.TransportContext; 42 import org.thingsboard.server.common.transport.TransportContext;
  43 +import org.thingsboard.server.common.transport.TransportResourceCache;
39 import org.thingsboard.server.common.transport.TransportService; 44 import org.thingsboard.server.common.transport.TransportService;
40 import org.thingsboard.server.common.transport.TransportServiceCallback; 45 import org.thingsboard.server.common.transport.TransportServiceCallback;
41 import org.thingsboard.server.common.transport.adaptor.AdaptorException; 46 import org.thingsboard.server.common.transport.adaptor.AdaptorException;
42 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; 47 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
43 -import org.thingsboard.server.gen.transport.TransportProtos; 48 +import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
  49 +import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg;
  50 +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
  51 +import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
44 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 52 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
45 import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; 53 import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
46 54
  55 +import java.io.ByteArrayInputStream;
  56 +import java.io.IOException;
  57 +
47 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; 58 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
48 59
49 @Slf4j 60 @Slf4j
@@ -56,12 +67,16 @@ public class LwM2mTransportContextServer extends TransportContext { @@ -56,12 +67,16 @@ public class LwM2mTransportContextServer extends TransportContext {
56 67
57 private final TransportService transportService; 68 private final TransportService transportService;
58 69
  70 + private final TransportResourceCache transportResourceCache;
  71 +
  72 +
59 @Getter 73 @Getter
60 private final LwM2MJsonAdaptor adaptor; 74 private final LwM2MJsonAdaptor adaptor;
61 75
62 - public LwM2mTransportContextServer(LwM2MTransportConfigServer lwM2MTransportConfigServer, TransportService transportService, LwM2MJsonAdaptor adaptor) { 76 + public LwM2mTransportContextServer(LwM2MTransportConfigServer lwM2MTransportConfigServer, TransportService transportService, TransportResourceCache transportResourceCache, LwM2MJsonAdaptor adaptor) {
63 this.lwM2MTransportConfigServer = lwM2MTransportConfigServer; 77 this.lwM2MTransportConfigServer = lwM2MTransportConfigServer;
64 this.transportService = transportService; 78 this.transportService = transportService;
  79 + this.transportResourceCache = transportResourceCache;
65 this.adaptor = adaptor; 80 this.adaptor = adaptor;
66 } 81 }
67 82
@@ -69,6 +84,10 @@ public class LwM2mTransportContextServer extends TransportContext { @@ -69,6 +84,10 @@ public class LwM2mTransportContextServer extends TransportContext {
69 return this.lwM2MTransportConfigServer; 84 return this.lwM2MTransportConfigServer;
70 } 85 }
71 86
  87 + public TransportResourceCache getTransportResourceCache() {
  88 + return this.transportResourceCache;
  89 + }
  90 +
72 /** 91 /**
73 * Sent to Thingsboard Attribute || Telemetry 92 * Sent to Thingsboard Attribute || Telemetry
74 * 93 *
@@ -89,14 +108,14 @@ public class LwM2mTransportContextServer extends TransportContext { @@ -89,14 +108,14 @@ public class LwM2mTransportContextServer extends TransportContext {
89 }; 108 };
90 } 109 }
91 110
92 - public void sentParametersOnThingsboard(JsonElement msg, String topicName, TransportProtos.SessionInfoProto sessionInfo) { 111 + public void sentParametersOnThingsboard(JsonElement msg, String topicName, SessionInfoProto sessionInfo) {
93 try { 112 try {
94 if (topicName.equals(LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) { 113 if (topicName.equals(LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) {
95 - TransportProtos.PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg); 114 + PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg);
96 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postAttributeMsg); 115 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postAttributeMsg);
97 transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSentAttrTelemetry(call)); 116 transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSentAttrTelemetry(call));
98 } else if (topicName.equals(LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC)) { 117 } else if (topicName.equals(LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC)) {
99 - TransportProtos.PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg); 118 + PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg);
100 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postTelemetryMsg); 119 TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(postTelemetryMsg);
101 transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSentAttrTelemetry(call)); 120 transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSentAttrTelemetry(call));
102 } 121 }
@@ -115,8 +134,8 @@ public class LwM2mTransportContextServer extends TransportContext { @@ -115,8 +134,8 @@ public class LwM2mTransportContextServer extends TransportContext {
115 /** 134 /**
116 * @return - sessionInfo after access connect client 135 * @return - sessionInfo after access connect client
117 */ 136 */
118 - public TransportProtos.SessionInfoProto getValidateSessionInfo(TransportProtos.ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) {  
119 - return TransportProtos.SessionInfoProto.newBuilder() 137 + public SessionInfoProto getValidateSessionInfo(ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) {
  138 + return SessionInfoProto.newBuilder()
120 .setNodeId(this.getNodeId()) 139 .setNodeId(this.getNodeId())
121 .setSessionIdMSB(mostSignificantBits) 140 .setSessionIdMSB(mostSignificantBits)
122 .setSessionIdLSB(leastSignificantBits) 141 .setSessionIdLSB(leastSignificantBits)
@@ -131,4 +150,13 @@ public class LwM2mTransportContextServer extends TransportContext { @@ -131,4 +150,13 @@ public class LwM2mTransportContextServer extends TransportContext {
131 .build(); 150 .build();
132 } 151 }
133 152
  153 + public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) {
  154 + try {
  155 + DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator);
  156 + return ddfFileParser.parseEx(new ByteArrayInputStream(xmlByte), streamName).get(0);
  157 + } catch (IOException | InvalidDDFFileException e) {
  158 + log.error("Could not parse the XML file [{}]", streamName, e);
  159 + return null;
  160 + }
  161 + }
134 } 162 }
@@ -35,6 +35,7 @@ import org.eclipse.leshan.server.californium.LeshanServerBuilder; @@ -35,6 +35,7 @@ import org.eclipse.leshan.server.californium.LeshanServerBuilder;
35 import org.nustaq.serialization.FSTConfiguration; 35 import org.nustaq.serialization.FSTConfiguration;
36 import org.thingsboard.server.common.data.DeviceProfile; 36 import org.thingsboard.server.common.data.DeviceProfile;
37 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; 37 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
  38 +import org.thingsboard.server.common.data.id.TenantId;
38 import org.thingsboard.server.common.transport.TransportServiceCallback; 39 import org.thingsboard.server.common.transport.TransportServiceCallback;
39 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 40 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
40 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; 41 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
@@ -188,8 +189,9 @@ public class LwM2mTransportHandler { @@ -188,8 +189,9 @@ public class LwM2mTransportHandler {
188 return null; 189 return null;
189 } 190 }
190 191
191 - public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData) { 192 + public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) {
192 LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile(); 193 LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile();
  194 + lwM2MClientProfile.setTenantId(tenantId);
193 lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject()); 195 lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject());
194 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); 196 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject());
195 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); 197 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray());
@@ -221,7 +223,7 @@ public class LwM2mTransportHandler { @@ -221,7 +223,7 @@ public class LwM2mTransportHandler {
221 ObjectMapper mapper = new ObjectMapper(); 223 ObjectMapper mapper = new ObjectMapper();
222 String profileStr = mapper.writeValueAsString(profile); 224 String profileStr = mapper.writeValueAsString(profile);
223 JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null; 225 JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
224 - return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson) : null; 226 + return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null;
225 } catch (IOException e) { 227 } catch (IOException e) {
226 log.error("", e); 228 log.error("", e);
227 } 229 }
@@ -47,7 +47,6 @@ import org.eclipse.leshan.core.util.Hex; @@ -47,7 +47,6 @@ import org.eclipse.leshan.core.util.Hex;
47 import org.eclipse.leshan.core.util.NamedThreadFactory; 47 import org.eclipse.leshan.core.util.NamedThreadFactory;
48 import org.eclipse.leshan.server.californium.LeshanServer; 48 import org.eclipse.leshan.server.californium.LeshanServer;
49 import org.eclipse.leshan.server.registration.Registration; 49 import org.eclipse.leshan.server.registration.Registration;
50 -import org.springframework.beans.factory.annotation.Autowired;  
51 import org.springframework.stereotype.Service; 50 import org.springframework.stereotype.Service;
52 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 51 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
53 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 52 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
@@ -88,13 +87,13 @@ public class LwM2mTransportRequest { @@ -88,13 +87,13 @@ public class LwM2mTransportRequest {
88 87
89 private final LeshanServer leshanServer; 88 private final LeshanServer leshanServer;
90 89
91 - @Autowired  
92 - private LwM2mTransportServiceImpl serviceImpl; 90 + private final LwM2mTransportServiceImpl serviceImpl;
93 91
94 - public LwM2mTransportRequest(LwM2mTransportContextServer context, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer) { 92 + public LwM2mTransportRequest(LwM2mTransportContextServer context, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, LwM2mTransportServiceImpl serviceImpl) {
95 this.context = context; 93 this.context = context;
96 this.lwM2mClientContext = lwM2mClientContext; 94 this.lwM2mClientContext = lwM2mClientContext;
97 this.leshanServer = leshanServer; 95 this.leshanServer = leshanServer;
  96 + this.serviceImpl = serviceImpl;
98 } 97 }
99 98
100 @PostConstruct 99 @PostConstruct
@@ -230,6 +229,7 @@ public class LwM2mTransportRequest { @@ -230,6 +229,7 @@ public class LwM2mTransportRequest {
230 private void sendRequest(Registration registration, DownlinkRequest request, long timeoutInMs) { 229 private void sendRequest(Registration registration, DownlinkRequest request, long timeoutInMs) {
231 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); 230 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
232 leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { 231 leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
  232 +
233 if (!lwM2MClient.isInit()) { 233 if (!lwM2MClient.isInit()) {
234 lwM2MClient.initValue(this.serviceImpl, request.getPath().toString()); 234 lwM2MClient.initValue(this.serviceImpl, request.getPath().toString());
235 } 235 }
@@ -24,14 +24,13 @@ import org.eclipse.leshan.server.californium.LeshanServer; @@ -24,14 +24,13 @@ import org.eclipse.leshan.server.californium.LeshanServer;
24 import org.eclipse.leshan.server.californium.LeshanServerBuilder; 24 import org.eclipse.leshan.server.californium.LeshanServerBuilder;
25 import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; 25 import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
26 import org.eclipse.leshan.server.model.LwM2mModelProvider; 26 import org.eclipse.leshan.server.model.LwM2mModelProvider;
27 -import org.eclipse.leshan.server.model.VersionedModelProvider;  
28 import org.eclipse.leshan.server.security.DefaultAuthorizer; 27 import org.eclipse.leshan.server.security.DefaultAuthorizer;
29 import org.eclipse.leshan.server.security.EditableSecurityStore; 28 import org.eclipse.leshan.server.security.EditableSecurityStore;
30 import org.eclipse.leshan.server.security.SecurityChecker; 29 import org.eclipse.leshan.server.security.SecurityChecker;
31 -import org.springframework.beans.factory.annotation.Autowired;  
32 import org.springframework.context.annotation.Bean; 30 import org.springframework.context.annotation.Bean;
33 import org.springframework.stereotype.Component; 31 import org.springframework.stereotype.Component;
34 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 32 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
  33 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
35 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 34 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
36 35
37 import java.math.BigInteger; 36 import java.math.BigInteger;
@@ -61,21 +60,23 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_W @@ -61,21 +60,23 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_W
61 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig; 60 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig;
62 61
63 @Slf4j 62 @Slf4j
64 -@Component("LwM2MTransportServerConfiguration") 63 +@Component
65 @TbLwM2mTransportComponent 64 @TbLwM2mTransportComponent
66 public class LwM2mTransportServerConfiguration { 65 public class LwM2mTransportServerConfiguration {
67 private PublicKey publicKey; 66 private PublicKey publicKey;
68 private PrivateKey privateKey; 67 private PrivateKey privateKey;
69 private boolean pskMode = false; 68 private boolean pskMode = false;
  69 + private final LwM2mTransportContextServer context;
  70 + private final CaliforniumRegistrationStore registrationStore;
  71 + private final EditableSecurityStore securityStore;
  72 + private final LwM2mClientContext lwM2mClientContext;
70 73
71 - @Autowired  
72 - private LwM2mTransportContextServer context;  
73 -  
74 - @Autowired  
75 - private CaliforniumRegistrationStore registrationStore;  
76 -  
77 - @Autowired  
78 - private EditableSecurityStore securityStore; 74 + public LwM2mTransportServerConfiguration(LwM2mTransportContextServer context, CaliforniumRegistrationStore registrationStore, EditableSecurityStore securityStore, LwM2mClientContext lwM2mClientContext) {
  75 + this.context = context;
  76 + this.registrationStore = registrationStore;
  77 + this.securityStore = securityStore;
  78 + this.lwM2mClientContext = lwM2mClientContext;
  79 + }
79 80
80 @Bean 81 @Bean
81 public LeshanServer getLeshanServer() { 82 public LeshanServer getLeshanServer() {
@@ -95,7 +96,8 @@ public class LwM2mTransportServerConfiguration { @@ -95,7 +96,8 @@ public class LwM2mTransportServerConfiguration {
95 builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort)); 96 builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort));
96 97
97 /** Define model provider (Create Models )*/ 98 /** Define model provider (Create Models )*/
98 - LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValue()); 99 + LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.lwM2mClientContext, this.context);
  100 + this.context.getLwM2MTransportConfigServer().setModelProvider(modelProvider);
99 builder.setObjectModelProvider(modelProvider); 101 builder.setObjectModelProvider(modelProvider);
100 102
101 /** Create credentials */ 103 /** Create credentials */
@@ -652,21 +652,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -652,21 +652,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
652 return (clientInstances.size() > 0) ? clientInstances : null; 652 return (clientInstances.size() > 0) ? clientInstances : null;
653 } 653 }
654 654
655 -// /**  
656 -// * get AttrName/TelemetryName with value from Client  
657 -// *  
658 -// * @param registration -  
659 -// * @return - JsonObject, format: {name: value}}  
660 -// */  
661 -// private JsonObject getAttributeClient(Registration registration) {  
662 -// if (registration.getAdditionalRegistrationAttributes().size() > 0) {  
663 -// JsonObject resNameValues = new JsonObject();  
664 -// registration.getAdditionalRegistrationAttributes().forEach(resNameValues::addProperty);  
665 -// return resNameValues;  
666 -// }  
667 -// return null;  
668 -// }  
669 -  
670 /** 655 /**
671 * @param attributes - new JsonObject 656 * @param attributes - new JsonObject
672 * @param telemetry - new JsonObject 657 * @param telemetry - new JsonObject
  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.transport.lwm2m.server;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
  20 +import org.eclipse.leshan.core.model.LwM2mModel;
  21 +import org.eclipse.leshan.core.model.ObjectModel;
  22 +import org.eclipse.leshan.core.model.ResourceModel;
  23 +import org.eclipse.leshan.server.model.LwM2mModelProvider;
  24 +import org.eclipse.leshan.server.registration.Registration;
  25 +import org.thingsboard.server.common.data.id.TenantId;
  26 +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
  27 +
  28 +import java.util.ArrayList;
  29 +import java.util.Base64;
  30 +import java.util.Collection;
  31 +import java.util.Iterator;
  32 +import java.util.Map;
  33 +
  34 +import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL;
  35 +
  36 +@Slf4j
  37 +public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
  38 +
  39 + /**
  40 + * int objectId
  41 + * String version ("1.01")
  42 + * Key = objectId + "##" + version
  43 + * Value = TenantId
  44 + */
  45 + private final LwM2mClientContext lwM2mClientContext;
  46 + private final LwM2mTransportContextServer lwM2mTransportContextServer;
  47 +
  48 + public LwM2mVersionedModelProvider(LwM2mClientContext lwM2mClientContext, LwM2mTransportContextServer lwM2mTransportContextServer) {
  49 + this.lwM2mClientContext = lwM2mClientContext;
  50 + this.lwM2mTransportContextServer = lwM2mTransportContextServer;
  51 + }
  52 + private String getIdVer(ObjectModel objectModel) {
  53 + return objectModel.id + "##" + ((objectModel.getVersion() == null || objectModel.getVersion().isEmpty()) ? ObjectModel.DEFAULT_VERSION : objectModel.getVersion());
  54 + }
  55 +
  56 + private String getIdVer(Integer objectId, String version) {
  57 + return objectId != null ? objectId + "##" + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
  58 + }
  59 +
  60 + /**
  61 + * Update repository if need
  62 + *
  63 + * @param registration
  64 + * @return
  65 + */
  66 + @Override
  67 + public LwM2mModel getObjectModel(Registration registration) {
  68 + return new DynamicModel(registration
  69 + );
  70 + }
  71 +
  72 + private class DynamicModel implements LwM2mModel {
  73 +
  74 + private final Registration registration;
  75 + private final TenantId tenantId;
  76 +
  77 + public DynamicModel(Registration registration) {
  78 + this.registration = registration;
  79 + this.tenantId = lwM2mClientContext.getProfile(registration).getTenantId();
  80 + }
  81 +
  82 + @Override
  83 + public ResourceModel getResourceModel(int objectId, int resourceId) {
  84 + try {
  85 + ObjectModel objectModel = getObjectModel(objectId);
  86 + if (objectModel != null)
  87 + return objectModel.resources.get(resourceId);
  88 + else
  89 + return null;
  90 + } catch (Exception e) {
  91 + log.error("", e);
  92 + return null;
  93 + }
  94 + }
  95 +
  96 + @Override
  97 + public ObjectModel getObjectModel(int objectId) {
  98 + String version = registration.getSupportedVersion(objectId);
  99 + if (version != null) {
  100 + return this.getObjectModelDynamic(objectId, version);
  101 + }
  102 + return null;
  103 + }
  104 +
  105 + @Override
  106 + public Collection<ObjectModel> getObjectModels() {
  107 + Map<Integer, String> supportedObjects = this.registration.getSupportedObject();
  108 + Collection<ObjectModel> result = new ArrayList(supportedObjects.size());
  109 + Iterator i$ = supportedObjects.entrySet().iterator();
  110 +
  111 + while (i$.hasNext()) {
  112 + Map.Entry<Integer, String> supportedObject = (Map.Entry) i$.next();
  113 + ObjectModel objectModel = this.getObjectModelDynamic((Integer) supportedObject.getKey(), (String) supportedObject.getValue());
  114 + if (objectModel != null) {
  115 + result.add(objectModel);
  116 + }
  117 + }
  118 + return result;
  119 + }
  120 +
  121 + private ObjectModel getObjectModelDynamic(Integer objectId, String version) {
  122 + String key = getIdVer(objectId, version);
  123 + String xmlB64 = lwM2mTransportContextServer.getTransportResourceCache().get(
  124 + this.tenantId,
  125 + LWM2M_MODEL,
  126 + key).
  127 + getValue();
  128 + return xmlB64 != null && !xmlB64.isEmpty() ?
  129 + lwM2mTransportContextServer.parseFromXmlToObjectModel(
  130 + Base64.getDecoder().decode(xmlB64),
  131 + key + ".xml",
  132 + new DefaultDDFFileValidator()) :
  133 + null;
  134 + }
  135 + }
  136 +}
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.transport.lwm2m.server.client; 16 package org.thingsboard.server.transport.lwm2m.server.client;
17 17
18 -import lombok.extern.slf4j.Slf4j;  
19 import org.eclipse.leshan.server.registration.Registration; 18 import org.eclipse.leshan.server.registration.Registration;
20 import org.eclipse.leshan.server.security.EditableSecurityStore; 19 import org.eclipse.leshan.server.security.EditableSecurityStore;
21 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
@@ -105,6 +104,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @@ -105,6 +104,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
105 104
106 /** 105 /**
107 * Add new LwM2MClient to session 106 * Add new LwM2MClient to session
  107 + *
108 * @param identity- 108 * @param identity-
109 * @return SecurityInfo. If error - SecurityInfoError 109 * @return SecurityInfo. If error - SecurityInfoError
110 * and log: 110 * and log:
@@ -19,15 +19,18 @@ import com.google.gson.Gson; @@ -19,15 +19,18 @@ import com.google.gson.Gson;
19 import com.google.gson.JsonArray; 19 import com.google.gson.JsonArray;
20 import com.google.gson.JsonObject; 20 import com.google.gson.JsonObject;
21 import lombok.Data; 21 import lombok.Data;
  22 +import org.thingsboard.server.common.data.id.TenantId;
22 23
23 @Data 24 @Data
24 public class LwM2mClientProfile { 25 public class LwM2mClientProfile {
  26 +
  27 + private TenantId tenantId;
25 /** 28 /**
26 * {"clientLwM2mSettings": { 29 * {"clientLwM2mSettings": {
27 * clientUpdateValueAfterConnect: false; 30 * clientUpdateValueAfterConnect: false;
28 * } 31 * }
29 **/ 32 **/
30 - JsonObject postClientLwM2mSettings; 33 + private JsonObject postClientLwM2mSettings;
31 34
32 /** 35 /**
33 * {"keyName": { 36 * {"keyName": {
@@ -36,22 +39,22 @@ public class LwM2mClientProfile { @@ -36,22 +39,22 @@ public class LwM2mClientProfile {
36 * "/3/0/2": "serialNumber" 39 * "/3/0/2": "serialNumber"
37 * } 40 * }
38 **/ 41 **/
39 - JsonObject postKeyNameProfile; 42 + private JsonObject postKeyNameProfile;
40 43
41 /** 44 /**
42 * [ "/2/0/0", "/2/0/1"] 45 * [ "/2/0/0", "/2/0/1"]
43 */ 46 */
44 - JsonArray postAttributeProfile; 47 + private JsonArray postAttributeProfile;
45 48
46 /** 49 /**
47 * [ "/2/0/0", "/2/0/1"] 50 * [ "/2/0/0", "/2/0/1"]
48 */ 51 */
49 - JsonArray postTelemetryProfile; 52 + private JsonArray postTelemetryProfile;
50 53
51 /** 54 /**
52 * [ "/2/0/0", "/2/0/1"] 55 * [ "/2/0/0", "/2/0/1"]
53 */ 56 */
54 - JsonArray postObserveProfile; 57 + private JsonArray postObserveProfile;
55 58
56 public LwM2mClientProfile clone() { 59 public LwM2mClientProfile clone() {
57 LwM2mClientProfile lwM2mClientProfile = new LwM2mClientProfile(); 60 LwM2mClientProfile lwM2mClientProfile = new LwM2mClientProfile();
@@ -26,10 +26,13 @@ import org.eclipse.leshan.core.util.StringUtils; @@ -26,10 +26,13 @@ import org.eclipse.leshan.core.util.StringUtils;
26 import javax.xml.datatype.DatatypeConfigurationException; 26 import javax.xml.datatype.DatatypeConfigurationException;
27 import javax.xml.datatype.DatatypeFactory; 27 import javax.xml.datatype.DatatypeFactory;
28 import javax.xml.datatype.XMLGregorianCalendar; 28 import javax.xml.datatype.XMLGregorianCalendar;
  29 +import java.math.BigInteger;
29 import java.text.DateFormat; 30 import java.text.DateFormat;
30 import java.text.SimpleDateFormat; 31 import java.text.SimpleDateFormat;
31 import java.util.Date; 32 import java.util.Date;
32 33
  34 +import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
  35 +
33 @Slf4j 36 @Slf4j
34 public class LwM2mValueConverterImpl implements LwM2mValueConverter { 37 public class LwM2mValueConverterImpl implements LwM2mValueConverter {
35 38
@@ -51,6 +54,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { @@ -51,6 +54,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
51 /** expected type */ 54 /** expected type */
52 return value; 55 return value;
53 } 56 }
  57 + if (currentType == null) {
  58 + currentType = OPAQUE;
  59 + }
54 60
55 switch (expectedType) { 61 switch (expectedType) {
56 case INTEGER: 62 case INTEGER:
@@ -130,7 +136,13 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { @@ -130,7 +136,13 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
130 return String.valueOf(value); 136 return String.valueOf(value);
131 case TIME: 137 case TIME:
132 String DATE_FORMAT = "MMM d, yyyy HH:mm a"; 138 String DATE_FORMAT = "MMM d, yyyy HH:mm a";
133 - Long timeValue = ((Date) value).getTime(); 139 + Long timeValue;
  140 + try {
  141 + timeValue = ((Date) value).getTime();
  142 + }
  143 + catch (Exception e){
  144 + timeValue = new BigInteger((byte [])value).longValue();
  145 + }
134 DateFormat formatter = new SimpleDateFormat(DATE_FORMAT); 146 DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
135 return formatter.format(new Date(timeValue)); 147 return formatter.format(new Date(timeValue));
136 default: 148 default:
@@ -15,9 +15,9 @@ @@ -15,9 +15,9 @@
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.id.TenantId;  
19 import org.thingsboard.server.common.data.Resource; 18 import org.thingsboard.server.common.data.Resource;
20 import org.thingsboard.server.common.data.ResourceType; 19 import org.thingsboard.server.common.data.ResourceType;
  20 +import org.thingsboard.server.common.data.id.TenantId;
21 21
22 public interface TransportResourceCache { 22 public interface TransportResourceCache {
23 23
@@ -18,10 +18,10 @@ package org.thingsboard.server.common.transport.lwm2m; @@ -18,10 +18,10 @@ package org.thingsboard.server.common.transport.lwm2m;
18 import lombok.Getter; 18 import lombok.Getter;
19 import lombok.Setter; 19 import lombok.Setter;
20 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
21 -import org.eclipse.leshan.core.model.ObjectLoader;  
22 import org.eclipse.leshan.core.model.ObjectModel; 21 import org.eclipse.leshan.core.model.ObjectModel;
23 import org.eclipse.leshan.core.model.ResourceModel; 22 import org.eclipse.leshan.core.model.ResourceModel;
24 import org.eclipse.leshan.core.node.LwM2mPath; 23 import org.eclipse.leshan.core.node.LwM2mPath;
  24 +import org.eclipse.leshan.server.model.LwM2mModelProvider;
25 import org.eclipse.leshan.server.registration.Registration; 25 import org.eclipse.leshan.server.registration.Registration;
26 import org.springframework.beans.factory.annotation.Value; 26 import org.springframework.beans.factory.annotation.Value;
27 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 27 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@@ -38,16 +38,13 @@ import java.security.KeyStore; @@ -38,16 +38,13 @@ import java.security.KeyStore;
38 import java.security.KeyStoreException; 38 import java.security.KeyStoreException;
39 import java.security.NoSuchAlgorithmException; 39 import java.security.NoSuchAlgorithmException;
40 import java.security.cert.CertificateException; 40 import java.security.cert.CertificateException;
41 -import java.util.Arrays;  
42 import java.util.List; 41 import java.util.List;
43 -import java.util.stream.Collectors;  
44 42
45 @Slf4j 43 @Slf4j
46 @Component 44 @Component
47 @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'") 45 @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
48 public class LwM2MTransportConfigServer { 46 public class LwM2MTransportConfigServer {
49 47
50 -  
51 @Getter 48 @Getter
52 private String MODEL_PATH_DEFAULT = "models"; 49 private String MODEL_PATH_DEFAULT = "models";
53 50
@@ -84,7 +81,11 @@ public class LwM2MTransportConfigServer { @@ -84,7 +81,11 @@ public class LwM2MTransportConfigServer {
84 81
85 @Getter 82 @Getter
86 @Setter 83 @Setter
87 - private List<ObjectModel> modelsValue; 84 + private List<ObjectModel> modelsValueCommon;
  85 +
  86 + @Getter
  87 + @Setter
  88 + private LwM2mModelProvider modelProvider;
88 89
89 @Getter 90 @Getter
90 @Value("${transport.lwm2m.timeout:}") 91 @Value("${transport.lwm2m.timeout:}")
@@ -188,29 +189,9 @@ public class LwM2MTransportConfigServer { @@ -188,29 +189,9 @@ public class LwM2MTransportConfigServer {
188 189
189 @PostConstruct 190 @PostConstruct
190 public void init() { 191 public void init() {
191 - modelsValue = ObjectLoader.loadDefault();  
192 - File path = getPathModels();  
193 - if (path.isDirectory()) {  
194 - try {  
195 - modelsValue.addAll(ObjectLoader.loadObjectsFromDir(path));  
196 - log.info(" [{}] Models directory is a directory", path.getAbsoluteFile());  
197 - } catch (Exception e) {  
198 - log.error(" [{}] Could not parse the resource definition file", e.toString());  
199 - }  
200 - } else {  
201 - log.error(" [{}] Read Models", path.getAbsoluteFile());  
202 - }  
203 this.getInKeyStore(); 192 this.getInKeyStore();
204 } 193 }
205 194
206 - private File getPathModels() {  
207 - Path pathModels = (modelPathFile != null && !modelPathFile.isEmpty()) ? Paths.get(modelPathFile) :  
208 - (new File(Paths.get(getBaseDirPath(), PATH_DATA, MODEL_PATH_DEFAULT).toUri()).isDirectory()) ?  
209 - Paths.get(getBaseDirPath(), PATH_DATA, MODEL_PATH_DEFAULT) :  
210 - Paths.get(getBaseDirPath(), APP_DIR, TRANSPORT_DIR, LWM2M_DIR, SRC_DIR, MAIN_DIR, RESOURCES_DIR, MODEL_PATH_DEFAULT);  
211 - return (pathModels != null) ? new File(pathModels.toUri()) : null;  
212 - }  
213 -  
214 private KeyStore getInKeyStore() { 195 private KeyStore getInKeyStore() {
215 try { 196 try {
216 if (keyStoreValue != null && keyStoreValue.size() > 0) 197 if (keyStoreValue != null && keyStoreValue.size() > 0)
@@ -253,12 +234,7 @@ public class LwM2MTransportConfigServer { @@ -253,12 +234,7 @@ public class LwM2MTransportConfigServer {
253 } 234 }
254 235
255 public ResourceModel getResourceModel(Registration registration, LwM2mPath pathIds) { 236 public ResourceModel getResourceModel(Registration registration, LwM2mPath pathIds) {
256 - String pathLink = "/" + pathIds.getObjectId() + "/" + pathIds.getObjectInstanceId();  
257 - return (Arrays.stream(registration.getObjectLinks()).filter(p-> p.getUrl().equals(pathLink)).findFirst().isPresent() &&  
258 - this.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).size() > 0) &&  
259 - this.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.containsKey(pathIds.getResourceId()) ?  
260 - this.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.get(pathIds.getResourceId()) :  
261 - null; 237 + return this.modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId());
262 } 238 }
263 239
264 public ResourceModel.Type getResourceModelType(Registration registration, LwM2mPath pathIds) { 240 public ResourceModel.Type getResourceModelType(Registration registration, LwM2mPath pathIds) {
@@ -270,4 +246,5 @@ public class LwM2MTransportConfigServer { @@ -270,4 +246,5 @@ public class LwM2MTransportConfigServer {
270 ResourceModel resource = this.getResourceModel(registration, pathIds); 246 ResourceModel resource = this.getResourceModel(registration, pathIds);
271 return (resource == null) ? ResourceModel.Operations.NONE : resource.operations; 247 return (resource == null) ? ResourceModel.Operations.NONE : resource.operations;
272 } 248 }
  249 +
273 } 250 }
@@ -19,9 +19,9 @@ import lombok.Data; @@ -19,9 +19,9 @@ 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.id.TenantId;  
23 import org.thingsboard.server.common.data.Resource; 22 import org.thingsboard.server.common.data.Resource;
24 import org.thingsboard.server.common.data.ResourceType; 23 import org.thingsboard.server.common.data.ResourceType;
  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;
26 import org.thingsboard.server.common.transport.TransportService; 26 import org.thingsboard.server.common.transport.TransportService;
27 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; 27 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
@@ -31,13 +31,13 @@ import org.thingsboard.server.common.data.Device; @@ -31,13 +31,13 @@ import org.thingsboard.server.common.data.Device;
31 import org.thingsboard.server.common.data.DeviceProfile; 31 import org.thingsboard.server.common.data.DeviceProfile;
32 import org.thingsboard.server.common.data.DeviceTransportType; 32 import org.thingsboard.server.common.data.DeviceTransportType;
33 import org.thingsboard.server.common.data.EntityType; 33 import org.thingsboard.server.common.data.EntityType;
  34 +import org.thingsboard.server.common.data.ResourceType;
34 import org.thingsboard.server.common.data.Tenant; 35 import org.thingsboard.server.common.data.Tenant;
35 import org.thingsboard.server.common.data.id.DeviceId; 36 import org.thingsboard.server.common.data.id.DeviceId;
36 import org.thingsboard.server.common.data.id.DeviceProfileId; 37 import org.thingsboard.server.common.data.id.DeviceProfileId;
37 import org.thingsboard.server.common.data.id.RuleChainId; 38 import org.thingsboard.server.common.data.id.RuleChainId;
38 import org.thingsboard.server.common.data.id.TenantId; 39 import org.thingsboard.server.common.data.id.TenantId;
39 import org.thingsboard.server.common.data.id.TenantProfileId; 40 import org.thingsboard.server.common.data.id.TenantProfileId;
40 -import org.thingsboard.server.common.data.ResourceType;  
41 import org.thingsboard.server.common.msg.TbMsg; 41 import org.thingsboard.server.common.msg.TbMsg;
42 import org.thingsboard.server.common.msg.TbMsgMetaData; 42 import org.thingsboard.server.common.msg.TbMsgMetaData;
43 import org.thingsboard.server.common.msg.queue.ServiceQueue; 43 import org.thingsboard.server.common.msg.queue.ServiceQueue;
@@ -295,6 +295,7 @@ public class DefaultTransportService implements TransportService { @@ -295,6 +295,7 @@ public class DefaultTransportService implements TransportService {
295 response -> callback.onSuccess(response.getValue().getValidateCredResponseMsg()), callback::onError, transportCallbackExecutor); 295 response -> callback.onSuccess(response.getValue().getValidateCredResponseMsg()), callback::onError, transportCallbackExecutor);
296 } 296 }
297 297
  298 + @Override
298 public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceX509CertRequestMsg msg, TransportServiceCallback<ValidateDeviceCredentialsResponse> callback) { 299 public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceX509CertRequestMsg msg, TransportServiceCallback<ValidateDeviceCredentialsResponse> callback) {
299 log.trace("Processing msg: {}", msg); 300 log.trace("Processing msg: {}", msg);
300 TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), TransportApiRequestMsg.newBuilder().setValidateX509CertRequestMsg(msg).build()); 301 TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), TransportApiRequestMsg.newBuilder().setValidateX509CertRequestMsg(msg).build());
@@ -16,9 +16,9 @@ @@ -16,9 +16,9 @@
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.id.TenantId;  
20 import org.thingsboard.server.common.data.Resource; 19 import org.thingsboard.server.common.data.Resource;
21 import org.thingsboard.server.common.data.ResourceType; 20 import org.thingsboard.server.common.data.ResourceType;
  21 +import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.dao.model.ToData; 22 import org.thingsboard.server.dao.model.ToData;
23 23
24 import javax.persistence.Column; 24 import javax.persistence.Column;
@@ -17,13 +17,15 @@ package org.thingsboard.server.dao.resource; @@ -17,13 +17,15 @@ package org.thingsboard.server.dao.resource;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
  20 +import org.thingsboard.server.common.data.Resource;
  21 +import org.thingsboard.server.common.data.ResourceType;
20 import org.thingsboard.server.common.data.id.TenantId; 22 import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.PageData; 23 import org.thingsboard.server.common.data.page.PageData;
22 import org.thingsboard.server.common.data.page.PageLink; 24 import org.thingsboard.server.common.data.page.PageLink;
23 -import org.thingsboard.server.common.data.Resource;  
24 -import org.thingsboard.server.common.data.ResourceType;  
25 import org.thingsboard.server.dao.exception.DataValidationException; 25 import org.thingsboard.server.dao.exception.DataValidationException;
26 26
  27 +import java.util.List;
  28 +
27 import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; 29 import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID;
28 import static org.thingsboard.server.dao.service.Validator.validateId; 30 import static org.thingsboard.server.dao.service.Validator.validateId;
29 31
@@ -65,6 +67,14 @@ public class BaseResourceService implements ResourceService { @@ -65,6 +67,14 @@ public class BaseResourceService implements ResourceService {
65 return resourceDao.findAllByTenantId(tenantId, pageLink); 67 return resourceDao.findAllByTenantId(tenantId, pageLink);
66 } 68 }
67 69
  70 +
  71 + @Override
  72 + public List<Resource> findResourcesByTenantIdResourceType(TenantId tenantId, ResourceType resourceType) {
  73 + log.trace("Executing findByTenantId [{}]", tenantId);
  74 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  75 + return resourceDao.findAllByTenantIdResourceType(tenantId, resourceType);
  76 + }
  77 +
68 @Override 78 @Override
69 public void deleteResourcesByTenantId(TenantId tenantId) { 79 public void deleteResourcesByTenantId(TenantId tenantId) {
70 log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId); 80 log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId);
@@ -15,11 +15,13 @@ @@ -15,11 +15,13 @@
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.id.TenantId; 20 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.PageData; 21 import org.thingsboard.server.common.data.page.PageData;
20 import org.thingsboard.server.common.data.page.PageLink; 22 import org.thingsboard.server.common.data.page.PageLink;
21 -import org.thingsboard.server.common.data.Resource;  
22 -import org.thingsboard.server.common.data.ResourceType; 23 +
  24 +import java.util.List;
23 25
24 public interface ResourceDao { 26 public interface ResourceDao {
25 27
@@ -31,5 +33,8 @@ public interface ResourceDao { @@ -31,5 +33,8 @@ public interface ResourceDao {
31 33
32 PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink); 34 PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink);
33 35
  36 +
  37 + List<Resource> findAllByTenantIdResourceType(TenantId tenantId, ResourceType resourceType);
  38 +
34 void removeAllByTenantId(TenantId tenantId); 39 void removeAllByTenantId(TenantId tenantId);
35 } 40 }
@@ -18,16 +18,18 @@ package org.thingsboard.server.dao.sql.resource; @@ -18,16 +18,18 @@ package org.thingsboard.server.dao.sql.resource;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
20 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
  21 +import org.thingsboard.server.common.data.Resource;
  22 +import org.thingsboard.server.common.data.ResourceType;
21 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.PageData; 24 import org.thingsboard.server.common.data.page.PageData;
23 import org.thingsboard.server.common.data.page.PageLink; 25 import org.thingsboard.server.common.data.page.PageLink;
24 -import org.thingsboard.server.common.data.Resource;  
25 -import org.thingsboard.server.common.data.ResourceType;  
26 import org.thingsboard.server.dao.DaoUtil; 26 import org.thingsboard.server.dao.DaoUtil;
27 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey; 27 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;
28 import org.thingsboard.server.dao.model.sql.ResourceEntity; 28 import org.thingsboard.server.dao.model.sql.ResourceEntity;
29 import org.thingsboard.server.dao.resource.ResourceDao; 29 import org.thingsboard.server.dao.resource.ResourceDao;
30 30
  31 +import java.util.List;
  32 +
31 @Slf4j 33 @Slf4j
32 @Component 34 @Component
33 public class ResourceDaoImpl implements ResourceDao { 35 public class ResourceDaoImpl implements ResourceDao {
@@ -71,6 +73,11 @@ public class ResourceDaoImpl implements ResourceDao { @@ -71,6 +73,11 @@ public class ResourceDaoImpl implements ResourceDao {
71 } 73 }
72 74
73 @Override 75 @Override
  76 + public List<Resource> findAllByTenantIdResourceType(TenantId tenantId, ResourceType resourceType) {
  77 + return DaoUtil.convertDataList(resourceRepository.findAllByTenantIdAndResourceType(tenantId.getId(), resourceType.name()));
  78 + }
  79 +
  80 + @Override
74 public void removeAllByTenantId(TenantId tenantId) { 81 public void removeAllByTenantId(TenantId tenantId) {
75 resourceRepository.removeAllByTenantId(tenantId.getId()); 82 resourceRepository.removeAllByTenantId(tenantId.getId());
76 } 83 }
@@ -21,11 +21,15 @@ import org.springframework.data.repository.CrudRepository; @@ -21,11 +21,15 @@ import org.springframework.data.repository.CrudRepository;
21 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey; 21 import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;
22 import org.thingsboard.server.dao.model.sql.ResourceEntity; 22 import org.thingsboard.server.dao.model.sql.ResourceEntity;
23 23
  24 +import java.util.List;
24 import java.util.UUID; 25 import java.util.UUID;
25 26
26 public interface ResourceRepository extends CrudRepository<ResourceEntity, ResourceCompositeKey> { 27 public interface ResourceRepository extends CrudRepository<ResourceEntity, ResourceCompositeKey> {
27 28
28 Page<ResourceEntity> findAllByTenantId(UUID tenantId, Pageable pageable); 29 Page<ResourceEntity> findAllByTenantId(UUID tenantId, Pageable pageable);
29 30
  31 +
  32 + List<ResourceEntity> findAllByTenantIdAndResourceType(UUID tenantId, String resourceType);
  33 +
30 void removeAllByTenantId(UUID tenantId); 34 void removeAllByTenantId(UUID tenantId);
31 } 35 }
@@ -66,9 +66,9 @@ @@ -66,9 +66,9 @@
66 <jackson-core.version>2.12.1</jackson-core.version> 66 <jackson-core.version>2.12.1</jackson-core.version>
67 <json-schema-validator.version>2.2.6</json-schema-validator.version> 67 <json-schema-validator.version>2.2.6</json-schema-validator.version>
68 <californium.version>2.6.1</californium.version> 68 <californium.version>2.6.1</californium.version>
69 - <leshan-server.version>1.3.0</leshan-server.version>  
70 - <leshan-core.version>1.3.0</leshan-core.version>  
71 - <leshan-client.version>1.3.0</leshan-client.version> 69 + <leshan-server.version>1.3.1</leshan-server.version>
  70 + <leshan-core.version>1.3.1</leshan-core.version>
  71 + <leshan-client.version>1.3.1</leshan-client.version>
72 <gson.version>2.6.2</gson.version> 72 <gson.version>2.6.2</gson.version>
73 <freemarker.version>2.3.30</freemarker.version> 73 <freemarker.version>2.3.30</freemarker.version>
74 <mail.version>1.6.2</mail.version> 74 <mail.version>1.6.2</mail.version>