Commit fa8df682070d40e9630b3e621a454d98af195dc3

Authored by nickAS21
1 parent 15abe85b

Lwm2m: front: refactoring5

... ... @@ -48,13 +48,15 @@ import java.util.Map;
48 48 @RequestMapping("/api")
49 49 public class DeviceLwm2mController extends BaseController {
50 50
51   -
52 51 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
53   - @RequestMapping(value = "/lwm2m/deviceProfile/{objectIds}", method = RequestMethod.GET)
  52 + @RequestMapping(value = "/lwm2m/deviceProfile", params = {"objectIds"}, method = RequestMethod.GET)
54 53 @ResponseBody
55   - public List<LwM2mObject> getLwm2mListObjects(@PathVariable("objectIds") int[] objectIds) throws ThingsboardException {
  54 + public List<LwM2mObject> getLwm2mListObjects(@RequestParam int[] objectIds,
  55 + @RequestParam(required = false) String textSearch,
  56 + @RequestParam(required = false) String sortProperty,
  57 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
56 58 try {
57   - return lwM2MModelsRepository.getLwm2mObjects(objectIds, null);
  59 + return lwM2MModelsRepository.getLwm2mObjects(objectIds, textSearch, sortProperty, sortOrder);
58 60 } catch (Exception e) {
59 61 throw handleException(e);
60 62 }
... ...
... ... @@ -23,8 +23,11 @@ import org.springframework.beans.factory.annotation.Autowired;
23 23 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
24 24 import org.springframework.data.domain.PageImpl;
25 25 import org.springframework.stereotype.Service;
26   -import org.thingsboard.server.common.data.lwm2m.*;
27 26 import org.thingsboard.server.common.data.id.TenantId;
  27 +import org.thingsboard.server.common.data.lwm2m.LwM2mInstance;
  28 +import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
  29 +import org.thingsboard.server.common.data.lwm2m.LwM2mResource;
  30 +import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
28 31 import org.thingsboard.server.common.data.page.PageData;
29 32 import org.thingsboard.server.common.data.page.PageLink;
30 33 import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap;
... ... @@ -32,17 +35,23 @@ import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
32 35 import org.thingsboard.server.dao.service.Validator;
33 36 import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
34 37
  38 +import java.lang.reflect.Field;
35 39 import java.math.BigInteger;
36   -import java.security.*;
  40 +import java.security.AlgorithmParameters;
  41 +import java.security.GeneralSecurityException;
  42 +import java.security.KeyFactory;
  43 +import java.security.KeyStoreException;
  44 +import java.security.PublicKey;
37 45 import java.security.cert.CertificateEncodingException;
38 46 import java.security.cert.X509Certificate;
39 47 import java.security.spec.ECGenParameterSpec;
40 48 import java.security.spec.ECParameterSpec;
41   -import java.security.spec.ECPublicKeySpec;
42 49 import java.security.spec.ECPoint;
  50 +import java.security.spec.ECPublicKeySpec;
43 51 import java.security.spec.KeySpec;
44   -import java.util.List;
45 52 import java.util.ArrayList;
  53 +import java.util.Comparator;
  54 +import java.util.List;
46 55 import java.util.function.Predicate;
47 56 import java.util.stream.Collectors;
48 57 import java.util.stream.IntStream;
... ... @@ -70,22 +79,26 @@ public class LwM2MModelsRepository {
70 79 * Filter by Predicate (uses objectIds, if objectIds is null then it uses textSearch,
71 80 * if textSearch is null then it uses AllList from List<ObjectModel>)
72 81 */
73   - public List<LwM2mObject> getLwm2mObjects(int[] objectIds, String textSearch) {
74   - return getLwm2mObjects((objectIds != null && objectIds.length > 0) ?
75   - (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) :
76   - (textSearch != null && !textSearch.isEmpty()) ? (ObjectModel element) -> element.name.contains(textSearch) : null);
  82 + public List<LwM2mObject> getLwm2mObjects(int[] objectIds, String textSearch, String sortProperty, String sortOrder) {
  83 + return getLwm2mObjects((objectIds != null && objectIds.length > 0 && textSearch != null && !textSearch.isEmpty()) ?
  84 + (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) || element.name.contains(textSearch) :
  85 + (objectIds != null && objectIds.length > 0) ?
  86 + (ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) :
  87 + (textSearch != null && !textSearch.isEmpty()) ? (ObjectModel element) -> element.name.contains(textSearch) : null,
  88 + sortProperty, sortOrder);
77 89 }
78 90
79 91 /**
80 92 * @param predicate
81 93 * @return list of LwM2mObject
82 94 */
83   - private List<LwM2mObject> getLwm2mObjects(Predicate<? super ObjectModel> predicate) {
  95 + private List<LwM2mObject> getLwm2mObjects(Predicate<? super ObjectModel> predicate, String sortProperty, String sortOrder) {
84 96 List<LwM2mObject> lwM2mObjects = new ArrayList<>();
85 97 List<ObjectModel> listObjects = (predicate == null) ? this.contextServer.getModelsValue() :
86 98 contextServer.getModelsValue().stream()
87 99 .filter(predicate)
88 100 .collect(Collectors.toList());
  101 +
89 102 listObjects.forEach(obj -> {
90 103 LwM2mObject lwM2mObject = new LwM2mObject();
91 104 lwM2mObject.setId(obj.id);
... ... @@ -105,153 +118,177 @@ public class LwM2MModelsRepository {
105 118 lwM2mObject.setInstances(new LwM2mInstance[]{instance});
106 119 lwM2mObjects.add(lwM2mObject);
107 120 });
  121 + try {
  122 + Field field = LwM2mObject.class.getField(sortProperty);
  123 + } catch (NoSuchFieldException e) {
  124 + e.printStackTrace();
  125 + }
  126 + switch (sortProperty) {
  127 + case "name":
  128 + switch (sortOrder) {
  129 + case "ASC":
  130 + // ASC
  131 + lwM2mObjects.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
  132 + break;
  133 + case "DESC":
  134 + // DESC
  135 + lwM2mObjects.stream().sorted(Comparator.comparing(LwM2mObject::getName).reversed());
  136 + break;
  137 + }
  138 + case "id":
  139 + switch (sortOrder) {
  140 + case "ASC":
  141 + // ASC
  142 + lwM2mObjects.sort((o1, o2) -> Long.compare(o1.getId(), o2.getId()));
  143 + break;
  144 + case "DESC":
  145 + // DESC
  146 + lwM2mObjects.sort((o1, o2) -> Long.compare(o2.getId(), o1.getId()));
  147 + }
  148 + }
108 149 return lwM2mObjects;
109 150 }
110 151
111   - /**
112   - * @param tenantId
113   - * @param pageLink
114   - * @return List of LwM2mObject in PageData format
115   - */
116   - public PageData<LwM2mObject> findDeviceLwm2mObjects(TenantId tenantId, PageLink pageLink) {
117   - log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink);
118   - validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
119   - Validator.validatePageLink(pageLink);
120   - return this.findLwm2mListObjects(pageLink);
121   - }
  152 + /**
  153 + * @param tenantId
  154 + * @param pageLink
  155 + * @return List of LwM2mObject in PageData format
  156 + */
  157 + public PageData<LwM2mObject> findDeviceLwm2mObjects (TenantId tenantId, PageLink pageLink){
  158 + log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink);
  159 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  160 + Validator.validatePageLink(pageLink);
  161 + return this.findLwm2mListObjects(pageLink);
  162 + }
122 163
123   - /**
124   - * @param pageLink
125   - * @return List of LwM2mObject in PageData format, filter == TextSearch
126   - * PageNumber = 1, PageSize = List<LwM2mObject>.size()
127   - */
128   - public PageData<LwM2mObject> findLwm2mListObjects(PageLink pageLink) {
129   - PageImpl page = new PageImpl(getLwm2mObjects(null, pageLink.getTextSearch()));
130   - PageData pageData = new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
131   - return pageData;
132   - }
  164 + /**
  165 + * @param pageLink
  166 + * @return List of LwM2mObject in PageData format, filter == TextSearch
  167 + * PageNumber = 1, PageSize = List<LwM2mObject>.size()
  168 + */
  169 + public PageData<LwM2mObject> findLwm2mListObjects (PageLink pageLink){
  170 + PageImpl page = new PageImpl(getLwm2mObjects(null, pageLink.getTextSearch(), pageLink.getSortOrder().getProperty(), pageLink.getSortOrder().getDirection().name()));
  171 + PageData pageData = new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
  172 + return pageData;
  173 + }
133 174
134   - /**
135   - *
136   - * @param securityMode
137   - * @param bootstrapServerIs
138   - * @return ServerSecurityConfig more value is default: Important - port, host, publicKey
139   - */
140   - public ServerSecurityConfig getBootstrapSecurityInfo(String securityMode, boolean bootstrapServerIs) {
141   - LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase());
142   - return getBootstrapServer(bootstrapServerIs, lwM2MSecurityMode);
143   - }
  175 + /**
  176 + * @param securityMode
  177 + * @param bootstrapServerIs
  178 + * @return ServerSecurityConfig more value is default: Important - port, host, publicKey
  179 + */
  180 + public ServerSecurityConfig getBootstrapSecurityInfo (String securityMode,boolean bootstrapServerIs){
  181 + LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase());
  182 + return getBootstrapServer(bootstrapServerIs, lwM2MSecurityMode);
  183 + }
144 184
145   - /**
146   - *
147   - * @param bootstrapServerIs
148   - * @param mode
149   - * @return ServerSecurityConfig more value is default: Important - port, host, publicKey
150   - */
151   - private ServerSecurityConfig getBootstrapServer(boolean bootstrapServerIs, LwM2MSecurityMode mode) {
152   - ServerSecurityConfig bsServ = new ServerSecurityConfig();
153   - bsServ.setBootstrapServerIs(bootstrapServerIs);
154   - if (bootstrapServerIs) {
155   - bsServ.setServerId(contextBootStrap.getBootstrapServerId());
156   - switch (mode) {
157   - case NO_SEC:
158   - bsServ.setHost(contextBootStrap.getBootstrapHost());
159   - bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk());
160   - bsServ.setServerPublicKey("");
161   - break;
162   - case PSK:
163   - bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
164   - bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk());
165   - bsServ.setServerPublicKey("");
166   - break;
167   - case RPK:
168   - bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
169   - bsServ.setPort(contextBootStrap.getBootstrapSecurePortRpk());
170   - bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY()));
171   - break;
172   - case X509:
173   - bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
174   - bsServ.setPort(contextBootStrap.getBootstrapSecurePortX509());
175   - bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias()));
176   - break;
177   - default:
178   - break;
179   - }
180   - } else {
181   - bsServ.setServerId(contextServer.getServerId());
182   - switch (mode) {
183   - case NO_SEC:
184   - bsServ.setHost(contextServer.getServerHost());
185   - bsServ.setPort(contextServer.getServerPortNoSecPsk());
186   - bsServ.setServerPublicKey("");
187   - break;
188   - case PSK:
189   - bsServ.setHost(contextServer.getServerSecureHost());
190   - bsServ.setPort(contextServer.getServerPortPsk());
191   - bsServ.setServerPublicKey("");
192   - break;
193   - case RPK:
194   - bsServ.setHost(contextServer.getServerSecureHost());
195   - bsServ.setPort(contextServer.getServerPortRpk());
196   - bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY()));
197   - break;
198   - case X509:
199   - bsServ.setHost(contextServer.getServerSecureHost());
200   - bsServ.setPort(contextServer.getServerPortX509());
201   - bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias()));
202   - break;
203   - default:
204   - break;
  185 + /**
  186 + * @param bootstrapServerIs
  187 + * @param mode
  188 + * @return ServerSecurityConfig more value is default: Important - port, host, publicKey
  189 + */
  190 + private ServerSecurityConfig getBootstrapServer ( boolean bootstrapServerIs, LwM2MSecurityMode mode){
  191 + ServerSecurityConfig bsServ = new ServerSecurityConfig();
  192 + bsServ.setBootstrapServerIs(bootstrapServerIs);
  193 + if (bootstrapServerIs) {
  194 + bsServ.setServerId(contextBootStrap.getBootstrapServerId());
  195 + switch (mode) {
  196 + case NO_SEC:
  197 + bsServ.setHost(contextBootStrap.getBootstrapHost());
  198 + bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk());
  199 + bsServ.setServerPublicKey("");
  200 + break;
  201 + case PSK:
  202 + bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
  203 + bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk());
  204 + bsServ.setServerPublicKey("");
  205 + break;
  206 + case RPK:
  207 + bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
  208 + bsServ.setPort(contextBootStrap.getBootstrapSecurePortRpk());
  209 + bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY()));
  210 + break;
  211 + case X509:
  212 + bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
  213 + bsServ.setPort(contextBootStrap.getBootstrapSecurePortX509());
  214 + bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias()));
  215 + break;
  216 + default:
  217 + break;
  218 + }
  219 + } else {
  220 + bsServ.setServerId(contextServer.getServerId());
  221 + switch (mode) {
  222 + case NO_SEC:
  223 + bsServ.setHost(contextServer.getServerHost());
  224 + bsServ.setPort(contextServer.getServerPortNoSecPsk());
  225 + bsServ.setServerPublicKey("");
  226 + break;
  227 + case PSK:
  228 + bsServ.setHost(contextServer.getServerSecureHost());
  229 + bsServ.setPort(contextServer.getServerPortPsk());
  230 + bsServ.setServerPublicKey("");
  231 + break;
  232 + case RPK:
  233 + bsServ.setHost(contextServer.getServerSecureHost());
  234 + bsServ.setPort(contextServer.getServerPortRpk());
  235 + bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY()));
  236 + break;
  237 + case X509:
  238 + bsServ.setHost(contextServer.getServerSecureHost());
  239 + bsServ.setPort(contextServer.getServerPortX509());
  240 + bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias()));
  241 + break;
  242 + default:
  243 + break;
  244 + }
205 245 }
  246 + return bsServ;
206 247 }
207   - return bsServ;
208   - }
209 248
210   - /**
211   - *
212   - * @param alias
213   - * @return PublicKey format HexString or null
214   - */
215   - private String getServerPublicKeyX509 (String alias) {
216   - try {
217   - X509Certificate serverCertificate = (X509Certificate) contextServer.getKeyStoreValue().getCertificate(alias);
218   - return Hex.encodeHexString(serverCertificate.getEncoded());
219   - } catch (CertificateEncodingException | KeyStoreException e) {
220   - e.printStackTrace();
  249 + /**
  250 + * @param alias
  251 + * @return PublicKey format HexString or null
  252 + */
  253 + private String getServerPublicKeyX509 (String alias){
  254 + try {
  255 + X509Certificate serverCertificate = (X509Certificate) contextServer.getKeyStoreValue().getCertificate(alias);
  256 + return Hex.encodeHexString(serverCertificate.getEncoded());
  257 + } catch (CertificateEncodingException | KeyStoreException e) {
  258 + e.printStackTrace();
  259 + }
  260 + return null;
221 261 }
222   - return null;
223   - }
224 262
225   - /**
226   - *
227   - * @param publicServerX
228   - * @param publicServerY
229   - * @return PublicKey format HexString or null
230   - */
231   - private String getRPKPublicKey(String publicServerX, String publicServerY) {
232   - try {
233   - /** Get Elliptic Curve Parameter spec for secp256r1 */
234   - AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
235   - algoParameters.init(new ECGenParameterSpec("secp256r1"));
236   - ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
237   - if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) {
238   - /** Get point values */
239   - byte[] publicX = Hex.decodeHex(publicServerX.toCharArray());
240   - byte[] publicY = Hex.decodeHex(publicServerY.toCharArray());
241   - /** Create key specs */
242   - KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
243   - parameterSpec);
244   - /** Get keys */
245   - PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
246   - if (publicKey != null && publicKey.getEncoded().length > 0 ) {
247   - return Hex.encodeHexString(publicKey.getEncoded());
  263 + /**
  264 + * @param publicServerX
  265 + * @param publicServerY
  266 + * @return PublicKey format HexString or null
  267 + */
  268 + private String getRPKPublicKey (String publicServerX, String publicServerY){
  269 + try {
  270 + /** Get Elliptic Curve Parameter spec for secp256r1 */
  271 + AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
  272 + algoParameters.init(new ECGenParameterSpec("secp256r1"));
  273 + ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
  274 + if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) {
  275 + /** Get point values */
  276 + byte[] publicX = Hex.decodeHex(publicServerX.toCharArray());
  277 + byte[] publicY = Hex.decodeHex(publicServerY.toCharArray());
  278 + /** Create key specs */
  279 + KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
  280 + parameterSpec);
  281 + /** Get keys */
  282 + PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
  283 + if (publicKey != null && publicKey.getEncoded().length > 0) {
  284 + return Hex.encodeHexString(publicKey.getEncoded());
  285 + }
248 286 }
  287 + } catch (GeneralSecurityException | IllegalArgumentException e) {
  288 + log.error("[{}] Failed generate Server RPK for profile", e.getMessage());
  289 + throw new RuntimeException(e);
249 290 }
250   - } catch (GeneralSecurityException | IllegalArgumentException e) {
251   - log.error("[{}] Failed generate Server RPK for profile", e.getMessage());
252   - throw new RuntimeException(e);
  291 + return null;
253 292 }
254   - return null;
255 293 }
256   -}
257 294
... ...
... ... @@ -16,7 +16,11 @@
16 16 package org.thingsboard.server.common.data.lwm2m;
17 17
18 18 import lombok.Data;
  19 +import lombok.Getter;
  20 +import lombok.Setter;
19 21
  22 +@Setter
  23 +@Getter
20 24 @Data
21 25 public class LwM2mObject {
22 26 int id;
... ...
... ... @@ -23,6 +23,7 @@ import { PageData } from '@shared/models/page/page-data';
23 23 import { DeviceProfile, DeviceProfileInfo, DeviceTransportType } from '@shared/models/device.models';
24 24 import { isDefinedAndNotNull } from '@core/utils';
25 25 import { ObjectLwM2M, ServerSecurityConfig } from '@home/components/profile/device/lwm2m/profile-config.models';
  26 +import { SortOrder } from '@shared/models/page/sort-order';
26 27
27 28 @Injectable({
28 29 providedIn: 'root'
... ... @@ -31,7 +32,8 @@ export class DeviceProfileService {
31 32
32 33 constructor(
33 34 private http: HttpClient
34   - ) { }
  35 + ) {
  36 + }
35 37
36 38 public getDeviceProfiles(pageLink: PageLink, config?: RequestConfig): Observable<PageData<DeviceProfile>> {
37 39 return this.http.get<PageData<DeviceProfile>>(`/api/deviceProfiles${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config));
... ... @@ -41,8 +43,14 @@ export class DeviceProfileService {
41 43 return this.http.get<DeviceProfile>(`/api/deviceProfile/${deviceProfileId}`, defaultHttpOptionsFromConfig(config));
42 44 }
43 45
44   - public getLwm2mObjects(objectIds: number[], config?: RequestConfig): Observable<Array<ObjectLwM2M>> {
45   - return this.http.get<Array<ObjectLwM2M>>(`/api/lwm2m/deviceProfile/${objectIds}`, defaultHttpOptionsFromConfig(config));
  46 + public getLwm2mObjects(objectIds?: number[], searchText?: string, sortOrder?: SortOrder, config?: RequestConfig):
  47 + Observable<Array<ObjectLwM2M>> {
  48 + // tslint:disable-next-line:no-debugger
  49 + debugger;
  50 + return this.http.get<Array<ObjectLwM2M>>
  51 + (`/api/lwm2m/deviceProfile/?objectIds=${objectIds}&searchText=${searchText}&sortProperty=${sortOrder.property}
  52 + &sortOrder=${sortOrder.direction}`,
  53 + defaultHttpOptionsFromConfig(config));
46 54 }
47 55
48 56 public getLwm2mBootstrapSecurityInfo(securityMode: string, bootstrapServerIs: boolean,
... ...
... ... @@ -37,6 +37,7 @@ import { deepClone, isUndefined } from '@core/utils';
37 37 import { WINDOW } from '@core/services/window.service';
38 38 import { JsonObject } from '@angular/compiler-cli/ngcc/src/packages/entry_point';
39 39 import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined';
  40 +import { Direction, SortOrder } from '@shared/models/page/sort-order';
40 41
41 42 @Component({
42 43 selector: 'tb-profile-lwm2m-device-transport-configuration',
... ... @@ -128,7 +129,11 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
128 129 const modelValue = {objectIds: null, objectsList: []};
129 130 modelValue.objectIds = this.getObjectsFromJsonAllConfig();
130 131 if (modelValue.objectIds !== null) {
131   - this.deviceProfileService.getLwm2mObjects(modelValue.objectIds).subscribe(
  132 + const sortOrder = {
  133 + property: 'id',
  134 + direction: Direction.ASC
  135 + };
  136 + this.deviceProfileService.getLwm2mObjects(modelValue.objectIds, null, sortOrder).subscribe(
132 137 (objectsList) => {
133 138 modelValue.objectsList = objectsList;
134 139 this.updateWriteValue(modelValue);
... ...