Lwm2m: back: add key to profile - refactoring-light start2

This commit is contained in:
nickAS21 2021-02-02 19:09:07 +02:00 committed by Andrew Shvayka
parent c230e3fdcd
commit ade09738eb
8 changed files with 653 additions and 620 deletions

View File

@ -249,6 +249,11 @@ public class LwM2MTransportHandler {
profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientUpdateValueAfterConnect").getAsBoolean();
}
public static boolean getClientOnlyObserveAfterConnect (LwM2MClientProfile profile) {
return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") &&
profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsBoolean();
}
private static boolean getValidateCredentialsBodyFromThingsboard(JsonObject objectMsg) {
return (objectMsg != null &&
!objectMsg.isJsonNull() &&

View File

@ -226,7 +226,7 @@ public class LwM2MTransportRequest {
String msg = String.format(LOG_LW2M_ERROR + ": sendRequest: Resource path - %s msg No SendRequest to Client", target);
service.sentLogsToThingsboard(msg, registration);
log.error("[{}] - [{}] No SendRequest", target);
this.handleResponseError(registration, target, lwM2MClient, true);
// this.handleResponseError(registration, target, lwM2MClient, true);
}
}
@ -262,9 +262,9 @@ public class LwM2MTransportRequest {
((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString());
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);
}
// if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest() && isDelayedUpdate) {
// this.handleResponseError(registration, request.getPath().toString(), lwM2MClient, isDelayedUpdate);
// }
}
}, e -> {
@ -272,9 +272,9 @@ public class LwM2MTransportRequest {
request.getPath().toString(), e.toString());
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);
}
// if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest() && isDelayedUpdate) {
// this.handleResponseError(registration, request.getPath().toString(), lwM2MClient, isDelayedUpdate);
// }
});
}
@ -317,16 +317,16 @@ public class LwM2MTransportRequest {
}
});
}
private void handleResponseError(Registration registration, final String path, LwM2MClient lwM2MClient, boolean isDelayedUpdate) {
executorResponseError.submit(() -> {
try {
if (isDelayedUpdate) lwM2MClient.onSuccessOrErrorDelayedRequests(path);
} catch (RuntimeException t) {
log.error("[{}] endpoint [{}] path [{}] RuntimeException Unable to after send response.", registration.getEndpoint(), path, t);
}
});
}
//
// private void handleResponseError(Registration registration, final String path, LwM2MClient lwM2MClient, boolean isDelayedUpdate) {
// executorResponseError.submit(() -> {
// try {
// if (isDelayedUpdate) lwM2MClient.onSuccessOrErrorDelayedRequests(path);
// } catch (RuntimeException t) {
// log.error("[{}] endpoint [{}] path [{}] RuntimeException Unable to after send response.", registration.getEndpoint(), path, t);
// }
// });
// }
/**
* processing a response from a client
@ -336,26 +336,10 @@ public class LwM2MTransportRequest {
* @param lwM2MClient -
*/
private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request, LwM2MClient lwM2MClient, boolean isDelayedUpdate) {
if (response instanceof ObserveResponse) {
if (response instanceof ObserveResponse || response instanceof ReadResponse) {
service.onObservationResponse(registration, path, (ReadResponse) response);
} else if (response instanceof CancelObservationResponse) {
log.info("[{}] Path [{}] CancelObservationResponse 3_Send", path, response);
} else if (response instanceof ReadResponse) {
/**
* Use only at the first start after registration
* Fill with data -> Model client
*/
if (lwM2MClient != null) {
if (lwM2MClient.getPendingRequests().size() > 0) {
lwM2MClient.onSuccessHandler(path, response);
}
}
/**
* Use after registration on request
*/
else {
service.onObservationResponse(registration, path, (ReadResponse) response);
}
} else if (response instanceof DeleteResponse) {
log.info("[{}] Path [{}] DeleteResponse 5_Send", path, response);
} else if (response instanceof DiscoverResponse) {
@ -366,7 +350,7 @@ public class LwM2MTransportRequest {
log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", path, response);
} else if (response instanceof WriteResponse) {
log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", path, response);
service.onAttributeUpdateOk(registration, path, (WriteRequest) request, isDelayedUpdate);
service.onWriteResponseOk(registration, path, (WriteRequest) request, isDelayedUpdate);
}
}
}

View File

@ -18,12 +18,8 @@ package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.node.LwM2mMultipleResource;
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.response.LwM2mResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.SecurityInfo;
@ -33,7 +29,6 @@ import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportServiceImpl;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -54,10 +49,10 @@ public class LwM2MClient implements Cloneable {
private ValidateDeviceCredentialsResponseMsg credentialsResponse;
private Map<String, String> attributes;
private Map<String, ResourceValue> resources;
private Set<String> pendingRequests;
// private Set<String> pendingRequests;
private Map<String, TransportProtos.TsKvProto> delayedRequests;
private Set<Integer> delayedRequestsId;
private Map<String, LwM2mResponse> responses;
// private Set<Integer> delayedRequestsId;
// private Map<String, LwM2mResponse> responses;
private final LwM2mValueConverterImpl converter;
public Object clone() throws CloneNotSupportedException {
@ -70,69 +65,76 @@ public class LwM2MClient implements Cloneable {
this.securityInfo = securityInfo;
this.credentialsResponse = credentialsResponse;
this.attributes = new ConcurrentHashMap<>();
this.pendingRequests = ConcurrentHashMap.newKeySet();
// this.pendingRequests = ConcurrentHashMap.newKeySet();
this.delayedRequests = new ConcurrentHashMap<>();
this.resources = new ConcurrentHashMap<>();
this.delayedRequestsId = ConcurrentHashMap.newKeySet();
// this.delayedRequestsId = ConcurrentHashMap.newKeySet();
this.profileUuid = profileUuid;
/**
* Key <objectId>, response<Value -> instance -> resources: value...>
*/
this.responses = new ConcurrentHashMap<>();
// this.responses = new ConcurrentHashMap<>();
this.converter = LwM2mValueConverterImpl.getInstance();
}
/**
* Fill with data -> Model client
*
* @param path -
* @param response -
*/
public void onSuccessHandler(String path, LwM2mResponse response) {
this.responses.put(path, response);
this.pendingRequests.remove(path);
if (this.pendingRequests.size() == 0) {
this.initValue();
this.lwM2MTransportServiceImpl.putDelayedUpdateResourcesThingsboard(this);
}
}
// /**
// * Fill with data -> Model client
// *
// * @param path -
// * @param response -
// */
// public void onSuccessHandler(String path, LwM2mResponse response) {
// this.responses.put(path, response);
// this.pendingRequests.remove(path);
// if (this.pendingRequests.size() == 0) {
// this.initValue();
// this.lwM2MTransportServiceImpl.putDelayedUpdateResourcesThingsboard(this);
// }
// }
//
// private void initValue() {
// this.responses.forEach((key, lwM2mResponse) -> {
// LwM2mPath pathIds = new LwM2mPath(key);
// if (pathIds.isObjectInstance()) {
// ((LwM2mObjectInstance) ((ReadResponse) lwM2mResponse).getContent()).getResources().forEach((k, v) -> {
// String pathRez = pathIds.toString() + "/" + k;
// this.updateResourceValue(pathRez, v);
// });
// }
// else if (pathIds.isResource()) {
// this.updateResourceValue(pathIds.toString(), ((LwM2mResource) ((ReadResponse) lwM2mResponse).getContent()));
// }
// });
// if (this.responses.size() == 0) this.responses = new ConcurrentHashMap<>();
// }
private void initValue() {
this.responses.forEach((key, lwM2mResponse) -> {
LwM2mPath pathIds = new LwM2mPath(key);
if (pathIds.isObjectInstance()) {
((LwM2mObjectInstance) ((ReadResponse) lwM2mResponse).getContent()).getResources().forEach((k, v) -> {
String pathRez = pathIds.toString() + "/" + k;
this.updateResourceValue(pathRez, v);
});
}
else if (pathIds.isResource()) {
this.updateResourceValue(pathIds.toString(), ((LwM2mResource) ((ReadResponse) lwM2mResponse).getContent()));
}
});
if (this.responses.size() == 0) this.responses = new ConcurrentHashMap<>();
}
// public void updateObjectInstanceResourceValue(String pathInst, LwM2mObjectInstance instance) {
// LwM2mPath pathIds = new LwM2mPath(pathInst);
// instance.getResources().forEach((k, v) -> {
// String pathRez = pathIds.toString() + "/" + k;
// this.updateResourceValue(pathRez, v);
// });
// }
public void updateResourceValue(String pathRez, LwM2mResource rez) {
if (rez instanceof LwM2mMultipleResource){
if (rez instanceof LwM2mMultipleResource) {
this.resources.put(pathRez, new ResourceValue(rez.getValues(), null, true));
}
else if (rez instanceof LwM2mSingleResource) {
} else if (rez instanceof LwM2mSingleResource) {
this.resources.put(pathRez, new ResourceValue(null, rez.getValue(), false));
}
}
/**
* if path != null
*
* @param path
*/
public void onSuccessOrErrorDelayedRequests(String path) {
if (path != null) this.delayedRequests.remove(path);
if (this.delayedRequests.size() == 0 && this.getDelayedRequestsId().size() == 0) {
this.lwM2MTransportServiceImpl.updatesAndSentModelParameter(this);
}
}
// /**
// * if path != null
// *
// * @param path
// */
// public void onSuccessOrErrorDelayedRequests(String path) {
// if (path != null) this.delayedRequests.remove(path);
// if (this.delayedRequests.size() == 0 && this.getDelayedRequestsId().size() == 0) {
// this.lwM2MTransportServiceImpl.updatesAndSentModelParameter(this);
// }
// }
}

View File

@ -21,14 +21,20 @@
<ng-template matTabContent>
<section [formGroup]="lwm2mDeviceProfileFormGroup">
<div class="mat-padding" style="padding-bottom: 0px">
<mat-checkbox formControlName="clientUpdateValueAfterConnect" color="primary"
<mat-checkbox formControlName="clientOnlyObserveAfterConnect" color="primary"
matTooltip="{{ translate.get('device-profile.lwm2m.client-only-observe-after-connect-tip',
{ count: +lwm2mDeviceProfileFormGroup.get('clientOnlyObserveAfterConnect').value }) | async }}"
matTooltipPosition="above">
{{ translate.get('device-profile.lwm2m.client-only-observe-after-connect',
{ count: +lwm2mDeviceProfileFormGroup.get('clientOnlyObserveAfterConnect').value }) | async }}
</mat-checkbox>
<mat-checkbox *ngIf="!lwm2mDeviceProfileFormGroup.get('clientOnlyObserveAfterConnect').value"
formControlName="clientUpdateValueAfterConnect" color="primary"
matTooltip="{{ translate.get('device-profile.lwm2m.client-update-value-after-connect-tip',
{ count: +lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value,
value: lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value }) | async }}"
{ count: +lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value }) | async }}"
matTooltipPosition="above">
{{ translate.get('device-profile.lwm2m.client-update-value-after-connect',
{ count: +lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value,
value: lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value }) | async }}
{ count: +lwm2mDeviceProfileFormGroup.get('clientUpdateValueAfterConnect').value }) | async }}
</mat-checkbox>
</div>
<div class="mat-padding" style="padding-top: 0">

View File

@ -74,6 +74,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
private deviceProfileService: DeviceProfileService,
@Inject(WINDOW) private window: Window) {
this.lwm2mDeviceProfileFormGroup = this.fb.group({
clientOnlyObserveAfterConnect: [true, []],
clientUpdateValueAfterConnect: [false, []],
objectIds: [null, Validators.required],
observeAttrTelemetry: [null, Validators.required],
@ -144,6 +145,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
private updateWriteValue = (value: ModelValue): void => {
this.lwm2mDeviceProfileFormGroup.patchValue({
clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect,
clientUpdateValueAfterConnect: this.configurationValue.clientLwM2mSettings.clientUpdateValueAfterConnect,
objectIds: value,
observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value['objectsList']),
@ -176,6 +178,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
private updateDeviceProfileValue(config): void {
if (this.lwm2mDeviceProfileFormGroup.valid) {
this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect =
config.clientOnlyObserveAfterConnect;
this.configurationValue.clientLwM2mSettings.clientUpdateValueAfterConnect =
config.clientUpdateValueAfterConnect;
this.updateObserveAttrTelemetryFromGroupToJson(config.observeAttrTelemetry.clientLwM2M);

View File

@ -97,7 +97,8 @@ export interface ProfileConfigModels {
}
export interface ClientLwM2mSettings {
clientUpdateValueAfterConnect: false;
clientOnlyObserveAfterConnect: boolean;
clientUpdateValueAfterConnect: boolean;
}
export interface ObservableAttributes {
observe: string[];
@ -145,17 +146,26 @@ function getDefaultProfileBootstrapSecurityConfig(hostname: any): BootstrapSecur
};
}
function getDefaultProfileObserveAttrConfig(): ObservableAttributes {
return {
observe: [],
attribute: [],
telemetry: [],
keyName: {}
};
}
function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings {
return {
clientOnlyObserveAfterConnect: true,
clientUpdateValueAfterConnect: false
};
}
export function getDefaultProfileConfig(hostname?: any): ProfileConfigModels {
return {
clientLwM2mSettings: {
clientUpdateValueAfterConnect: false
},
observeAttr: {
observe: [],
attribute: [],
telemetry: [],
keyName: {}
},
clientLwM2mSettings: getDefaultProfileClientLwM2mSettingsConfig(),
observeAttr: getDefaultProfileObserveAttrConfig(),
bootstrap: getDefaultProfileBootstrapSecurityConfig((hostname) ? hostname : DEFAULT_HOST_NAME)
};
}

View File

@ -1103,6 +1103,8 @@
"schedule-time-to": "To",
"schedule-days-of-week-required": "At least one day of week should be selected.",
"lwm2m": {
"client-only-observe-after-connect": "{ count, plural, 1 {Only Observe Request to the client after registration} other {Read&Observe Request to the client after registration} }",
"client-only-observe-after-connect-tip": "{ count, plural, 1 {Only Observe Request to the client marked as observe from the profile configuration.} other {Read Request to the client after registration to read the values of the resources then Observe Request to the client marked as observe from the profile configuration.} }",
"client-update-value-after-connect": "{ count, plural, 1 {Request to the client after registration for All resource values} other {Request to the client after registration to read values only as attributes or telemetry} }",
"client-update-value-after-connect-tip": "{ count, plural, 1 {Request to the client after registration to read all resource values for all objects} other {Request to the client after registration to read the values of the resources marked as attribute or telemetry from the profile configuration.} }",
"object-list": "Object list",