fixed xxe vulnerability
This commit is contained in:
parent
52a31dffc5
commit
9b461272c4
@ -16,8 +16,6 @@
|
||||
package org.thingsboard.server.service.resource;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.model.DDFFileParser;
|
||||
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ResourceType;
|
||||
@ -53,11 +51,9 @@ import static org.thingsboard.server.utils.LwM2mObjectModelUtils.toLwm2mResource
|
||||
public class DefaultTbResourceService extends AbstractTbEntityService implements TbResourceService {
|
||||
|
||||
private final ResourceService resourceService;
|
||||
private final DDFFileParser ddfFileParser;
|
||||
|
||||
public DefaultTbResourceService(ResourceService resourceService) {
|
||||
this.resourceService = resourceService;
|
||||
this.ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.lwm2m.LwM2mInstance;
|
||||
import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
|
||||
import org.thingsboard.server.common.data.lwm2m.LwM2mResourceObserve;
|
||||
import org.thingsboard.server.common.data.util.TbDDFFileParser;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -41,7 +42,7 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA
|
||||
@Slf4j
|
||||
public class LwM2mObjectModelUtils {
|
||||
|
||||
private static final DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
|
||||
private static final TbDDFFileParser ddfFileParser = new TbDDFFileParser();
|
||||
|
||||
public static void toLwm2mResource (TbResource resource) throws ThingsboardException {
|
||||
try {
|
||||
|
||||
@ -45,6 +45,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@DaoSqlTest
|
||||
@ -75,6 +77,32 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
"</Object>\n" +
|
||||
"</LWM2M>";
|
||||
|
||||
private static final String LWM2M_TEST_MODEL_WITH_XXE = "<!DOCTYPE replace [<!ENTITY ObjectVersion SYSTEM \"file:///etc/hostname\"> ]>" +
|
||||
"<LWM2M xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.openmobilealliance.org/tech/profiles/LWM2M-v1_1.xsd\">\n" +
|
||||
"<Object ObjectType=\"MODefinition\">\n" +
|
||||
"<Name>My first resource</Name>\n" +
|
||||
"<Description1></Description1>\n" +
|
||||
"<ObjectID>0</ObjectID>\n" +
|
||||
"<ObjectURN></ObjectURN>\n" +
|
||||
"<ObjectVersion>&ObjectVersion;</ObjectVersion>\n" +
|
||||
"<MultipleInstances>Multiple</MultipleInstances>\n" +
|
||||
"<Mandatory>Mandatory</Mandatory>\n" +
|
||||
"<Resources>\n" +
|
||||
"<Item ID=\"0\">\n" +
|
||||
"<Name>LWM2M</Name>\n" +
|
||||
"<Operations>RW</Operations>\n" +
|
||||
"<MultipleInstances>Single</MultipleInstances>\n" +
|
||||
"<Mandatory>Mandatory</Mandatory>\n" +
|
||||
"<Type>String</Type>\n" +
|
||||
"<RangeEnumeration>0..255</RangeEnumeration>\n" +
|
||||
"<Units></Units>\n" +
|
||||
"<Description></Description>\n" +
|
||||
"</Item>\n" +
|
||||
"</Resources>\n" +
|
||||
"<Description2></Description2>\n" +
|
||||
"</Object>\n" +
|
||||
"</LWM2M>";
|
||||
|
||||
private static final String DEFAULT_FILE_NAME = "test.jks";
|
||||
|
||||
private IdComparator<TbResourceInfo> idComparator = new IdComparator<>();
|
||||
@ -126,11 +154,11 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
|
||||
loginTenantAdmin();
|
||||
|
||||
Assert.assertEquals(0, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(0, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
|
||||
createResource("test", DEFAULT_FILE_NAME);
|
||||
|
||||
Assert.assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
|
||||
try {
|
||||
assertThatThrownBy(() -> createResource("test1", 1 + DEFAULT_FILE_NAME))
|
||||
@ -145,19 +173,19 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
|
||||
@Test
|
||||
public void sumDataSizeByTenantId() throws Exception {
|
||||
Assert.assertEquals(0, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(0, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
|
||||
createResource("test", DEFAULT_FILE_NAME);
|
||||
Assert.assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
|
||||
int maxSumDataSize = 8;
|
||||
|
||||
for (int i = 2; i <= maxSumDataSize; i++) {
|
||||
createResource("test" + i, i + DEFAULT_FILE_NAME);
|
||||
Assert.assertEquals(i, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(i, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
}
|
||||
|
||||
Assert.assertEquals(maxSumDataSize, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
assertEquals(maxSumDataSize, resourceService.sumDataSizeByTenantId(tenantId));
|
||||
}
|
||||
|
||||
private TbResource createResource(String title, String filename) throws Exception {
|
||||
@ -184,16 +212,16 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
Assert.assertNotNull(savedResource);
|
||||
Assert.assertNotNull(savedResource.getId());
|
||||
Assert.assertTrue(savedResource.getCreatedTime() > 0);
|
||||
Assert.assertEquals(resource.getTenantId(), savedResource.getTenantId());
|
||||
Assert.assertEquals(resource.getTitle(), savedResource.getTitle());
|
||||
Assert.assertEquals(resource.getResourceKey(), savedResource.getResourceKey());
|
||||
Assert.assertEquals(resource.getData(), savedResource.getData());
|
||||
assertEquals(resource.getTenantId(), savedResource.getTenantId());
|
||||
assertEquals(resource.getTitle(), savedResource.getTitle());
|
||||
assertEquals(resource.getResourceKey(), savedResource.getResourceKey());
|
||||
assertEquals(resource.getData(), savedResource.getData());
|
||||
|
||||
savedResource.setTitle("My new resource");
|
||||
|
||||
resourceService.save(savedResource);
|
||||
TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
|
||||
Assert.assertEquals(foundResource.getTitle(), savedResource.getTitle());
|
||||
assertEquals(foundResource.getTitle(), savedResource.getTitle());
|
||||
|
||||
resourceService.delete(savedResource, null);
|
||||
}
|
||||
@ -211,10 +239,10 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
Assert.assertNotNull(savedResource);
|
||||
Assert.assertNotNull(savedResource.getId());
|
||||
Assert.assertTrue(savedResource.getCreatedTime() > 0);
|
||||
Assert.assertEquals(resource.getTenantId(), savedResource.getTenantId());
|
||||
Assert.assertEquals("My first resource id=0 v1.0", savedResource.getTitle());
|
||||
Assert.assertEquals("0_1.0", savedResource.getResourceKey());
|
||||
Assert.assertEquals(resource.getData(), savedResource.getData());
|
||||
assertEquals(resource.getTenantId(), savedResource.getTenantId());
|
||||
assertEquals("My first resource id=0 v1.0", savedResource.getTitle());
|
||||
assertEquals("0_1.0", savedResource.getResourceKey());
|
||||
assertEquals(resource.getData(), savedResource.getData());
|
||||
|
||||
resourceService.delete(savedResource, null);
|
||||
}
|
||||
@ -228,7 +256,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
resource.setData("Test Data");
|
||||
TbResource savedResource = resourceService.save(resource);
|
||||
|
||||
Assert.assertEquals(TenantId.SYS_TENANT_ID, savedResource.getTenantId());
|
||||
assertEquals(TenantId.SYS_TENANT_ID, savedResource.getTenantId());
|
||||
|
||||
resourceService.delete(savedResource, null);
|
||||
}
|
||||
@ -285,6 +313,21 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveLwm2mTbResourceWithXXE() {
|
||||
TbResource resource = new TbResource();
|
||||
resource.setTenantId(tenantId);
|
||||
resource.setResourceType(ResourceType.LWM2M_MODEL);
|
||||
resource.setFileName("xxe_test_model.xml");
|
||||
resource.setData(Base64.getEncoder().encodeToString(LWM2M_TEST_MODEL_WITH_XXE.getBytes()));
|
||||
|
||||
DataValidationException thrown = assertThrows(DataValidationException.class, () -> {
|
||||
resourceService.save(resource);
|
||||
});
|
||||
assertEquals("Failed to parse file xxe_test_model.xml", thrown.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFindResourceById() throws Exception {
|
||||
TbResource resource = new TbResource();
|
||||
@ -296,7 +339,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
|
||||
TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId());
|
||||
Assert.assertNotNull(foundResource);
|
||||
Assert.assertEquals(savedResource, foundResource);
|
||||
assertEquals(savedResource, foundResource);
|
||||
resourceService.delete(savedResource, null);
|
||||
}
|
||||
|
||||
@ -312,7 +355,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
|
||||
TbResource foundResource = resourceService.getResource(tenantId, savedResource.getResourceType(), savedResource.getResourceKey());
|
||||
Assert.assertNotNull(foundResource);
|
||||
Assert.assertEquals(savedResource, foundResource);
|
||||
assertEquals(savedResource, foundResource);
|
||||
resourceService.delete(savedResource, null);
|
||||
}
|
||||
|
||||
@ -366,7 +409,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
Collections.sort(resources, idComparator);
|
||||
Collections.sort(loadedResources, idComparator);
|
||||
|
||||
Assert.assertEquals(resources, loadedResources);
|
||||
assertEquals(resources, loadedResources);
|
||||
|
||||
resourceService.deleteResourcesByTenantId(tenantId);
|
||||
|
||||
@ -427,14 +470,14 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest {
|
||||
Collections.sort(resources, idComparator);
|
||||
Collections.sort(loadedResources, idComparator);
|
||||
|
||||
Assert.assertEquals(resources, loadedResources);
|
||||
assertEquals(resources, loadedResources);
|
||||
|
||||
resourceService.deleteResourcesByTenantId(tenantId);
|
||||
|
||||
pageLink = new PageLink(100);
|
||||
pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink);
|
||||
Assert.assertFalse(pageData.hasNext());
|
||||
Assert.assertEquals(pageData.getData().size(), 100);
|
||||
assertEquals(pageData.getData().size(), 100);
|
||||
|
||||
resourceService.deleteResourcesByTenantId(TenantId.SYS_TENANT_ID);
|
||||
|
||||
|
||||
@ -116,6 +116,11 @@
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.leshan</groupId>
|
||||
<artifactId>leshan-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -0,0 +1,272 @@
|
||||
/**
|
||||
* Copyright © 2016-2023 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.common.data.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.LwM2m;
|
||||
import org.eclipse.leshan.core.model.DDFFileValidator;
|
||||
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
|
||||
import org.eclipse.leshan.core.model.InvalidDDFFileException;
|
||||
import org.eclipse.leshan.core.model.ObjectModel;
|
||||
import org.eclipse.leshan.core.model.ResourceModel;
|
||||
import org.eclipse.leshan.core.util.StringUtils;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class TbDDFFileParser {
|
||||
private static final DDFFileValidator ddfFileValidator = new DefaultDDFFileValidator();
|
||||
|
||||
public List<ObjectModel> parse(InputStream inputStream, String streamName)
|
||||
throws InvalidDDFFileException, IOException {
|
||||
streamName = streamName == null ? "" : streamName;
|
||||
|
||||
log.debug("Parsing DDF file {}", streamName);
|
||||
|
||||
try {
|
||||
// Parse XML file
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document document = builder.parse(inputStream);
|
||||
|
||||
// Get DDF file validator
|
||||
LwM2m.LwM2mVersion lwm2mVersion = null;
|
||||
ddfFileValidator.validate(document);
|
||||
|
||||
// Build list of ObjectModel
|
||||
ArrayList<ObjectModel> objects = new ArrayList<>();
|
||||
NodeList nodeList = document.getDocumentElement().getElementsByTagName("Object");
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
objects.add(parseObject(nodeList.item(i), streamName, lwm2mVersion, true));
|
||||
}
|
||||
return objects;
|
||||
} catch (InvalidDDFFileException | SAXException e) {
|
||||
throw new InvalidDDFFileException(e, "Invalid DDF file %s", streamName);
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
throw new IllegalStateException("Unable to create Document Builder", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectModel parseObject(Node object, String streamName, LwM2m.LwM2mVersion schemaVersion, boolean validate)
|
||||
throws InvalidDDFFileException {
|
||||
|
||||
Node objectType = object.getAttributes().getNamedItem("ObjectType");
|
||||
if (validate && (objectType == null || !"MODefinition".equals(objectType.getTextContent()))) {
|
||||
throw new InvalidDDFFileException(
|
||||
"Object element in %s MUST have a ObjectType attribute equals to 'MODefinition'.", streamName);
|
||||
}
|
||||
|
||||
Integer id = null;
|
||||
String name = null;
|
||||
String description = null;
|
||||
String version = ObjectModel.DEFAULT_VERSION;
|
||||
Boolean multiple = null;
|
||||
Boolean mandatory = null;
|
||||
Map<Integer, ResourceModel> resources = new HashMap<>();
|
||||
String urn = null;
|
||||
String description2 = null;
|
||||
String lwm2mVersion = ObjectModel.DEFAULT_VERSION;
|
||||
|
||||
for (int i = 0; i < object.getChildNodes().getLength(); i++) {
|
||||
Node field = object.getChildNodes().item(i);
|
||||
if (field.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
switch (field.getNodeName()) {
|
||||
case "ObjectID":
|
||||
id = Integer.valueOf(field.getTextContent());
|
||||
break;
|
||||
case "Name":
|
||||
name = field.getTextContent();
|
||||
break;
|
||||
case "Description1":
|
||||
description = field.getTextContent();
|
||||
break;
|
||||
case "ObjectVersion":
|
||||
if (!StringUtils.isEmpty(field.getTextContent())) {
|
||||
version = field.getTextContent();
|
||||
}
|
||||
break;
|
||||
case "MultipleInstances":
|
||||
if ("Multiple".equals(field.getTextContent())) {
|
||||
multiple = true;
|
||||
} else if ("Single".equals(field.getTextContent())) {
|
||||
multiple = false;
|
||||
}
|
||||
break;
|
||||
case "Mandatory":
|
||||
if ("Mandatory".equals(field.getTextContent())) {
|
||||
mandatory = true;
|
||||
} else if ("Optional".equals(field.getTextContent())) {
|
||||
mandatory = false;
|
||||
}
|
||||
break;
|
||||
case "Resources":
|
||||
for (int j = 0; j < field.getChildNodes().getLength(); j++) {
|
||||
Node item = field.getChildNodes().item(j);
|
||||
if (item.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (item.getNodeName().equals("Item")) {
|
||||
ResourceModel resource = parseResource(item, streamName);
|
||||
if (validate && resources.containsKey(resource.id)) {
|
||||
throw new InvalidDDFFileException(
|
||||
"Object %s in %s contains at least 2 resources with same id %s.",
|
||||
id != null ? id : "", streamName, resource.id);
|
||||
} else {
|
||||
resources.put(resource.id, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ObjectURN":
|
||||
urn = field.getTextContent();
|
||||
break;
|
||||
case "LWM2MVersion":
|
||||
if (!StringUtils.isEmpty(field.getTextContent())) {
|
||||
lwm2mVersion = field.getTextContent();
|
||||
if (schemaVersion != null && !schemaVersion.toString().equals(lwm2mVersion)) {
|
||||
throw new InvalidDDFFileException(
|
||||
"LWM2MVersion is not consistent with xml shema(xsi:noNamespaceSchemaLocation) in %s : %s expected but was %s.",
|
||||
streamName, schemaVersion, lwm2mVersion);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Description2":
|
||||
description2 = field.getTextContent();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new ObjectModel(id, name, description, version, multiple, mandatory, resources.values(), urn,
|
||||
lwm2mVersion, description2);
|
||||
|
||||
}
|
||||
|
||||
private ResourceModel parseResource(Node item, String streamName) throws DOMException, InvalidDDFFileException {
|
||||
|
||||
Integer id = Integer.valueOf(item.getAttributes().getNamedItem("ID").getTextContent());
|
||||
String name = null;
|
||||
ResourceModel.Operations operations = null;
|
||||
Boolean multiple = false;
|
||||
Boolean mandatory = false;
|
||||
ResourceModel.Type type = null;
|
||||
String rangeEnumeration = null;
|
||||
String units = null;
|
||||
String description = null;
|
||||
|
||||
for (int i = 0; i < item.getChildNodes().getLength(); i++) {
|
||||
Node field = item.getChildNodes().item(i);
|
||||
if (field.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
switch (field.getNodeName()) {
|
||||
case "Name":
|
||||
name = field.getTextContent();
|
||||
break;
|
||||
case "Operations":
|
||||
String strOp = field.getTextContent();
|
||||
if (strOp != null && !strOp.isEmpty()) {
|
||||
operations = ResourceModel.Operations.valueOf(strOp);
|
||||
} else {
|
||||
operations = ResourceModel.Operations.NONE;
|
||||
}
|
||||
break;
|
||||
case "MultipleInstances":
|
||||
if ("Multiple".equals(field.getTextContent())) {
|
||||
multiple = true;
|
||||
} else if ("Single".equals(field.getTextContent())) {
|
||||
multiple = false;
|
||||
}
|
||||
break;
|
||||
case "Mandatory":
|
||||
if ("Mandatory".equals(field.getTextContent())) {
|
||||
mandatory = true;
|
||||
} else if ("Optional".equals(field.getTextContent())) {
|
||||
mandatory = false;
|
||||
}
|
||||
break;
|
||||
case "Type":
|
||||
switch (field.getTextContent()) {
|
||||
case "String":
|
||||
type = ResourceModel.Type.STRING;
|
||||
break;
|
||||
case "Integer":
|
||||
type = ResourceModel.Type.INTEGER;
|
||||
break;
|
||||
case "Float":
|
||||
type = ResourceModel.Type.FLOAT;
|
||||
break;
|
||||
case "Boolean":
|
||||
type = ResourceModel.Type.BOOLEAN;
|
||||
break;
|
||||
case "Opaque":
|
||||
type = ResourceModel.Type.OPAQUE;
|
||||
break;
|
||||
case "Time":
|
||||
type = ResourceModel.Type.TIME;
|
||||
break;
|
||||
case "Objlnk":
|
||||
type = ResourceModel.Type.OBJLNK;
|
||||
break;
|
||||
case "Unsigned Integer":
|
||||
type = ResourceModel.Type.UNSIGNED_INTEGER;
|
||||
break;
|
||||
case "Corelnk":
|
||||
type = ResourceModel.Type.CORELINK;
|
||||
break;
|
||||
case "":
|
||||
type = ResourceModel.Type.NONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "RangeEnumeration":
|
||||
rangeEnumeration = field.getTextContent();
|
||||
break;
|
||||
case "Units":
|
||||
units = field.getTextContent();
|
||||
break;
|
||||
case "Description":
|
||||
description = field.getTextContent();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new ResourceModel(id, name, operations, multiple, mandatory, type, rangeEnumeration, units, description);
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@ import org.eclipse.leshan.core.model.ObjectModel;
|
||||
import org.eclipse.leshan.core.model.ResourceModel;
|
||||
import org.eclipse.leshan.core.node.codec.CodecException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.util.TbDDFFileParser;
|
||||
import org.thingsboard.server.common.transport.TransportServiceCallback;
|
||||
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
@ -142,9 +143,9 @@ public class LwM2mTransportServerHelper {
|
||||
.build();
|
||||
}
|
||||
|
||||
public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) {
|
||||
public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName) {
|
||||
try {
|
||||
DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator);
|
||||
TbDDFFileParser ddfFileParser = new TbDDFFileParser();
|
||||
return ddfFileParser.parse(new ByteArrayInputStream(xmlByte), streamName).get(0);
|
||||
} catch (IOException | InvalidDDFFileException e) {
|
||||
log.error("Could not parse the XML file [{}]", streamName, e);
|
||||
|
||||
@ -154,8 +154,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
|
||||
Optional<TbResource> tbResource = context.getTransportResourceCache().get(this.tenantId, LWM2M_MODEL, key);
|
||||
return tbResource.map(resource -> helper.parseFromXmlToObjectModel(
|
||||
Base64.getDecoder().decode(resource.getData()),
|
||||
key + ".xml",
|
||||
new DefaultDDFFileValidator())).orElse(null);
|
||||
key + ".xml")).orElse(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user