Added new option for including Bootstrap Serer updates

This commit is contained in:
Sergey Tarnavskiy 2021-11-26 17:53:06 +02:00
parent bfd206fa5b
commit f9aab73e92
8 changed files with 80 additions and 5 deletions

View File

@ -29,6 +29,7 @@ public class Lwm2mDeviceProfileTransportConfiguration implements DeviceProfileTr
private static final long serialVersionUID = 6257277825459600068L; private static final long serialVersionUID = 6257277825459600068L;
private TelemetryMappingConfiguration observeAttr; private TelemetryMappingConfiguration observeAttr;
private boolean bootstrapServerUpdateEnable;
private List<LwM2MBootstrapServerCredential> bootstrap; private List<LwM2MBootstrapServerCredential> bootstrap;
private OtherConfiguration clientLwM2mSettings; private OtherConfiguration clientLwM2mSettings;

View File

@ -709,12 +709,16 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
private void validateLwm2mServersConfigOfBootstrapForClient(List<LwM2MBootstrapServerCredential> lwM2MBootstrapServersConfigurations) { private void validateLwm2mServersConfigOfBootstrapForClient(List<LwM2MBootstrapServerCredential> lwM2MBootstrapServersConfigurations) {
Set <String> uris = new HashSet<>(); Set <String> uris = new HashSet<>();
Set <Integer> shortServerIds = new HashSet<>();
for (LwM2MBootstrapServerCredential bootstrapServerCredential : lwM2MBootstrapServersConfigurations) { for (LwM2MBootstrapServerCredential bootstrapServerCredential : lwM2MBootstrapServersConfigurations) {
AbstractLwM2MBootstrapServerCredential serverConfig = (AbstractLwM2MBootstrapServerCredential) bootstrapServerCredential; AbstractLwM2MBootstrapServerCredential serverConfig = (AbstractLwM2MBootstrapServerCredential) bootstrapServerCredential;
String server = serverConfig.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server" + " shortServerId: " + serverConfig.getShortServerId() + ":"; String server = serverConfig.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server" + " shortServerId: " + serverConfig.getShortServerId() + ":";
if (serverConfig.getShortServerId() < 1 || serverConfig.getShortServerId() > 65534) { if (serverConfig.getShortServerId() < 1 || serverConfig.getShortServerId() > 65534) {
throw new DeviceCredentialsValidationException(server + " ShortServerId must not be less than 1 and more than 65534!"); throw new DeviceCredentialsValidationException(server + " ShortServerId must not be less than 1 and more than 65534!");
} }
if (!shortServerIds.add(serverConfig.getShortServerId())){
throw new DeviceCredentialsValidationException(server + " \"Short server Id\" value = " + serverConfig.getShortServerId() + ". This value must be a unique value for all servers!");
};
String uri = serverConfig.getHost() + ":" + serverConfig.getPort(); String uri = serverConfig.getHost() + ":" + serverConfig.getPort();
if (!uris.add(uri)){ if (!uris.add(uri)){
throw new DeviceCredentialsValidationException(server + " \"Host + port\" value = " + uri + ". This value must be a unique value for all servers!"); throw new DeviceCredentialsValidationException(server + " \"Host + port\" value = " + uri + ". This value must be a unique value for all servers!");

View File

@ -32,7 +32,7 @@
<button mat-raised-button color="primary" <button mat-raised-button color="primary"
type="button" type="button"
(click)="addServerConfig()"> (click)="addServerConfig()">
<span>{{ (isBootstrapAdded() ? 'device-profile.lwm2m.add-lwm2m-server-config' : <span>{{ ((isBootstrapAdded() || !isBootstrapServerUpdateEnableValue) ? 'device-profile.lwm2m.add-lwm2m-server-config' :
'device-profile.lwm2m.add-server-config') | translate}}</span> 'device-profile.lwm2m.add-server-config') | translate}}</span>
</button> </button>
</div> </div>

View File

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core';
import { import {
AbstractControl, AbstractControl,
ControlValueAccessor, ControlValueAccessor,
@ -57,6 +57,15 @@ export class Lwm2mBootstrapConfigServersComponent implements OnInit, ControlValu
@Input() @Input()
disabled: boolean; disabled: boolean;
public isBootstrapServerUpdateEnableValue: boolean;
@Input()
set isBootstrapServerUpdateEnable(value: boolean) {
this.isBootstrapServerUpdateEnableValue = value;
if (!value) {
this.removeBootstrapServerConfig();
}
}
private valueChangeSubscription: Subscription = null; private valueChangeSubscription: Subscription = null;
private propagateChange = (v: any) => { }; private propagateChange = (v: any) => { };
@ -138,7 +147,7 @@ export class Lwm2mBootstrapConfigServersComponent implements OnInit, ControlValu
} }
addServerConfig(): void { addServerConfig(): void {
const addDialogObs = this.isBootstrapAdded() ? of(false) : const addDialogObs = (this.isBootstrapAdded() || !this.isBootstrapServerUpdateEnableValue) ? of(false) :
this.matDialog.open<Lwm2mBootstrapAddConfigServerDialogComponent>(Lwm2mBootstrapAddConfigServerDialogComponent, { this.matDialog.open<Lwm2mBootstrapAddConfigServerDialogComponent>(Lwm2mBootstrapAddConfigServerDialogComponent, {
disableClose: true, disableClose: true,
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'] panelClass: ['tb-dialog', 'tb-fullscreen-dialog']
@ -178,6 +187,15 @@ export class Lwm2mBootstrapConfigServersComponent implements OnInit, ControlValu
return false; return false;
} }
private removeBootstrapServerConfig(): void {
if (this.bootstrapConfigServersFormGroup) {
const bootstrapServerIndex = this.serverConfigsFromArray().getRawValue().findIndex(server => server.bootstrapServerIs === true);
if (bootstrapServerIndex !== -1) {
this.serverConfigsFromArray().removeAt(bootstrapServerIndex);
}
}
}
private updateModel() { private updateModel() {
const serverConfigs: Array<ServerSecurityConfig> = this.serverConfigsFromArray().value; const serverConfigs: Array<ServerSecurityConfig> = this.serverConfigsFromArray().value;
this.propagateChange(serverConfigs); this.propagateChange(serverConfigs);

View File

@ -33,8 +33,12 @@
</mat-tab> </mat-tab>
<mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}"> <mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}">
<section [formGroup]="lwm2mDeviceProfileFormGroup"> <section [formGroup]="lwm2mDeviceProfileFormGroup">
<mat-checkbox formControlName="bootstrapServerUpdateEnable" style="margin-left:8px;margin-top:20px">
{{ 'device-profile.lwm2m.include-bootstrap-server' | translate }}
</mat-checkbox>
<section style="padding: 20px 2px"> <section style="padding: 20px 2px">
<tb-profile-lwm2m-bootstrap-config-servers formControlName="bootstrap"> <tb-profile-lwm2m-bootstrap-config-servers formControlName="bootstrap"
[isBootstrapServerUpdateEnable]="isBootstrapServerUpdateEnable">
</tb-profile-lwm2m-bootstrap-config-servers> </tb-profile-lwm2m-bootstrap-config-servers>
</section> </section>
</section> </section>

View File

@ -52,6 +52,8 @@ import _ from 'lodash';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Lwm2mSecurityType } from '@shared/models/lwm2m-security-config.models'; import { Lwm2mSecurityType } from '@shared/models/lwm2m-security-config.models';
import { DialogService } from '@core/services/dialog.service';
import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
selector: 'tb-profile-lwm2m-device-transport-configuration', selector: 'tb-profile-lwm2m-device-transport-configuration',
@ -72,6 +74,7 @@ import { Lwm2mSecurityType } from '@shared/models/lwm2m-security-config.models';
export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, Validator, OnDestroy { export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, Validator, OnDestroy {
public disabled = false; public disabled = false;
public isBootstrapServerUpdateEnable: boolean;
private requiredValue: boolean; private requiredValue: boolean;
private destroy$ = new Subject(); private destroy$ = new Subject();
@ -94,12 +97,15 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
private propagateChange = (v: any) => { private propagateChange = (v: any) => {
} }
constructor(private fb: FormBuilder, constructor(public translate: TranslateService,
private fb: FormBuilder,
private cd: ChangeDetectorRef, private cd: ChangeDetectorRef,
private dialogService: DialogService,
private deviceProfileService: DeviceProfileService) { private deviceProfileService: DeviceProfileService) {
this.lwm2mDeviceProfileFormGroup = this.fb.group({ this.lwm2mDeviceProfileFormGroup = this.fb.group({
objectIds: [null], objectIds: [null],
observeAttrTelemetry: [null], observeAttrTelemetry: [null],
bootstrapServerUpdateEnable: [false],
bootstrap: [[]], bootstrap: [[]],
clientLwM2mSettings: this.fb.group({ clientLwM2mSettings: this.fb.group({
clientOnlyObserveAfterConnect: [1, []], clientOnlyObserveAfterConnect: [1, []],
@ -114,6 +120,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
compositeOperationsSupport: [false] compositeOperationsSupport: [false]
}) })
}); });
this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').valueChanges.pipe( this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').valueChanges.pipe(
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((fwStrategy) => { ).subscribe((fwStrategy) => {
@ -125,6 +132,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
.reset(DEFAULT_FW_UPDATE_RESOURCE, {emitEvent: false}); .reset(DEFAULT_FW_UPDATE_RESOURCE, {emitEvent: false});
} }
}); });
this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').valueChanges.pipe( this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').valueChanges.pipe(
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((swStrategy) => { ).subscribe((swStrategy) => {
@ -136,6 +144,39 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
.reset(DEFAULT_SW_UPDATE_RESOURCE, {emitEvent: false}); .reset(DEFAULT_SW_UPDATE_RESOURCE, {emitEvent: false});
} }
}); });
this.lwm2mDeviceProfileFormGroup.get('bootstrapServerUpdateEnable').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe((value) => {
if (!value) {
const bootstrap = this.lwm2mDeviceProfileFormGroup.get('bootstrap').value;
const bootstrapResultArray = bootstrap.filter(server => server.bootstrapServerIs === true);
if (bootstrapResultArray.length) {
this.dialogService.confirm(
this.translate.instant('device-profile.lwm2m.bootstrap-update-title'),
this.translate.instant('device-profile.lwm2m.bootstrap-update-text'),
this.translate.instant('action.no'),
this.translate.instant('action.yes'),
).pipe(
takeUntil(this.destroy$)
).subscribe((result) => {
if (result) {
this.isBootstrapServerUpdateEnable = value;
} else {
this.lwm2mDeviceProfileFormGroup.patchValue({
bootstrapServerUpdateEnable: true
}, {emitEvent: true});
}
this.cd.markForCheck();
});
} else {
this.isBootstrapServerUpdateEnable = value;
}
} else {
this.isBootstrapServerUpdateEnable = value;
}
});
this.lwm2mDeviceProfileFormGroup.valueChanges.pipe( this.lwm2mDeviceProfileFormGroup.valueChanges.pipe(
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
@ -217,6 +258,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
objectIds: value, objectIds: value,
observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value), observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value),
bootstrap: this.configurationValue.bootstrap, bootstrap: this.configurationValue.bootstrap,
bootstrapServerUpdateEnable: this.configurationValue.bootstrapServerUpdateEnable || false,
clientLwM2mSettings: { clientLwM2mSettings: {
clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect,
fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy || 1, fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy || 1,
@ -232,6 +274,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
} }
}, },
{emitEvent: false}); {emitEvent: false});
this.isBootstrapServerUpdateEnable = this.configurationValue.bootstrapServerUpdateEnable || false;
if (!this.disabled) { if (!this.disabled) {
this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').updateValueAndValidity({onlySelf: true}); this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').updateValueAndValidity({onlySelf: true});
this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').updateValueAndValidity({onlySelf: true}); this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').updateValueAndValidity({onlySelf: true});
@ -261,6 +304,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
} }
this.configurationValue.bootstrap = config.bootstrap; this.configurationValue.bootstrap = config.bootstrap;
this.configurationValue.clientLwM2mSettings = config.clientLwM2mSettings; this.configurationValue.clientLwM2mSettings = config.clientLwM2mSettings;
this.configurationValue.bootstrapServerUpdateEnable = config.bootstrapServerUpdateEnable;
this.updateModel(); this.updateModel();
} }

View File

@ -148,6 +148,7 @@ export interface ServerSecurityConfigInfo extends ServerSecurityConfig {
export interface Lwm2mProfileConfigModels { export interface Lwm2mProfileConfigModels {
clientLwM2mSettings: ClientLwM2mSettings; clientLwM2mSettings: ClientLwM2mSettings;
observeAttr: ObservableAttributes; observeAttr: ObservableAttributes;
bootstrapServerUpdateEnable: boolean;
bootstrap: Array<ServerSecurityConfig>; bootstrap: Array<ServerSecurityConfig>;
} }

View File

@ -1348,6 +1348,9 @@
"binding-tooltip": "Tis is the list in the\"binding\" resource of the LwM2M server object - /1/x/7.\nIndicates the supported binding modes in the LwM2M Client.\nThis value SHOULD be the same as the value in the “Supported Binding and Modes” resource in the Device Object (/3/0/16).\nWhile multiple transports are supported, only one transport binding can be used during the entire Transport Session.\nAs an example, when UDP and SMS are both supported, the LwM2M Client and the LwM2M Server can choose to communicate either over UDP or SMS during the entire Transport Session.", "binding-tooltip": "Tis is the list in the\"binding\" resource of the LwM2M server object - /1/x/7.\nIndicates the supported binding modes in the LwM2M Client.\nThis value SHOULD be the same as the value in the “Supported Binding and Modes” resource in the Device Object (/3/0/16).\nWhile multiple transports are supported, only one transport binding can be used during the entire Transport Session.\nAs an example, when UDP and SMS are both supported, the LwM2M Client and the LwM2M Server can choose to communicate either over UDP or SMS during the entire Transport Session.",
"bootstrap-server": "Bootstrap Server", "bootstrap-server": "Bootstrap Server",
"lwm2m-server": "LwM2M Server", "lwm2m-server": "LwM2M Server",
"include-bootstrap-server": "Include Bootstrap Server updates",
"bootstrap-update-title": "You already have configured Bootstrap Server. Are you sure you want to exclude the updates?",
"bootstrap-update-text": "Be careful, after the confirmation the Bootstrap Server configuration data will become unrecoverable.",
"server-host": "Host", "server-host": "Host",
"server-host-required": "Host is required.", "server-host-required": "Host is required.",
"server-port": "Port", "server-port": "Port",