lwm2m: add Lwm2m provider for models

This commit is contained in:
nickAS21 2021-03-12 17:53:03 +02:00
parent d27c721bbf
commit 648e8ec262
13 changed files with 191 additions and 220 deletions

View File

@ -17,6 +17,10 @@ package org.thingsboard.server.service.install;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.DDFFileParser;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.InvalidDDFFileException;
import org.eclipse.leshan.core.model.ObjectModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@ -39,6 +43,8 @@ import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
@ -196,37 +202,70 @@ public class InstallScripts {
}
public void loadSystemLwm2mResources() throws Exception {
// Path modelsDir = Paths.get("/home/nick/Igor_project/thingsboard_ce_3_2_docker/thingsboard/common/transport/lwm2m/src/main/resources/models/");
Path modelsDir = Paths.get(getDataDir(), MODELS_DIR);
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(modelsDir, path -> path.toString().endsWith(XML_EXT))) {
dirStream.forEach(
path -> {
try {
Resource resource = new Resource();
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setResourceType(ResourceType.LWM2M_MODEL);
resource.setResourceId(path.getFileName().toString());
resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(path)));
resourceService.saveResource(resource);
} catch (Exception e) {
log.error("Unable to load lwm2m model [{}]", path.toString());
throw new RuntimeException("Unable to load lwm2m model", e);
if (Files.isDirectory(modelsDir)) {
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(modelsDir, path -> path.toString().endsWith(XML_EXT))) {
dirStream.forEach(
path -> {
try {
byte[] fileBytes = Files.readAllBytes(path);
String key = getObjectModelLwm2mValid(fileBytes, path.getFileName().toString(), new DefaultDDFFileValidator());
if (key != null) {
Resource resource = new Resource();
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setResourceType(ResourceType.LWM2M_MODEL);
resource.setResourceId(key);
resource.setValue(Base64.getEncoder().encodeToString(fileBytes));
resourceService.saveResource(resource);
}
} catch (Exception e) {
log.error("Unable to load lwm2m model [{}]", path.toString());
throw new RuntimeException("Unable to load lwm2m model", e);
}
}
}
);
);
}
}
Path jksPath = Paths.get(getDataDir(), CREDENTIALS_DIR, "serverKeyStore.jks");
try {
Resource resource = new Resource();
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setResourceType(ResourceType.JKS);
resource.setResourceId(jksPath.getFileName().toString());
resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath)));
resourceService.saveResource(resource);
} catch (Exception e) {
log.error("Unable to load lwm2m serverKeyStore [{}]", jksPath.toString());
throw new RuntimeException("Unable to load l2m2m serverKeyStore", e);
}
try {
Resource resource = new Resource();
resource.setTenantId(TenantId.SYS_TENANT_ID);
resource.setResourceType(ResourceType.JKS);
resource.setResourceId(jksPath.getFileName().toString());
resource.setValue(Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath)));
resourceService.saveResource(resource);
} catch (Exception e) {
log.error("Unable to load lwm2m serverKeyStore [{}]", jksPath.toString());
throw new RuntimeException("Unable to load l2m2m serverKeyStore", e);
}
}
private String getObjectModelLwm2mValid(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) {
try {
DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator);
ObjectModel objectModel = ddfFileParser.parseEx(new ByteArrayInputStream(xmlByte), streamName).get(0);
return objectModel.id + "##" + objectModel.getVersion();
} catch (IOException | InvalidDDFFileException e) {
log.error("Could not parse the XML file [{}]", streamName, e);
return null;
}
}
private void removeFile(Path modelsDir, String nameFile, byte[] fileBytes) {
String path = "/home/nick/Igor_project/thingsboard_ce_3_2_docker/thingsboard/common/transport/lwm2m/src/main/resources/models/";
File file = new File(path + nameFile);
if (!file.isDirectory()) {
try {
Files.write(Paths.get(path + "server/" + nameFile), fileBytes);
file.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void loadDashboards(TenantId tenantId, CustomerId customerId) throws Exception {

View File

@ -17,7 +17,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.core.model.StaticModel;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
@ -94,7 +93,7 @@ public class LwM2MTransportBootstrapServerConfiguration {
builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort));
/** Define model provider (Create Models )*/
builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValueCommon()));
// builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValueCommon()));
/** Create credentials */
this.setServerWithCredentials(builder);

View File

@ -16,13 +16,13 @@
package org.thingsboard.server.transport.lwm2m.server;
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* <p>
* 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
*
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* 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.
@ -34,9 +34,13 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.DDFFileParser;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.InvalidDDFFileException;
import org.eclipse.leshan.core.model.ObjectModel;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
import org.thingsboard.server.common.transport.TransportResourceCache;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
@ -48,7 +52,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCreden
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
import java.util.List;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
@ -62,14 +67,16 @@ public class LwM2mTransportContextServer extends TransportContext {
private final TransportService transportService;
private List<ObjectModel> modelsValueServer;
private final TransportResourceCache transportResourceCache;
@Getter
private final LwM2MJsonAdaptor adaptor;
public LwM2mTransportContextServer(LwM2MTransportConfigServer lwM2MTransportConfigServer, TransportService transportService, LwM2MJsonAdaptor adaptor) {
public LwM2mTransportContextServer(LwM2MTransportConfigServer lwM2MTransportConfigServer, TransportService transportService, TransportResourceCache transportResourceCache, LwM2MJsonAdaptor adaptor) {
this.lwM2MTransportConfigServer = lwM2MTransportConfigServer;
this.transportService = transportService;
this.transportResourceCache = transportResourceCache;
this.adaptor = adaptor;
}
@ -77,6 +84,10 @@ public class LwM2mTransportContextServer extends TransportContext {
return this.lwM2MTransportConfigServer;
}
public TransportResourceCache getTransportResourceCache() {
return this.transportResourceCache;
}
/**
* Sent to Thingsboard Attribute || Telemetry
*
@ -139,59 +150,13 @@ public class LwM2mTransportContextServer extends TransportContext {
.build();
}
// /**
// * ResourcesRequestMsg
// *
// * @param resourceType
// * @return
// */
// public GetResourcesResponseMsg getResourceTenant (UUID tenantId, String resourceType) {
// CountDownLatch latch = new CountDownLatch(1);
// GetResourcesResponseMsg responseMsg =
// this.getTransportService()
// .getResources(GetResourcesRequestMsg.newBuilder()
// .setResourceType(resourceType)
// .setTenantIdLSB(tenantId.getLeastSignificantBits())
// .setTenantIdMSB(tenantId.getMostSignificantBits())
// .build());
// latch.countDown();
// try {
// latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
// } catch (InterruptedException e) {
// log.error("Failed to await credentials!", e);
// }
//
// return responseMsg;
// }
// public GetResourcesResponseMsg getResourceTenantProcess (UUID tenantId, String resourceType) {
// CountDownLatch latch = new CountDownLatch(2);
// final GetResourcesResponseMsg[] responseMsg = {null};
// this.getTransportService().process(GetResourcesRequestMsg.newBuilder()
// .setResourceType(resourceType)
// .setTenantIdLSB(tenantId.getLeastSignificantBits())
// .setTenantIdMSB(tenantId.getMostSignificantBits())
// .build(),
// new TransportServiceCallback<>() {
// @Override
// public void onSuccess(GetResourcesResponseMsg msg) { responseMsg[0] = msg;
// latch.countDown();
// }
//
// @Override
// public void onError(Throwable e) {
// log.trace("[{}] [{}] Failed to process credentials ", tenantId, e);
// latch.countDown();
// }
// });
// try {
// latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
// } catch (InterruptedException e) {
// log.error("Failed to await credentials!", e);
// }
// return responseMsg[0];
// }
public ObjectModel parseFromXmlToObjectModel(byte[] xmlByte, String streamName, DefaultDDFFileValidator ddfValidator) {
try {
DDFFileParser ddfFileParser = new DDFFileParser(ddfValidator);
return ddfFileParser.parseEx(new ByteArrayInputStream(xmlByte), streamName).get(0);
} catch (IOException | InvalidDDFFileException e) {
log.error("Could not parse the XML file [{}]", streamName, e);
return null;
}
}
}

View File

@ -35,6 +35,7 @@ import org.eclipse.leshan.server.californium.LeshanServerBuilder;
import org.nustaq.serialization.FSTConfiguration;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
@ -45,7 +46,6 @@ import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.Optional;
import java.util.UUID;
@Slf4j
//@Component("LwM2MTransportHandler")
@ -189,7 +189,7 @@ public class LwM2mTransportHandler {
return null;
}
public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, UUID tenantId) {
public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) {
LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile();
lwM2MClientProfile.setTenantId(tenantId);
lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject());
@ -223,7 +223,7 @@ public class LwM2mTransportHandler {
ObjectMapper mapper = new ObjectMapper();
String profileStr = mapper.writeValueAsString(profile);
JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson, deviceProfile.getTenantId().getId()) : null;
return (getValidateCredentialsBodyFromThingsboard(profileJson)) ? LwM2mTransportHandler.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null;
} catch (IOException e) {
log.error("", e);
}

View File

@ -87,9 +87,6 @@ public class LwM2mTransportRequest {
private final LeshanServer leshanServer;
// @Autowired
// private LwM2mTransportServiceImpl serviceImpl;
private final LwM2mTransportServiceImpl serviceImpl;
public LwM2mTransportRequest(LwM2mTransportContextServer context, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, LwM2mTransportServiceImpl serviceImpl) {
@ -232,6 +229,7 @@ public class LwM2mTransportRequest {
private void sendRequest(Registration registration, DownlinkRequest request, long timeoutInMs) {
LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
if (!lwM2MClient.isInit()) {
lwM2MClient.initValue(this.serviceImpl, request.getPath().toString());
}

View File

@ -27,7 +27,6 @@ import org.eclipse.leshan.server.model.LwM2mModelProvider;
import org.eclipse.leshan.server.security.DefaultAuthorizer;
import org.eclipse.leshan.server.security.EditableSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
@ -61,24 +60,23 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_W
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig;
@Slf4j
@Component("LwM2MTransportServerConfiguration")
@Component
@TbLwM2mTransportComponent
public class LwM2mTransportServerConfiguration {
private PublicKey publicKey;
private PrivateKey privateKey;
private boolean pskMode = false;
private final LwM2mTransportContextServer context;
private final CaliforniumRegistrationStore registrationStore;
private final EditableSecurityStore securityStore;
private final LwM2mClientContext lwM2mClientContext;
@Autowired
private LwM2mTransportContextServer context;
@Autowired
private CaliforniumRegistrationStore registrationStore;
@Autowired
private EditableSecurityStore securityStore;
@Autowired
private LwM2mClientContext lwM2mClientContext;;
public LwM2mTransportServerConfiguration(LwM2mTransportContextServer context, CaliforniumRegistrationStore registrationStore, EditableSecurityStore securityStore, LwM2mClientContext lwM2mClientContext) {
this.context = context;
this.registrationStore = registrationStore;
this.securityStore = securityStore;
this.lwM2mClientContext = lwM2mClientContext;
}
@Bean
public LeshanServer getLeshanServer() {
@ -98,10 +96,8 @@ public class LwM2mTransportServerConfiguration {
builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort));
/** Define model provider (Create Models )*/
// TransportProtos.GetResourcesResponseMsg responseMsg= this.context.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.context.getResourceTenant(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValueCommon());
LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValueServer(), this.lwM2mClientContext);
LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.lwM2mClientContext, this.context);
this.context.getLwM2MTransportConfigServer().setModelProvider(modelProvider);
builder.setObjectModelProvider(modelProvider);
/** Create credentials */

View File

@ -153,11 +153,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
executorRegistered.submit(() -> {
try {
log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
((LwM2mVersionedModelProvider)leshanServer.getModelProvider()).setRepository(this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelsValueCommon());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.lwM2mTransportContextServer.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.lwM2mTransportContextServer.getResourceTenant(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// (((VersionedModelProvider) (leshanServer)).modelProvider).repository;
LwM2mClient lwM2MClient = this.lwM2mClientContext.updateInSessionsLwM2MClient(registration);
if (lwM2MClient != null) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
@ -657,21 +652,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
return (clientInstances.size() > 0) ? clientInstances : null;
}
// /**
// * get AttrName/TelemetryName with value from Client
// *
// * @param registration -
// * @return - JsonObject, format: {name: value}}
// */
// private JsonObject getAttributeClient(Registration registration) {
// if (registration.getAdditionalRegistrationAttributes().size() > 0) {
// JsonObject resNameValues = new JsonObject();
// registration.getAdditionalRegistrationAttributes().forEach(resNameValues::addProperty);
// return resNameValues;
// }
// return null;
// }
/**
* @param attributes - new JsonObject
* @param telemetry - new JsonObject

View File

@ -15,100 +15,122 @@
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.LwM2mModel;
import org.eclipse.leshan.core.model.LwM2mModelRepository;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.server.model.LwM2mModelProvider;
import org.eclipse.leshan.server.registration.Registration;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
import static org.thingsboard.server.common.data.ResourceType.LWM2M_MODEL;
private LwM2mModelRepository repository;
private Map<String, LwM2mModelRepository> repositoriesTenant;
private LwM2mClientContext lwM2mClientContext;
@Slf4j
public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
public LwM2mVersionedModelProvider(Collection<ObjectModel> objectModels, LwM2mClientContext lwM2mClientContext) {
this.repository = new LwM2mModelRepository(objectModels);
/**
* int objectId
* String version ("1.01")
* Key = objectId + "##" + version
* Value = TenantId
*/
private final LwM2mClientContext lwM2mClientContext;
private final LwM2mTransportContextServer lwM2mTransportContextServer;
public LwM2mVersionedModelProvider(LwM2mClientContext lwM2mClientContext, LwM2mTransportContextServer lwM2mTransportContextServer) {
this.lwM2mClientContext = lwM2mClientContext;
this.repositoriesTenant = new ConcurrentHashMap<>();
this.lwM2mTransportContextServer = lwM2mTransportContextServer;
}
private String getIdVer(ObjectModel objectModel) {
return objectModel.id + "##" + ((objectModel.getVersion() == null || objectModel.getVersion().isEmpty()) ? ObjectModel.DEFAULT_VERSION : objectModel.getVersion());
}
public LwM2mVersionedModelProvider(LwM2mModelRepository repository, LwM2mClientContext lwM2mClientContext) {
this.repository = repository;
this.lwM2mClientContext = lwM2mClientContext;
this.repositoriesTenant = new ConcurrentHashMap<>();
}
public void setRepositoriesTenant (String tenantID, LwM2mModelRepository repositoryTenant) {
this.repositoriesTenant.put(tenantID, repositoryTenant);
}
public LwM2mModelRepository getRepositoriesTenant (String tenantID) {
return this.repositoriesTenant.get(tenantID);
}
public void setRepository (Collection<ObjectModel> objectModels) {
this.repository = new LwM2mModelRepository(objectModels);
}
public LwM2mModelRepository getRepositoriesCommonTenant (String tenantID) {
LwM2mModelRepository repository = new LwM2mModelRepository();
return repository;
private String getIdVer(Integer objectId, String version) {
return objectId != null ? objectId + "##" + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
}
/**
* Update repository if need
*
* @param registration
* @return
*/
@Override
public LwM2mModel getObjectModel(Registration registration) {
return new DynamicModel(registration, this.lwM2mClientContext.getProfile(registration).getTenantId());
return new DynamicModel(registration
);
}
private class DynamicModel implements LwM2mModel {
private final Registration registration;
private final UUID tenantId;
private final TenantId tenantId;
public DynamicModel(Registration registration, UUID tenantId) {
public DynamicModel(Registration registration) {
this.registration = registration;
this.tenantId = tenantId;
this.tenantId = lwM2mClientContext.getProfile(registration).getTenantId();
}
@Override
public ResourceModel getResourceModel(int objectId, int resourceId) {
ObjectModel objectModel = getObjectModel(objectId);
if (objectModel != null)
return objectModel.resources.get(resourceId);
else
try {
ObjectModel objectModel = getObjectModel(objectId);
if (objectModel != null)
return objectModel.resources.get(resourceId);
else
return null;
} catch (Exception e) {
log.error("", e);
return null;
}
}
@Override
public ObjectModel getObjectModel(int objectId) {
String version = registration.getSupportedVersion(objectId);
if (version != null) {
return repository.getObjectModel(objectId, version);
return this.getObjectModelDynamic(objectId, version);
}
return null;
}
@Override
public Collection<ObjectModel> getObjectModels() {
Map<Integer, String> supportedObjects = registration.getSupportedObject();
Collection<ObjectModel> result = new ArrayList<>(supportedObjects.size());
for (Map.Entry<Integer, String> supportedObject : supportedObjects.entrySet()) {
ObjectModel objectModel = repository.getObjectModel(supportedObject.getKey(),
supportedObject.getValue());
if (objectModel != null)
Map<Integer, String> supportedObjects = this.registration.getSupportedObject();
Collection<ObjectModel> result = new ArrayList(supportedObjects.size());
Iterator i$ = supportedObjects.entrySet().iterator();
while (i$.hasNext()) {
Map.Entry<Integer, String> supportedObject = (Map.Entry) i$.next();
ObjectModel objectModel = this.getObjectModelDynamic((Integer) supportedObject.getKey(), (String) supportedObject.getValue());
if (objectModel != null) {
result.add(objectModel);
}
}
return result;
}
private ObjectModel getObjectModelDynamic(Integer objectId, String version) {
String key = getIdVer(objectId, version);
String xmlB64 = lwM2mTransportContextServer.getTransportResourceCache().get(
this.tenantId,
LWM2M_MODEL,
key).
getValue();
return xmlB64 != null && !xmlB64.isEmpty() ?
lwM2mTransportContextServer.parseFromXmlToObjectModel(
Base64.getDecoder().decode(xmlB64),
key + ".xml",
new DefaultDDFFileValidator()) :
null;
}
}
}

View File

@ -168,5 +168,4 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
}
return false;
}
}

View File

@ -19,13 +19,12 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import lombok.Data;
import java.util.UUID;
import org.thingsboard.server.common.data.id.TenantId;
@Data
public class LwM2mClientProfile {
private UUID tenantId;
private TenantId tenantId;
/**
* {"clientLwM2mSettings": {
* clientUpdateValueAfterConnect: false;

View File

@ -31,6 +31,8 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
@Slf4j
public class LwM2mValueConverterImpl implements LwM2mValueConverter {
@ -52,6 +54,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
/** expected type */
return value;
}
if (currentType == null) {
currentType = OPAQUE;
}
switch (expectedType) {
case INTEGER:

View File

@ -18,10 +18,10 @@ package org.thingsboard.server.common.transport.lwm2m;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.ObjectLoader;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.server.model.LwM2mModelProvider;
import org.eclipse.leshan.server.registration.Registration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ -38,9 +38,7 @@ import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Component
@ -87,7 +85,7 @@ public class LwM2MTransportConfigServer {
@Getter
@Setter
private List<ObjectModel> modelsValueServer;
private LwM2mModelProvider modelProvider;
@Getter
@Value("${transport.lwm2m.timeout:}")
@ -189,35 +187,11 @@ public class LwM2MTransportConfigServer {
@Value("${transport.lwm2m.server.secure.alias:}")
private String serverAlias;
@PostConstruct
public void init() {
modelsValueServer = ObjectLoader.loadDefault();
modelsValueServer.remove(3);
modelsValueCommon = ObjectLoader.loadDefault();
File path = getPathModels();
if (path.isDirectory()) {
try {
modelsValueCommon.addAll(ObjectLoader.loadObjectsFromDir(path));
log.info(" [{}] Models directory is a directory", path.getAbsoluteFile());
} catch (Exception e) {
log.error(" [{}] Could not parse the resource definition file", e.toString());
}
} else {
log.error(" [{}] Read Models", path.getAbsoluteFile());
}
this.getInKeyStore();
}
private File getPathModels() {
Path pathModels = (modelPathFile != null && !modelPathFile.isEmpty()) ? Paths.get(modelPathFile) :
(new File(Paths.get(getBaseDirPath(), PATH_DATA, MODEL_PATH_DEFAULT).toUri()).isDirectory()) ?
Paths.get(getBaseDirPath(), PATH_DATA, MODEL_PATH_DEFAULT) :
Paths.get(getBaseDirPath(), APP_DIR, TRANSPORT_DIR, LWM2M_DIR, SRC_DIR, MAIN_DIR, RESOURCES_DIR, MODEL_PATH_DEFAULT);
return (pathModels != null) ? new File(pathModels.toUri()) : null;
}
private KeyStore getInKeyStore() {
try {
if (keyStoreValue != null && keyStoreValue.size() > 0)
@ -260,12 +234,7 @@ public class LwM2MTransportConfigServer {
}
public ResourceModel getResourceModel(Registration registration, LwM2mPath pathIds) {
String pathLink = "/" + pathIds.getObjectId() + "/" + pathIds.getObjectInstanceId();
return (Arrays.stream(registration.getObjectLinks()).filter(p-> p.getUrl().equals(pathLink)).findFirst().isPresent() &&
this.modelsValueCommon.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).size() > 0) &&
this.modelsValueCommon.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.containsKey(pathIds.getResourceId()) ?
this.modelsValueCommon.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.get(pathIds.getResourceId()) :
null;
return this.modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId());
}
public ResourceModel.Type getResourceModelType(Registration registration, LwM2mPath pathIds) {

View File

@ -66,9 +66,9 @@
<jackson-core.version>2.12.1</jackson-core.version>
<json-schema-validator.version>2.2.6</json-schema-validator.version>
<californium.version>2.6.1</californium.version>
<leshan-server.version>1.3.0</leshan-server.version>
<leshan-core.version>1.3.0</leshan-core.version>
<leshan-client.version>1.3.0</leshan-client.version>
<leshan-server.version>1.3.1</leshan-server.version>
<leshan-core.version>1.3.1</leshan-core.version>
<leshan-client.version>1.3.1</leshan-client.version>
<gson.version>2.6.2</gson.version>
<freemarker.version>2.3.30</freemarker.version>
<mail.version>1.6.2</mail.version>