Lwm2m: backEnd: model Client from provide

This commit is contained in:
nickAS21 2020-12-30 15:55:57 +02:00
parent e91cb65399
commit 3a7101a8a3
8 changed files with 135 additions and 154 deletions

View File

@ -65,15 +65,10 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- lechan start -->
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-cf</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.leshan</groupId>-->
<!-- <artifactId>leshan-server-cf</artifactId>-->
<!-- </dependency> -->
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-client-cf</artifactId>
@ -83,12 +78,6 @@
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-redis</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.californium</groupId>-->
<!-- <artifactId>californium-core</artifactId>-->
<!-- </dependency>-->
<!-- leshan finish -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@ -107,14 +96,12 @@
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>

View File

@ -124,7 +124,7 @@ public class LwM2MTransportRequest {
if (registration != null && resultIds.getObjectId() >= 0) {
DownlinkRequest request = null;
ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null;
ResourceModel resource = service.context.getCtxServer().getResourceModel(resultIds);
ResourceModel resource = service.context.getCtxServer().getResourceModel(registration, resultIds);
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
switch (typeOper) {
case GET_TYPE_OPER_READ:
@ -222,7 +222,7 @@ public class LwM2MTransportRequest {
this.sendRequest(lwServer, registration, request, lwM2MClient, timeoutInMs, isDelayedUpdate);
} else if (request == null && isDelayedUpdate) {
String msg = String.format(LOG_LW2M_ERROR + ": sendRequest: Resource path - %s msg No SendRequest to Client", target);
service.sentLogsToThingsboard(msg, registration.getId());
service.sentLogsToThingsboard(msg, registration);
log.error("[{}] - [{}] No SendRequest", target);
this.handleResponseError(registration, target, lwM2MClient, isDelayedUpdate);
@ -251,14 +251,14 @@ public class LwM2MTransportRequest {
String msg = String.format(LOG_LW2M_INFO + ": sendRequest Replace%s: CoapCde - %s Lwm2m code - %d name - %s Resource path - %s value - %s SendRequest to Client",
delayedUpdateStr, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString(),
((LwM2mSingleResource) ((WriteRequest) request).getNode()).getValue().toString());
service.sentLogsToThingsboard(msg, registration.getId());
service.sentLogsToThingsboard(msg, registration);
log.info("[{}] - [{}] [{}] [{}] Update SendRequest[{}]", ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString(),
((LwM2mSingleResource) ((WriteRequest) request).getNode()).getValue(), delayedUpdateStr);
}
} else {
String msg = String.format(LOG_LW2M_ERROR + ": sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client",
((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString());
service.sentLogsToThingsboard(msg, registration.getId());
service.sentLogsToThingsboard(msg, registration);
log.error("[{}] - [{}] [{}] error SendRequest", ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString());
if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest() && isDelayedUpdate) {
this.handleResponseError(registration, request.getPath().toString(), lwM2MClient, isDelayedUpdate);
@ -268,7 +268,7 @@ public class LwM2MTransportRequest {
}, e -> {
String msg = String.format(LOG_LW2M_ERROR + ": sendRequest: Resource path - %s msg error - %s SendRequest to Client",
request.getPath().toString(), e.toString());
service.sentLogsToThingsboard(msg, registration.getId());
service.sentLogsToThingsboard(msg, registration);
log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString());
if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest() && isDelayedUpdate) {
this.handleResponseError(registration, request.getPath().toString(), lwM2MClient, isDelayedUpdate);
@ -300,7 +300,7 @@ public class LwM2MTransportRequest {
String patn = "/" + objectId + "/" + instanceId + "/" + resourceId;
String msg = String.format(LOG_LW2M_ERROR + ": NumberFormatException: Resource path - %s type - %s value - %s msg error - %s SendRequest to Client",
patn, type, value, e.toString());
service.sentLogsToThingsboard(msg, registration.getId());
service.sentLogsToThingsboard(msg, registration);
log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString());
return null;
}

View File

@ -20,13 +20,11 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.LwM2mMultipleResource;
import org.eclipse.leshan.core.node.LwM2mObject;
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.node.LwM2mResource;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.request.ContentFormat;
@ -51,7 +49,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCre
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.transport.lwm2m.server.client.AttrTelemetryObserveValue;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;
import org.thingsboard.server.transport.lwm2m.server.client.ModelObject;
import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue;
import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters;
import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore;
@ -62,9 +59,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
@ -76,7 +73,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.transport.util.JsonUtils.getJsonObject;
@ -148,13 +144,14 @@ public class LwM2MTransportService {
public void onRegistered(LeshanServer lwServer, Registration registration, Collection<Observation> previousObsersations) {
executorRegistered.submit(() -> {
try {
log.info("[{}] Client: onRegistered name ", registration.getEndpoint());
log.info("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.updateInSessionsLwM2MClient(lwServer, registration);
if (lwM2MClient != null) {
lwM2MClient.setLwM2MTransportService(this);
lwM2MClient.setSessionUuid(UUID.randomUUID());
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client Registered", registration);
this.setLwM2MClient(lwServer, registration, lwM2MClient);
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
if (sessionInfo != null) {
lwM2MClient.setDeviceUuid(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
lwM2MClient.setProfileUuid(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
@ -163,7 +160,7 @@ public class LwM2MTransportService {
transportService.registerAsyncSession(sessionInfo, new LwM2MSessionMsgListener(this, sessionInfo));
transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null);
transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null);
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client registration", registration.getId());
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration);
} else {
log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null);
}
@ -184,7 +181,7 @@ public class LwM2MTransportService {
public void updatedReg(LeshanServer lwServer, Registration registration) {
executorUpdateRegistered.submit(() -> {
try {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
if (sessionInfo != null) {
this.checkInactivity(sessionInfo);
log.info("Client: [{}] updatedReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());
@ -206,7 +203,7 @@ public class LwM2MTransportService {
public void unReg(Registration registration, Collection<Observation> observations) {
executorUnRegistered.submit(() -> {
try {
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId());
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration);
this.closeClientSession(registration);
} catch (Throwable t) {
log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t);
@ -215,7 +212,7 @@ public class LwM2MTransportService {
}
private void closeClientSession(Registration registration) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
if (sessionInfo != null) {
transportService.deregisterSession(sessionInfo);
this.doCloseSession(sessionInfo);
@ -278,9 +275,6 @@ public class LwM2MTransportService {
* @param lwM2MClient - object with All parameters off client
*/
private void setLwM2MClient(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient) {
// #0
this.setNewObjectModels(lwServer, registration);
// #1
Arrays.stream(registration.getObjectLinks()).forEach(url -> {
LwM2mPath pathIds = new LwM2mPath(url.getUrl());
if (pathIds.isObjectInstance() && !pathIds.isResource()) {
@ -297,30 +291,35 @@ public class LwM2MTransportService {
});
}
private void setNewObjectModels(LeshanServer lwServer, Registration registration) {
Arrays.stream(registration.getObjectLinks()).forEach(url -> {
LwM2mPath pathIds = new LwM2mPath(url.getUrl());
if (pathIds.isObjectInstance() && !pathIds.isResource() && !context.getCtxServer().getObjectModels().containsKey(pathIds.getObjectId())) {
ObjectModel model = lwServer.getModelProvider().getObjectModel(registration).getObjectModels().stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0);
context.getCtxServer().getObjectModels().put(pathIds.getObjectId(), model);
}
});
/**
* @param registration - Registration LwM2M Client
* @return - sessionInfo after access connect client
*/
private SessionInfoProto getValidateSessionInfo(Registration registration) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null);
return getNewSessionInfoProto(lwM2MClient);
}
/**
* @param registrationId - Id of Registration LwM2M Client
* @return - sessionInfo after access connect client
*
* @param registrationId -
* @return -
*/
private SessionInfoProto getValidateSessionInfo(String registrationId) {
SessionInfoProto sessionInfo = null;
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registrationId);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(null, registrationId);
return getNewSessionInfoProto(lwM2MClient);
}
private SessionInfoProto getNewSessionInfoProto(LwM2MClient lwM2MClient) {
if (lwM2MClient != null) {
ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse();
if (msg == null || msg.getDeviceInfo() == null) {
log.error("[{}] [{}]", lwM2MClient.getEndPoint(), CLIENT_NOT_AUTHORIZED);
this.closeClientSession(lwM2MClient.getRegistration());
return null;
} else {
sessionInfo = SessionInfoProto.newBuilder()
return SessionInfoProto.newBuilder()
.setNodeId(this.context.getNodeId())
.setSessionIdMSB(lwM2MClient.getSessionUuid().getMostSignificantBits())
.setSessionIdLSB(lwM2MClient.getSessionUuid().getLeastSignificantBits())
@ -335,7 +334,7 @@ public class LwM2MTransportService {
.build();
}
}
return sessionInfo;
return null;
}
/**
@ -365,7 +364,7 @@ public class LwM2MTransportService {
* @param lwM2MClient - LwM2M Client
*/
public void putDelayedUpdateResourcesThingsboard(LwM2MClient lwM2MClient) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration().getId());
SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration());
if (sessionInfo != null) {
//#1.1 + #1.2
List<String> attrSharedNames = this.getNamesAttrFromProfileIsWritable(lwM2MClient);
@ -404,7 +403,7 @@ public class LwM2MTransportService {
attributesResponse.getSharedAttributeListList().forEach(attr -> {
String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey());
// #1.1
if (lwM2MClient.getDelayedRequests().keySet().contains(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) {
if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) {
lwM2MClient.getDelayedRequests().put(path, attr);
} else {
lwM2MClient.getDelayedRequests().put(path, attr);
@ -412,7 +411,7 @@ public class LwM2MTransportService {
});
// #2.1
lwM2MClient.getDelayedRequests().forEach((k, v) -> {
List listV = new ArrayList<TransportProtos.KeyValueProto>();
ArrayList<TransportProtos.KeyValueProto> listV = new ArrayList<>();
listV.add(v.getKv());
this.putDelayedUpdateResourcesClient(lwM2MClient, this.getResourceValueToString(lwM2MClient, k), getJsonObject(listV).get(v.getKv().getKey()), k);
});
@ -432,24 +431,24 @@ public class LwM2MTransportService {
}
/**
* Get names and keyNames from profile attr resources IsWritable
*
* Get names and keyNames from profile shared!!!! attr resources IsWritable
* @param lwM2MClient -
* @return ArrayList names and keyNames from profile attr resources IsWritable
* @return ArrayList keyNames from profile attr resources shared!!!! && IsWritable
*/
private List<String> getNamesAttrFromProfileIsWritable(LwM2MClient lwM2MClient) {
Set<String> namesIsIsWritable = ConcurrentHashMap.newKeySet();
AttrTelemetryObserveValue profile = lwM2mInMemorySecurityStore.getProfile(lwM2MClient.getProfileUuid());
Set attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), Set.class);
ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), ConcurrentHashMap.class);
ConcurrentMap<String, String> keyNamesIsWritable = keyNamesMap.entrySet()
.stream()
.filter(e -> (attrSet.contains(e.getKey()) && context.getCtxServer().getResourceModel(new LwM2mPath(e.getKey())) != null &&
context.getCtxServer().getResourceModel(new LwM2mPath(e.getKey())).operations.isWritable()))
.filter(e -> (attrSet.contains(e.getKey()) && context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())) != null &&
context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(e.getKey())).operations.isWritable()))
.collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
namesIsIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values()));
keyNamesIsWritable.keySet().forEach(p -> namesIsIsWritable.add(this.getResourceName(p)));
return new ArrayList<>(namesIsIsWritable);
Set<String> namesIsWritable = ConcurrentHashMap.newKeySet();
namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values()));
return new ArrayList<>(namesIsWritable);
}
@ -484,9 +483,9 @@ public class LwM2MTransportService {
log.error("[{}] updateAttrTelemetry", e.toString());
}
if (attributes.getAsJsonObject().entrySet().size() > 0)
this.updateParametersOnThingsboard(attributes, DEVICE_ATTRIBUTES_TOPIC, registration.getId());
this.updateParametersOnThingsboard(attributes, DEVICE_ATTRIBUTES_TOPIC, registration);
if (telemetries.getAsJsonObject().entrySet().size() > 0)
this.updateParametersOnThingsboard(telemetries, DEVICE_TELEMETRY_TOPIC, registration.getId());
this.updateParametersOnThingsboard(telemetries, DEVICE_TELEMETRY_TOPIC, registration);
}
/**
@ -541,9 +540,8 @@ public class LwM2MTransportService {
JsonObject names = lwM2mInMemorySecurityStore.getProfiles().get(lwM2MClient.getProfileUuid()).getPostKeyNameProfile();
String resName = String.valueOf(names.get(path));
if (resName != null && !resName.isEmpty()) {
String resValue = null;
try {
resValue = this.getResourceValueToString(lwM2MClient, path);
String resValue = this.getResourceValueToString(lwM2MClient, path);
if (resValue != null) {
parameters.addProperty(resName, resValue);
}
@ -558,14 +556,14 @@ public class LwM2MTransportService {
*
* @param msg - JsonArray: [{name: value}]
* @param topicName - Api Attribute or Telemetry
* @param registrationId - Id of Registration LwM2M Client
* @param registration - Id of Registration LwM2M Client
*/
public void updateParametersOnThingsboard(JsonElement msg, String topicName, String registrationId) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registrationId);
public void updateParametersOnThingsboard(JsonElement msg, String topicName, Registration registration) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration);
if (sessionInfo != null) {
context.sentParametersOnThingsboard(msg, topicName, sessionInfo);
} else {
log.error("Client: [{}] updateParametersOnThingsboard [{}] sessionInfo ", registrationId, null);
log.error("Client: [{}] updateParametersOnThingsboard [{}] sessionInfo ", registration, null);
}
}
@ -655,10 +653,9 @@ public class LwM2MTransportService {
public void onObservationResponse(Registration registration, String path, ReadResponse response) {
if (response.getContent() != null) {
if (response.getContent() instanceof LwM2mObject) {
LwM2mObject content = (LwM2mObject) response.getContent();
String target = "/" + content.getId();
// LwM2mObject content = (LwM2mObject) response.getContent();
} else if (response.getContent() instanceof LwM2mObjectInstance) {
LwM2mObjectInstance content = (LwM2mObjectInstance) response.getContent();
// LwM2mObjectInstance content = (LwM2mObjectInstance) response.getContent();
} else if (response.getContent() instanceof LwM2mSingleResource) {
LwM2mSingleResource content = (LwM2mSingleResource) response.getContent();
this.onObservationSetResourcesValue(registration, content.getValue(), null, path);
@ -684,10 +681,10 @@ public class LwM2MTransportService {
boolean isChange = false;
try {
// #1
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registration.getId());
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null);
LwM2mPath pathIds = new LwM2mPath(path);
log.warn("#0 nameDevice: [{}] resultIds: [{}] value: [{}], values: [{}] ", lwM2MClient.getDeviceName(), pathIds, value, values);
ResourceModel.Type resModelType = context.getCtxServer().getResourceModelType(pathIds);
ResourceModel.Type resModelType = context.getCtxServer().getResourceModelType(registration, pathIds);
ResourceValue resValueOld = lwM2MClient.getResources().get(path);
// #2
if (resValueOld.isMultiInstances() && !values.toString().equals(resValueOld.getResourceValue().toString())) {
@ -739,8 +736,8 @@ public class LwM2MTransportService {
String value = de.getValue().getAsString();
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
AttrTelemetryObserveValue profile = lwM2mInMemorySecurityStore.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
ResourceModel resourceModel = context.getCtxServer().getResourceModel(new LwM2mPath(path));
if (path != null && (this.validatePathInAttrProfile(profile, path) || this.validatePathInTelemetryProfile(profile, path))) {
ResourceModel resourceModel = context.getCtxServer().getResourceModel(lwM2MClient.getRegistration(), new LwM2mPath(path));
if (!path.isEmpty() && (this.validatePathInAttrProfile(profile, path) || this.validatePathInTelemetryProfile(profile, path))) {
if (resourceModel != null && resourceModel.operations.isWritable()) {
lwM2MTransportRequest.sendAllRequest(lwM2MClient.getLwServer(), lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,
ContentFormat.TLV.getName(), lwM2MClient, null, value, this.context.getCtxServer().getTimeout(),
@ -748,12 +745,12 @@ public class LwM2MTransportService {
} else {
log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value);
String logMsg = String.format(LOG_LW2M_ERROR + ": attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", path, value);
this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId());
this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration());
}
} else {
log.error("Attribute name - [{}] value - [{}] is not present as attribute in profile and cannot be updated", de.getKey(), value);
String logMsg = String.format(LOG_LW2M_ERROR + ": attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", de.getKey(), value);
this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId());
this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration());
}
});
} else if (msg.getSharedDeletedCount() > 0) {
@ -767,11 +764,12 @@ public class LwM2MTransportService {
*
* @param sessionInfo -
* @param name -
* @return true if path isPresent in postProfile
* @return path if path isPresent in postProfile
*/
private String getPathAttributeUpdate(TransportProtos.SessionInfoProto sessionInfo, String name) {
String profilePath = this.getPathAttributeUpdateProfile(sessionInfo, name);
return !profilePath.isEmpty() ? profilePath : this.getPathAttributeUpdateModelObject(sessionInfo, name);
// return !profilePath.isEmpty() ? profilePath : this.getPathAttributeUpdateModelObject(name);
return !profilePath.isEmpty() ? profilePath : null;
}
/**
@ -800,7 +798,7 @@ public class LwM2MTransportService {
*
* @param sessionInfo -
* @param name -
* @return
* @return -
*/
private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
AttrTelemetryObserveValue profile = lwM2mInMemorySecurityStore.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
@ -809,31 +807,6 @@ public class LwM2MTransportService {
.orElse("");
}
/**
* Get path to resource from ModelObject equal name
*
* @param name -
* @return true if name isPresent as Resource name (usual format) in ResourceModel
*/
private String getPathAttributeUpdateModelObject(TransportProtos.SessionInfoProto sessionInfo, String name) {
try {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
Predicate<Map.Entry<Integer, ResourceModel>> predicateRes = res -> name.equals(res.getValue().name);
Predicate<Map.Entry<Integer, ModelObject>> predicateObj = (obj -> {
return obj.getValue().getObjectModel().resources.entrySet().stream().filter(predicateRes).findFirst().isPresent();
});
// Map.Entry<Integer, ModelObject> object = lwM2MClient.getModelObjects().entrySet().stream().filter(predicateObj).findFirst().get();
Map.Entry<Integer, ModelObject> object = null;
ModelObject modelObject = object.getValue();
LwM2mObjectInstance instance = modelObject.getInstances().entrySet().stream().findFirst().get().getValue();
ResourceModel resource = modelObject.getObjectModel().resources.entrySet().stream().filter(predicateRes).findFirst().get().getValue();
return new LwM2mPath(object.getKey(), instance.getId(), resource.id).toString();
} catch (NoSuchElementException e) {
log.error("[{}] keyName [{}]", name, e.toString());
return null;
}
}
/**
* Update resource (attribute) value on thingsboard after update value in client
*
@ -842,17 +815,14 @@ public class LwM2MTransportService {
* @param request -
*/
public void onAttributeUpdateOk(Registration registration, String path, WriteRequest request, boolean isDelayedUpdate) {
// ResultIds resultIds = new ResultIds(path);
LwM2mPath resultIds = new LwM2mPath(path);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registration.getId());
// LwM2mResource resource = lwM2MClient.getModelObjects().get(resultIds.getObjectId()).getInstances().get(resultIds.getObjectInstanceId()).getResource(resultIds.getResourceId());
LwM2mResource resource = null;
if (resource.isMultiInstances()) {
ResourceModel resource = context.getCtxServer().getResourceModel(registration, new LwM2mPath(path));
if (resource.multiple) {
this.onObservationSetResourcesValue(registration, null, ((LwM2mSingleResource) request.getNode()).getValues(), path);
} else {
this.onObservationSetResourcesValue(registration, ((LwM2mSingleResource) request.getNode()).getValue(), null, path);
}
if (isDelayedUpdate) lwM2MClient.onSuccessOrErrorDelayedRequests(request.getPath().toString());
if (isDelayedUpdate) lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null)
.onSuccessOrErrorDelayedRequests(request.getPath().toString());
}
/**
@ -863,7 +833,7 @@ public class LwM2MTransportService {
Set<String> registrationIds = lwM2mInMemorySecurityStore.getSessions().entrySet()
.stream()
.filter(e -> e.getValue().getProfileUuid().equals(deviceProfile.getUuidId()))
.map(Map.Entry::getKey).sorted().collect(Collectors.toSet());
.map(Map.Entry::getKey).sorted().collect(Collectors.toCollection(LinkedHashSet::new));
if (registrationIds.size() > 0) {
this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile);
}
@ -968,11 +938,11 @@ public class LwM2MTransportService {
if (sentAttrToThingsboard.getPathPostParametersAdd().size() > 0) {
// update value in Resources
registrationIds.forEach(registrationId -> {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registrationId);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(null, registrationId);
LeshanServer lwServer = lwM2MClient.getLwServer();
Registration registration = lwM2mInMemorySecurityStore.getByRegistration(registrationId);
log.warn("[{}] # 4.1", registration.getEndpoint());
this.updateResourceValueObserve(lwServer, registration, lwM2MClient, sentAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ);
this.updateResourceValueObserve(lwServer, registration, sentAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ);
// sent attr/telemetry to tingsboard for new path
this.updateAttrTelemetry(registration, false, sentAttrToThingsboard.getPathPostParametersAdd());
});
@ -997,11 +967,11 @@ public class LwM2MTransportService {
ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sentObserveToClientOld.getPathPostParametersAdd(), sentObserveToClientNew.getPathPostParametersAdd());
// sent Request observe to Client
registrationIds.forEach(registrationId -> {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registrationId);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(null, registrationId);
LeshanServer lwServer = lwM2MClient.getLwServer();
Registration registration = lwM2mInMemorySecurityStore.getByRegistration(registrationId);
log.warn("[{}] # 5.1", registration.getEndpoint());
this.updateResourceValueObserve(lwServer, registration, lwM2MClient, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE);
this.updateResourceValueObserve(lwServer, registration, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE);
// 5.3 del
// sent Request cancel observe to Client
this.cancelObserveIsValue(lwServer, registration, postObserveAnalyzer.getPathPostParametersDel());
@ -1052,10 +1022,9 @@ public class LwM2MTransportService {
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
* @param lwM2MClient - object with All parameters off client
* @param targets - path Resources == [ "/2/0/0", "/2/0/1"]
*/
private void updateResourceValueObserve(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient, Set<String> targets, String typeOper) {
private void updateResourceValueObserve(LeshanServer lwServer, Registration registration, Set<String> targets, String typeOper) {
targets.forEach(target -> {
LwM2mPath pathIds = new LwM2mPath(target);
if (pathIds.isResource()) {
@ -1073,7 +1042,7 @@ public class LwM2MTransportService {
}
private void cancelObserveIsValue(LeshanServer lwServer, Registration registration, Set<String> paramAnallyzer) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClient(registration.getId());
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getLwM2MClientWithReg(registration, null);
paramAnallyzer.forEach(p -> {
if (this.getResourceValue(lwM2MClient, new LwM2mPath(p)) != null) {
this.setCancelObservationRecourse(lwServer, registration, p);
@ -1130,7 +1099,7 @@ public class LwM2MTransportService {
/**
* if sessionInfo removed from sessions, then new registerAsyncSession
* @param sessionInfo
* @param sessionInfo -
*/
private void checkInactivity(SessionInfoProto sessionInfo) {
if (transportService.reportActivity(sessionInfo) == null) {
@ -1138,20 +1107,14 @@ public class LwM2MTransportService {
}
}
public void sentLogsToThingsboard(String msg, String registrationId) {
public void sentLogsToThingsboard(String msg, Registration registration) {
if (msg != null) {
JsonObject telemetries = new JsonObject();
telemetries.addProperty(LOG_LW2M_TELEMETRY, msg);
this.updateParametersOnThingsboard(telemetries, LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC, registrationId);
this.updateParametersOnThingsboard(telemetries, LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC, registration);
}
}
private String getResourceName(String path) {
LwM2mPath resultIds = new LwM2mPath(path);
return (context.getCtxServer().getObjectModels().get(resultIds.getObjectId()) != null) ?
context.getCtxServer().getObjectModels().get(resultIds.getObjectId()).resources.get(resultIds.getResourceId()).name : "";
}
/**
* @param path - path resource
* @return - value of Resource or null
@ -1160,6 +1123,6 @@ public class LwM2MTransportService {
LwM2mPath pathIds = new LwM2mPath(path);
ResourceValue resourceValue = this.getResourceValue(lwM2MClient, pathIds);
return (resourceValue == null) ? null :
(String) this.converter.convertValue(resourceValue.getResourceValue(), this.context.getCtxServer().getResourceModelType(pathIds), ResourceModel.Type.STRING, pathIds);
(String) this.converter.convertValue(resourceValue.getResourceValue(), this.context.getCtxServer().getResourceModelType(lwM2MClient.getRegistration(), pathIds), ResourceModel.Type.STRING, pathIds);
}
}

View File

@ -129,8 +129,12 @@ public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
return (modelClients != null) ? modelClients.getValue() : null;
}
public LwM2MClient getLwM2MClient(String registrationId) {
return this.sessions.get(registrationId);
public LwM2MClient getLwM2MClientWithReg(Registration registration, String registrationId) {
return registrationId != null ?
this.sessions.get(registrationId) :
this.sessions.containsKey(registration.getId()) ?
this.sessions.get(registration.getId()) :
this.sessions.get(registration.getEndpoint());
}
public LwM2MClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) {

View File

@ -114,9 +114,12 @@
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-core</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-cf</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -22,21 +22,25 @@ 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.registration.Registration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
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.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Slf4j
@Component
@ -177,10 +181,6 @@ public class LwM2MTransportConfigServer {
@Value("${transport.lwm2m.secure.redis_url:}")
private String redisUrl;
@Getter
@Setter
private Map<Integer, ObjectModel> objectModels;
@PostConstruct
public void init() {
modelsValue = ObjectLoader.loadDefault();
@ -196,7 +196,6 @@ public class LwM2MTransportConfigServer {
log.error(" [{}] Read Models", path.getAbsoluteFile());
}
getInKeyStore();
this.objectModels = new ConcurrentHashMap<Integer, ObjectModel>();
}
private File getPathModels() {
@ -248,21 +247,25 @@ public class LwM2MTransportConfigServer {
return FULL_FILE_PATH.toUri().getPath();
}
public ResourceModel getResourceModel(LwM2mPath pathIds) {
return (this.objectModels.size()>0 &&
this.objectModels.containsKey(pathIds.getObjectId()) &&
this.objectModels.get(pathIds.getObjectId()).resources.containsKey(pathIds.getResourceId())) ?
this.objectModels.get(pathIds.getObjectId()).resources.get(pathIds.getResourceId()) : null;
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.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).size() > 0) &&
this.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.containsKey(pathIds.getResourceId()) ?
this.modelsValue.stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0).resources.get(pathIds.getResourceId()) :
null;
}
public ResourceModel.Type getResourceModelType(LwM2mPath pathIds) {
ResourceModel resource = this.getResourceModel(pathIds);
public ResourceModel.Type getResourceModelType(Registration registration, LwM2mPath pathIds) {
ResourceModel resource = this.getResourceModel(registration, pathIds);
return (resource == null) ? null : resource.type;
}
public ResourceModel.Operations getOperation(LwM2mPath pathIds) {
ResourceModel resource = this.getResourceModel(pathIds);
public ResourceModel.Operations getOperation(Registration registration, LwM2mPath pathIds) {
ResourceModel resource = this.getResourceModel(registration, pathIds);
return (resource == null) ? ResourceModel.Operations.NONE : resource.operations;
}
}

25
pom.xml
View File

@ -64,6 +64,7 @@
<json-schema-validator.version>2.2.6</json-schema-validator.version>
<californium.version>2.2.3</californium.version>
<leshan-server.version>1.0.1</leshan-server.version>
<leshan-core.version>1.0.1</leshan-core.version>
<leshan-client.version>1.0.0</leshan-client.version>
<gson.version>2.6.2</gson.version>
<freemarker.version>2.3.30</freemarker.version>
@ -1160,11 +1161,35 @@
<artifactId>leshan-server-redis</artifactId>
<version>${leshan-server.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-core</artifactId>
<version>${leshan-core.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>

View File

@ -78,14 +78,10 @@
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>