From fa8df682070d40e9630b3e621a454d98af195dc3 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 22 Jan 2021 14:46:55 +0200 Subject: [PATCH] Lwm2m: front: refactoring5 --- .../controller/DeviceLwm2mController.java | 10 +- .../service/lwm2m/LwM2MModelsRepository.java | 323 ++++++++++-------- .../server/common/data/lwm2m/LwM2mObject.java | 4 + .../app/core/http/device-profile.service.ts | 14 +- ...ofile-transport-configuration.component.ts | 7 +- 5 files changed, 207 insertions(+), 151 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java index c38a163af9..a12bfb8900 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java @@ -48,13 +48,15 @@ import java.util.Map; @RequestMapping("/api") public class DeviceLwm2mController extends BaseController { - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/lwm2m/deviceProfile/{objectIds}", method = RequestMethod.GET) + @RequestMapping(value = "/lwm2m/deviceProfile", params = {"objectIds"}, method = RequestMethod.GET) @ResponseBody - public List getLwm2mListObjects(@PathVariable("objectIds") int[] objectIds) throws ThingsboardException { + public List getLwm2mListObjects(@RequestParam int[] objectIds, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String sortProperty, + @RequestParam(required = false) String sortOrder) throws ThingsboardException { try { - return lwM2MModelsRepository.getLwm2mObjects(objectIds, null); + return lwM2MModelsRepository.getLwm2mObjects(objectIds, textSearch, sortProperty, sortOrder); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java index cea898e7a1..4057d613b9 100644 --- a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java +++ b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java @@ -23,8 +23,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.lwm2m.*; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.lwm2m.LwM2mInstance; +import org.thingsboard.server.common.data.lwm2m.LwM2mObject; +import org.thingsboard.server.common.data.lwm2m.LwM2mResource; +import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap; @@ -32,17 +35,23 @@ import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; +import java.lang.reflect.Field; import java.math.BigInteger; -import java.security.*; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyStoreException; +import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; -import java.security.spec.ECPublicKeySpec; import java.security.spec.ECPoint; +import java.security.spec.ECPublicKeySpec; import java.security.spec.KeySpec; -import java.util.List; import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -70,22 +79,26 @@ public class LwM2MModelsRepository { * Filter by Predicate (uses objectIds, if objectIds is null then it uses textSearch, * if textSearch is null then it uses AllList from List) */ - public List getLwm2mObjects(int[] objectIds, String textSearch) { - return getLwm2mObjects((objectIds != null && objectIds.length > 0) ? - (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) : - (textSearch != null && !textSearch.isEmpty()) ? (ObjectModel element) -> element.name.contains(textSearch) : null); + public List getLwm2mObjects(int[] objectIds, String textSearch, String sortProperty, String sortOrder) { + return getLwm2mObjects((objectIds != null && objectIds.length > 0 && textSearch != null && !textSearch.isEmpty()) ? + (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) || element.name.contains(textSearch) : + (objectIds != null && objectIds.length > 0) ? + (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) : + (textSearch != null && !textSearch.isEmpty()) ? (ObjectModel element) -> element.name.contains(textSearch) : null, + sortProperty, sortOrder); } /** * @param predicate * @return list of LwM2mObject */ - private List getLwm2mObjects(Predicate predicate) { + private List getLwm2mObjects(Predicate predicate, String sortProperty, String sortOrder) { List lwM2mObjects = new ArrayList<>(); List listObjects = (predicate == null) ? this.contextServer.getModelsValue() : contextServer.getModelsValue().stream() .filter(predicate) .collect(Collectors.toList()); + listObjects.forEach(obj -> { LwM2mObject lwM2mObject = new LwM2mObject(); lwM2mObject.setId(obj.id); @@ -105,153 +118,177 @@ public class LwM2MModelsRepository { lwM2mObject.setInstances(new LwM2mInstance[]{instance}); lwM2mObjects.add(lwM2mObject); }); + try { + Field field = LwM2mObject.class.getField(sortProperty); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + switch (sortProperty) { + case "name": + switch (sortOrder) { + case "ASC": + // ASC + lwM2mObjects.sort((o1, o2) -> o1.getName().compareTo(o2.getName())); + break; + case "DESC": + // DESC + lwM2mObjects.stream().sorted(Comparator.comparing(LwM2mObject::getName).reversed()); + break; + } + case "id": + switch (sortOrder) { + case "ASC": + // ASC + lwM2mObjects.sort((o1, o2) -> Long.compare(o1.getId(), o2.getId())); + break; + case "DESC": + // DESC + lwM2mObjects.sort((o1, o2) -> Long.compare(o2.getId(), o1.getId())); + } + } return lwM2mObjects; } - /** - * @param tenantId - * @param pageLink - * @return List of LwM2mObject in PageData format - */ - public PageData findDeviceLwm2mObjects(TenantId tenantId, PageLink pageLink) { - log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - Validator.validatePageLink(pageLink); - return this.findLwm2mListObjects(pageLink); - } + /** + * @param tenantId + * @param pageLink + * @return List of LwM2mObject in PageData format + */ + public PageData findDeviceLwm2mObjects (TenantId tenantId, PageLink pageLink){ + log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validatePageLink(pageLink); + return this.findLwm2mListObjects(pageLink); + } - /** - * @param pageLink - * @return List of LwM2mObject in PageData format, filter == TextSearch - * PageNumber = 1, PageSize = List.size() - */ - public PageData findLwm2mListObjects(PageLink pageLink) { - PageImpl page = new PageImpl(getLwm2mObjects(null, pageLink.getTextSearch())); - PageData pageData = new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext()); - return pageData; - } + /** + * @param pageLink + * @return List of LwM2mObject in PageData format, filter == TextSearch + * PageNumber = 1, PageSize = List.size() + */ + public PageData findLwm2mListObjects (PageLink pageLink){ + PageImpl page = new PageImpl(getLwm2mObjects(null, pageLink.getTextSearch(), pageLink.getSortOrder().getProperty(), pageLink.getSortOrder().getDirection().name())); + PageData pageData = new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext()); + return pageData; + } - /** - * - * @param securityMode - * @param bootstrapServerIs - * @return ServerSecurityConfig more value is default: Important - port, host, publicKey - */ - public ServerSecurityConfig getBootstrapSecurityInfo(String securityMode, boolean bootstrapServerIs) { - LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase()); - return getBootstrapServer(bootstrapServerIs, lwM2MSecurityMode); - } + /** + * @param securityMode + * @param bootstrapServerIs + * @return ServerSecurityConfig more value is default: Important - port, host, publicKey + */ + public ServerSecurityConfig getBootstrapSecurityInfo (String securityMode,boolean bootstrapServerIs){ + LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase()); + return getBootstrapServer(bootstrapServerIs, lwM2MSecurityMode); + } - /** - * - * @param bootstrapServerIs - * @param mode - * @return ServerSecurityConfig more value is default: Important - port, host, publicKey - */ - private ServerSecurityConfig getBootstrapServer(boolean bootstrapServerIs, LwM2MSecurityMode mode) { - ServerSecurityConfig bsServ = new ServerSecurityConfig(); - bsServ.setBootstrapServerIs(bootstrapServerIs); - if (bootstrapServerIs) { - bsServ.setServerId(contextBootStrap.getBootstrapServerId()); - switch (mode) { - case NO_SEC: - bsServ.setHost(contextBootStrap.getBootstrapHost()); - bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk()); - bsServ.setServerPublicKey(""); - break; - case PSK: - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); - bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk()); - bsServ.setServerPublicKey(""); - break; - case RPK: - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); - bsServ.setPort(contextBootStrap.getBootstrapSecurePortRpk()); - bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY())); - break; - case X509: - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); - bsServ.setPort(contextBootStrap.getBootstrapSecurePortX509()); - bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias())); - break; - default: - break; - } - } else { - bsServ.setServerId(contextServer.getServerId()); - switch (mode) { - case NO_SEC: - bsServ.setHost(contextServer.getServerHost()); - bsServ.setPort(contextServer.getServerPortNoSecPsk()); - bsServ.setServerPublicKey(""); - break; - case PSK: - bsServ.setHost(contextServer.getServerSecureHost()); - bsServ.setPort(contextServer.getServerPortPsk()); - bsServ.setServerPublicKey(""); - break; - case RPK: - bsServ.setHost(contextServer.getServerSecureHost()); - bsServ.setPort(contextServer.getServerPortRpk()); - bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY())); - break; - case X509: - bsServ.setHost(contextServer.getServerSecureHost()); - bsServ.setPort(contextServer.getServerPortX509()); - bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias())); - break; - default: - break; + /** + * @param bootstrapServerIs + * @param mode + * @return ServerSecurityConfig more value is default: Important - port, host, publicKey + */ + private ServerSecurityConfig getBootstrapServer ( boolean bootstrapServerIs, LwM2MSecurityMode mode){ + ServerSecurityConfig bsServ = new ServerSecurityConfig(); + bsServ.setBootstrapServerIs(bootstrapServerIs); + if (bootstrapServerIs) { + bsServ.setServerId(contextBootStrap.getBootstrapServerId()); + switch (mode) { + case NO_SEC: + bsServ.setHost(contextBootStrap.getBootstrapHost()); + bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk()); + bsServ.setServerPublicKey(""); + break; + case PSK: + bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); + bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk()); + bsServ.setServerPublicKey(""); + break; + case RPK: + bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); + bsServ.setPort(contextBootStrap.getBootstrapSecurePortRpk()); + bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY())); + break; + case X509: + bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); + bsServ.setPort(contextBootStrap.getBootstrapSecurePortX509()); + bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias())); + break; + default: + break; + } + } else { + bsServ.setServerId(contextServer.getServerId()); + switch (mode) { + case NO_SEC: + bsServ.setHost(contextServer.getServerHost()); + bsServ.setPort(contextServer.getServerPortNoSecPsk()); + bsServ.setServerPublicKey(""); + break; + case PSK: + bsServ.setHost(contextServer.getServerSecureHost()); + bsServ.setPort(contextServer.getServerPortPsk()); + bsServ.setServerPublicKey(""); + break; + case RPK: + bsServ.setHost(contextServer.getServerSecureHost()); + bsServ.setPort(contextServer.getServerPortRpk()); + bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY())); + break; + case X509: + bsServ.setHost(contextServer.getServerSecureHost()); + bsServ.setPort(contextServer.getServerPortX509()); + bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias())); + break; + default: + break; + } } + return bsServ; } - return bsServ; - } - /** - * - * @param alias - * @return PublicKey format HexString or null - */ - private String getServerPublicKeyX509 (String alias) { - try { - X509Certificate serverCertificate = (X509Certificate) contextServer.getKeyStoreValue().getCertificate(alias); - return Hex.encodeHexString(serverCertificate.getEncoded()); - } catch (CertificateEncodingException | KeyStoreException e) { - e.printStackTrace(); + /** + * @param alias + * @return PublicKey format HexString or null + */ + private String getServerPublicKeyX509 (String alias){ + try { + X509Certificate serverCertificate = (X509Certificate) contextServer.getKeyStoreValue().getCertificate(alias); + return Hex.encodeHexString(serverCertificate.getEncoded()); + } catch (CertificateEncodingException | KeyStoreException e) { + e.printStackTrace(); + } + return null; } - return null; - } - /** - * - * @param publicServerX - * @param publicServerY - * @return PublicKey format HexString or null - */ - private String getRPKPublicKey(String publicServerX, String publicServerY) { - try { - /** Get Elliptic Curve Parameter spec for secp256r1 */ - AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); - algoParameters.init(new ECGenParameterSpec("secp256r1")); - ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); - if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) { - /** Get point values */ - byte[] publicX = Hex.decodeHex(publicServerX.toCharArray()); - byte[] publicY = Hex.decodeHex(publicServerY.toCharArray()); - /** Create key specs */ - KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), - parameterSpec); - /** Get keys */ - PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); - if (publicKey != null && publicKey.getEncoded().length > 0 ) { - return Hex.encodeHexString(publicKey.getEncoded()); + /** + * @param publicServerX + * @param publicServerY + * @return PublicKey format HexString or null + */ + private String getRPKPublicKey (String publicServerX, String publicServerY){ + try { + /** Get Elliptic Curve Parameter spec for secp256r1 */ + AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); + algoParameters.init(new ECGenParameterSpec("secp256r1")); + ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); + if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) { + /** Get point values */ + byte[] publicX = Hex.decodeHex(publicServerX.toCharArray()); + byte[] publicY = Hex.decodeHex(publicServerY.toCharArray()); + /** Create key specs */ + KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), + parameterSpec); + /** Get keys */ + PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); + if (publicKey != null && publicKey.getEncoded().length > 0) { + return Hex.encodeHexString(publicKey.getEncoded()); + } } + } catch (GeneralSecurityException | IllegalArgumentException e) { + log.error("[{}] Failed generate Server RPK for profile", e.getMessage()); + throw new RuntimeException(e); } - } catch (GeneralSecurityException | IllegalArgumentException e) { - log.error("[{}] Failed generate Server RPK for profile", e.getMessage()); - throw new RuntimeException(e); + return null; } - return null; } -} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java index 4bd700fdf9..5afb37c720 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java @@ -16,7 +16,11 @@ package org.thingsboard.server.common.data.lwm2m; import lombok.Data; +import lombok.Getter; +import lombok.Setter; +@Setter +@Getter @Data public class LwM2mObject { int id; diff --git a/ui-ngx/src/app/core/http/device-profile.service.ts b/ui-ngx/src/app/core/http/device-profile.service.ts index 22ff52e99b..816dde3260 100644 --- a/ui-ngx/src/app/core/http/device-profile.service.ts +++ b/ui-ngx/src/app/core/http/device-profile.service.ts @@ -23,6 +23,7 @@ import { PageData } from '@shared/models/page/page-data'; import { DeviceProfile, DeviceProfileInfo, DeviceTransportType } from '@shared/models/device.models'; import { isDefinedAndNotNull } from '@core/utils'; import { ObjectLwM2M, ServerSecurityConfig } from '@home/components/profile/device/lwm2m/profile-config.models'; +import { SortOrder } from '@shared/models/page/sort-order'; @Injectable({ providedIn: 'root' @@ -31,7 +32,8 @@ export class DeviceProfileService { constructor( private http: HttpClient - ) { } + ) { + } public getDeviceProfiles(pageLink: PageLink, config?: RequestConfig): Observable> { return this.http.get>(`/api/deviceProfiles${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config)); @@ -41,8 +43,14 @@ export class DeviceProfileService { return this.http.get(`/api/deviceProfile/${deviceProfileId}`, defaultHttpOptionsFromConfig(config)); } - public getLwm2mObjects(objectIds: number[], config?: RequestConfig): Observable> { - return this.http.get>(`/api/lwm2m/deviceProfile/${objectIds}`, defaultHttpOptionsFromConfig(config)); + public getLwm2mObjects(objectIds?: number[], searchText?: string, sortOrder?: SortOrder, config?: RequestConfig): + Observable> { + // tslint:disable-next-line:no-debugger + debugger; + return this.http.get> + (`/api/lwm2m/deviceProfile/?objectIds=${objectIds}&searchText=${searchText}&sortProperty=${sortOrder.property} + &sortOrder=${sortOrder.direction}`, + defaultHttpOptionsFromConfig(config)); } public getLwm2mBootstrapSecurityInfo(securityMode: string, bootstrapServerIs: boolean, diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index 1711f11ade..3dbe82287a 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -37,6 +37,7 @@ import { deepClone, isUndefined } from '@core/utils'; import { WINDOW } from '@core/services/window.service'; import { JsonObject } from '@angular/compiler-cli/ngcc/src/packages/entry_point'; import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined'; +import { Direction, SortOrder } from '@shared/models/page/sort-order'; @Component({ selector: 'tb-profile-lwm2m-device-transport-configuration', @@ -128,7 +129,11 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro const modelValue = {objectIds: null, objectsList: []}; modelValue.objectIds = this.getObjectsFromJsonAllConfig(); if (modelValue.objectIds !== null) { - this.deviceProfileService.getLwm2mObjects(modelValue.objectIds).subscribe( + const sortOrder = { + property: 'id', + direction: Direction.ASC + }; + this.deviceProfileService.getLwm2mObjects(modelValue.objectIds, null, sortOrder).subscribe( (objectsList) => { modelValue.objectsList = objectsList; this.updateWriteValue(modelValue);