From 48e5aed0b628f98b009fc625d42869da08b02512 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jul 2022 14:33:18 +0300 Subject: [PATCH 001/158] Rate limits implementation --- .../home/components/home-components.module.ts | 16 +- ...enant-profile-configuration.component.html | 118 +++++-------- ...-tenant-profile-configuration.component.ts | 3 + .../rate-limits-details-dialog.component.html | 52 ++++++ .../rate-limits-details-dialog.component.ts | 83 +++++++++ .../rate-limits-list.component.html | 61 +++++++ .../rate-limits-list.component.scss | 47 +++++ .../rate-limits/rate-limits-list.component.ts | 161 ++++++++++++++++++ .../rate-limits-text.component.html | 19 +++ .../rate-limits-text.component.scss | 49 ++++++ .../rate-limits/rate-limits-text.component.ts | 98 +++++++++++ .../rate-limits/rate-limits.component.html | 34 ++++ .../rate-limits/rate-limits.component.scss | 31 ++++ .../rate-limits/rate-limits.component.ts | 153 +++++++++++++++++ .../app/shared/models/rate-limits.models.ts | 137 +++++++++++++++ .../assets/locale/locale.constant-en_US.json | 36 +++- 16 files changed, 1018 insertions(+), 80 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts create mode 100644 ui-ngx/src/app/shared/models/rate-limits.models.ts diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index d195137509..9468289df8 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -166,6 +166,10 @@ import { EntityTypesVersionLoadComponent } from '@home/components/vc/entity-type import { ComplexVersionLoadComponent } from '@home/components/vc/complex-version-load.component'; import { RemoveOtherEntitiesConfirmComponent } from '@home/components/vc/remove-other-entities-confirm.component'; import { AutoCommitSettingsComponent } from '@home/components/vc/auto-commit-settings.component'; +import { RateLimitsListComponent } from '@home/components/profile/tenant/rate-limits/rate-limits-list.component'; +import { RateLimitsComponent } from '@home/components/profile/tenant/rate-limits/rate-limits.component'; +import { RateLimitsTextComponent } from '@home/components/profile/tenant/rate-limits/rate-limits-text.component'; +import { RateLimitsDetailsDialogComponent } from '@home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component'; @NgModule({ declarations: @@ -302,7 +306,11 @@ import { AutoCommitSettingsComponent } from '@home/components/vc/auto-commit-set EntityTypesVersionLoadComponent, ComplexVersionLoadComponent, RemoveOtherEntitiesConfirmComponent, - AutoCommitSettingsComponent + AutoCommitSettingsComponent, + RateLimitsListComponent, + RateLimitsComponent, + RateLimitsTextComponent, + RateLimitsDetailsDialogComponent ], imports: [ CommonModule, @@ -432,7 +440,11 @@ import { AutoCommitSettingsComponent } from '@home/components/vc/auto-commit-set EntityTypesVersionLoadComponent, ComplexVersionLoadComponent, RemoveOtherEntitiesConfirmComponent, - AutoCommitSettingsComponent + AutoCommitSettingsComponent, + RateLimitsListComponent, + RateLimitsComponent, + RateLimitsTextComponent, + RateLimitsDetailsDialogComponent ], providers: [ WidgetComponentService, diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html index 0e1553806a..5484aaed28 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html @@ -418,38 +418,24 @@
- Rate limits + + {{ 'tenant-profile.rate-limits.rate-limits' | translate }} +
- - tenant-profile.transport-tenant-msg-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - - - tenant-profile.transport-device-msg-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - + + + +
- - tenant-profile.transport-tenant-telemetry-msg-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - - - tenant-profile.transport-device-telemetry-msg-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - + + + +
@@ -459,40 +445,28 @@
- - tenant-profile.transport-tenant-telemetry-data-points-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - - - tenant-profile.transport-device-telemetry-data-points-rate-limit - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - + + + +
- - tenant-profile.tenant-rest-limits - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - - - tenant-profile.customer-rest-limits - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - + + + + +
+
+ + + +
@@ -503,22 +477,12 @@ tenant-profile.tenant-entity-import-rate-limit -
-
- - tenant-profile.ws-limit-updates-per-session - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - - - tenant-profile.cassandra-tenant-limits-configuration - - - {{ 'tenant-profile.incorrect-pattern-for-rate-limits' | translate}} - - +
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts index 65f030a3a6..ac2702ca43 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts @@ -21,6 +21,7 @@ import { AppState } from '@app/core/core.state'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { DefaultTenantProfileConfiguration, TenantProfileConfiguration } from '@shared/models/tenant.model'; import { isDefinedAndNotNull } from '@core/utils'; +import { RateLimitsType } from '@shared/models/rate-limits.models'; @Component({ selector: 'tb-default-tenant-profile-configuration', @@ -49,6 +50,8 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA @Input() disabled: boolean; + rateLimitsType = RateLimitsType; + private propagateChange = (v: any) => { }; constructor(private store: Store, diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html new file mode 100644 index 0000000000..911b44ecd8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html @@ -0,0 +1,52 @@ + +
+ +

{{ title }}

+ + +
+ + +
+
+
+ + +
+
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts new file mode 100644 index 0000000000..69bf5cda4f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts @@ -0,0 +1,83 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; +import { ErrorStateMatcher } from '@angular/material/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms'; +import { Router } from '@angular/router'; +import { DialogComponent } from '@app/shared/components/dialog.component'; +import { TranslateService } from '@ngx-translate/core'; + +export interface RateLimitsDetailsDialogData { + rateLimits: string; + title: string; + readonly: boolean; +} + +@Component({ + templateUrl: './rate-limits-details-dialog.component.html', + providers: [{provide: ErrorStateMatcher, useExisting: RateLimitsDetailsDialogComponent}] +}) +export class RateLimitsDetailsDialogComponent extends DialogComponent + implements OnInit, ErrorStateMatcher { + + editDetailsFormGroup: FormGroup; + + submitted: boolean = false; + + rateLimits: string = this.data.rateLimits; + + title: string = this.data.title; + + constructor(protected store: Store, + protected router: Router, + @Inject(MAT_DIALOG_DATA) public data: RateLimitsDetailsDialogData, + @SkipSelf() private errorStateMatcher: ErrorStateMatcher, + public dialogRef: MatDialogRef, + private fb: FormBuilder, + public translate: TranslateService) { + super(store, router, dialogRef); + + this.editDetailsFormGroup = this.fb.group({ + rateLimits: [this.rateLimits, []] + }); + if (this.data.readonly) { + this.editDetailsFormGroup.disable(); + } + } + + ngOnInit(): void { + } + + isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { + const originalErrorState = this.errorStateMatcher.isErrorState(control, form); + const customErrorState = !!(control && control.invalid && this.submitted); + return originalErrorState || customErrorState; + } + + cancel(): void { + this.dialogRef.close(null); + } + + save(): void { + this.submitted = true; + this.dialogRef.close(this.editDetailsFormGroup.get('rateLimits').value); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html new file mode 100644 index 0000000000..c0923927d8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html @@ -0,0 +1,61 @@ + +
+
+
+ tenant-profile.rate-limits.but-less-than +
+
+ + tenant-profile.rate-limits.number-of-messages + + + {{ 'tenant-profile.rate-limits.number-of-messages-required' | translate }} + + + + tenant-profile.rate-limits.per-seconds + + + {{ 'tenant-profile.rate-limits.per-seconds-required' | translate }} + + + +
+
+
+ +
+
+ tenant-profile.rate-limits.preview +
+ +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss new file mode 100644 index 0000000000..0db3694166 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss @@ -0,0 +1,47 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + button { + min-width: 40px; + mat-icon { + margin-top: 0.6em; + } + } + .tb-rate-limits-preview { + margin-top: 1.5em; + span { + padding-left: 1em; + } + div { + border: 1px groove rgba(0, 0, 0, .25); + border-radius: 4px; + padding: 1em; + } + } + .tb-rate-limits-operation { + font-size: 12px; + color: rgba(0,0,0,.54); + margin-bottom: 16px; + } +} + +:host ::ng-deep { + mat-form-field { + .mat-form-field-wrapper { + padding-bottom: 1em; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts new file mode 100644 index 0000000000..eb7a37cfde --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts @@ -0,0 +1,161 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + FormArray, + FormBuilder, + FormControl, + FormGroup, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + ValidationErrors, + Validator, + Validators +} from '@angular/forms'; +import { Subscription } from 'rxjs'; +import { + RateLimits, + rateLimitsArrayToString, + stringToRateLimitsArray +} from '@shared/models/rate-limits.models'; +import { isDefinedAndNotNull } from '@core/utils'; + +@Component({ + selector: 'tb-rate-limits-list', + templateUrl: './rate-limits-list.component.html', + styleUrls: ['./rate-limits-list.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RateLimitsListComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => RateLimitsListComponent), + multi: true + } + ] +}) +export class RateLimitsListComponent implements ControlValueAccessor, Validator, OnInit { + + @Input() disabled: boolean; + + rateLimitsListFormGroup: FormGroup; + + rateLimitsControl: FormControl; + + private propagateChange = (v: any) => { }; + + private valueChangeSubscription: Subscription = null; + + constructor(private fb: FormBuilder) { + } + + ngOnInit(): void { + this.rateLimitsListFormGroup = this.fb.group({}); + this.rateLimitsListFormGroup.addControl('rateLimits', + this.fb.array([])); + this.rateLimitsControl = this.fb.control(null); + this.rateLimitsListFormGroup.valueChanges.subscribe((value) => { + this.updateView(value?.rateLimits); + } + ); + } + + rateLimitsFormArray(): FormArray { + return this.rateLimitsListFormGroup.get('rateLimits') as FormArray; + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState?(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.rateLimitsListFormGroup.disable({emitEvent: false}); + this.rateLimitsControl.disable({emitEvent: false}); + } else { + this.rateLimitsListFormGroup.enable({emitEvent: false}); + this.rateLimitsControl.enable({emitEvent: false}); + } + } + + validate(): ValidationErrors | null { + return this.rateLimitsListFormGroup.valid && this.rateLimitsControl.valid ? null : { + rateLimitsList: {valid: false} + }; + } + + writeValue(value: string) { + if (this.valueChangeSubscription) { + this.valueChangeSubscription.unsubscribe(); + } + const rateLimitsControls: Array = []; + if (value) { + let rateLimitsArray = value.split(','); + for (let i = 0; i < rateLimitsArray.length; i++) { + let valueTime = rateLimitsArray[i].split(':'); + let value = valueTime[0]; + let time = valueTime[1]; + const rateLimitsControl = this.fb.group({ + value: [value, [Validators.required]], + time: [time, [Validators.required]] + }); + if (this.disabled) { + rateLimitsControl.disable(); + } + rateLimitsControls.push(rateLimitsControl); + } + } + this.rateLimitsListFormGroup.setControl('rateLimits', this.fb.array(rateLimitsControls)); + this.rateLimitsControl.patchValue(stringToRateLimitsArray(value), {emitEvent: false}); + this.valueChangeSubscription = this.rateLimitsListFormGroup.valueChanges.subscribe((value) => { + this.updateView(value?.rateLimits); + }); + } + + public removeRateLimits(index: number) { + (this.rateLimitsListFormGroup.get('rateLimits') as FormArray).removeAt(index); + } + + public addRateLimits() { + const rateLimitsArray = this.rateLimitsListFormGroup.get('rateLimits') as FormArray; + rateLimitsArray.push(this.fb.group({ + value: [null, [Validators.required]], + time: [null, [Validators.required]] + })); + this.rateLimitsListFormGroup.updateValueAndValidity(); + } + + updateView(rateLimitsArray: Array) { + if (rateLimitsArray.length > 0) { + const notNullRateLimits = rateLimitsArray.filter(rateLimits => isDefinedAndNotNull(rateLimits.value) && isDefinedAndNotNull(rateLimits.time)); + const rateLimitsString = rateLimitsArrayToString(notNullRateLimits); + this.propagateChange(rateLimitsString); + this.rateLimitsControl.patchValue(stringToRateLimitsArray(rateLimitsString), {emitEvent: false}); + } else { + this.propagateChange(null); + this.rateLimitsControl.patchValue(null, {emitEvent: false}); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html new file mode 100644 index 0000000000..98a30b055e --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html @@ -0,0 +1,19 @@ + +
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss new file mode 100644 index 0000000000..a8f8f8553f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss @@ -0,0 +1,49 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + .tb-rate-limits-text { + overflow: hidden; + + &.disabled { + opacity: 0.7; + } + &.required { + color: #f44336; + padding: 0 4px; + } + &.nowrap { + white-space: nowrap; + overflow: hidden; + } + } +} + +:host ::ng-deep { + .tb-rate-limits-text { + span { + font-size: 14px; + line-height: 1.8em; + } + .tb-rate-limits-value { + font-weight: bold; + border: 1px groove rgba(0, 0, 0, .25); + border-radius: 4px; + padding-left: 4px; + padding-right: 4px; + color: #305680; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts new file mode 100644 index 0000000000..9ab7e9b56b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts @@ -0,0 +1,98 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { RateLimits, rateLimitsArrayToHtml } from '@shared/models/rate-limits.models'; + +@Component({ + selector: 'tb-rate-limits-text', + templateUrl: './rate-limits-text.component.html', + styleUrls: ['./rate-limits-text.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RateLimitsTextComponent), + multi: true + } + ] +}) +export class RateLimitsTextComponent implements ControlValueAccessor, OnInit { + + private requiredValue: boolean; + get required(): boolean { + return this.requiredValue; + } + @Input() + set required(value: boolean) { + this.requiredValue = coerceBooleanProperty(value); + } + + @Input() + disabled: boolean; + + @Input() + noRateLimitsText = this.translate.instant('tenant-profile.rate-limits.not-set'); + + @Input() + nowrap = false; + + requiredClass = false; + + public rateLimitsText: string; + + private propagateChange = (v: any) => { }; + + constructor(private dialog: MatDialog, + private fb: FormBuilder, + private translate: TranslateService) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + ngOnInit() { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + } + + writeValue(value: Array): void { + this.updateText(value); + } + + private updateText(value: Array) { + this.requiredClass = false; + if (value && value.length) { + this.rateLimitsText = rateLimitsArrayToHtml(this.translate, value); + } else { + if (this.required && !this.disabled) { + this.requiredClass = true; + } else { + this.rateLimitsText = this.noRateLimitsText; + } + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html new file mode 100644 index 0000000000..3f1b698553 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html @@ -0,0 +1,34 @@ + +
+
+ {{ label | translate }} +
+ +
+
+
+ +
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss new file mode 100644 index 0000000000..6d45b33b73 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + padding: 12px 0 12px 0; + + .fieldset-element { + cursor: pointer; + padding: 0.5em; + border: 1px groove rgba(0, 0, 0, 0.25); + border-radius: 4px; + width: 100%; + + .legend-element { + color: rgba(0, 0, 0, 0.54); + font-size: 12px; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts new file mode 100644 index 0000000000..34cbadb755 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts @@ -0,0 +1,153 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + FormBuilder, + FormControl, + FormGroup, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + Validator +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { + RateLimitsDetailsDialogComponent, + RateLimitsDetailsDialogData +} from '@home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component'; +import { + addRateLimitTranslationMap, + editRateLimitTranslationMap, + rateLimitLabelTranslationMap, + RateLimitsType, + stringToRateLimitsArray +} from '@shared/models/rate-limits.models'; + +@Component({ + selector: 'tb-rate-limits', + templateUrl: './rate-limits.component.html', + styleUrls: ['./rate-limits.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RateLimitsComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => RateLimitsComponent), + multi: true, + } + ] +}) +export class RateLimitsComponent implements ControlValueAccessor, OnInit, Validator { + + @Input() + disabled: boolean; + + @Input() + type: RateLimitsType; + + label: string; + + rateLimitsFormGroup: FormGroup; + + private modelValue: string; + + private propagateChange = null; + + constructor(private dialog: MatDialog, + private fb: FormBuilder) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + ngOnInit() { + this.label = rateLimitLabelTranslationMap.get(this.type); + this.rateLimitsFormGroup = this.fb.group({ + rateLimits: [null, []] + }); + } + + setDisabledState(isDisabled: boolean) { + this.disabled = isDisabled; + if (this.disabled) { + this.rateLimitsFormGroup.disable({emitEvent: false}); + } else { + this.rateLimitsFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: string) { + this.modelValue = value; + this.updateRateLimitsInfo(); + } + + public validate(c: FormControl) { + return null; + } + + public onClick($event: Event, action: string) { + if ($event) { + $event.stopPropagation(); + } + const title = this.setTitle(action); + this.dialog.open(RateLimitsDetailsDialogComponent, { + disableClose: true, + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], + data: { + rateLimits: this.modelValue, + title, + readonly: this.disabled + } + }).afterClosed().subscribe((result) => { + if (result) { + this.modelValue = result; + this.updateModel(); + } + }); + } + + private setTitle(action: string): string { + switch (action) { + case 'add': + return addRateLimitTranslationMap.get(this.type); + case 'edit': + return editRateLimitTranslationMap.get(this.type); + } + } + + private updateRateLimitsInfo() { + this.rateLimitsFormGroup.patchValue( + { + rateLimits: stringToRateLimitsArray(this.modelValue) + } + ); + } + + private updateModel() { + this.updateRateLimitsInfo(); + this.propagateChange(this.modelValue); + } + +} diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts new file mode 100644 index 0000000000..8b8eae794a --- /dev/null +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -0,0 +1,137 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { TranslateService } from '@ngx-translate/core'; + +export interface RateLimits { + value: string; + time: string; +} + +export enum RateLimitsType { + DEVICE_MESSAGES = 'DEVICE_MESSAGES', + DEVICE_TELEMETRY_MESSAGES = 'DEVICE_TELEMETRY_MESSAGES', + DEVICE_TELEMETRY_DATA_POINTS = 'DEVICE_TELEMETRY_DATA_POINTS', + TENANT_MESSAGES = 'TENANT_MESSAGES', + TENANT_TELEMETRY_MESSAGES = 'TENANT_TELEMETRY_MESSAGES', + TENANT_TELEMETRY_DATA_POINTS = 'TENANT_TELEMETRY_DATA_POINTS', + TENANT_SERVER_REST_LIMITS_CONFIGURATION = 'TENANT_SERVER_REST_LIMITS_CONFIGURATION', + CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION = 'CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION', + WS_UPDATE_PER_SESSION_RATE_LIMIT = 'WS_UPDATE_PER_SESSION_RATE_LIMIT', + CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION = 'CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION', +} + +export const rateLimitLabelTranslationMap = new Map( + [ + [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.transport-tenant-msg'], + [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.transport-tenant-telemetry-msg'], + [RateLimitsType.TENANT_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.transport-tenant-telemetry-data-points'], + [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.transport-device-msg'], + [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.transport-device-telemetry-msg'], + [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.transport-device-telemetry-data-points'], + [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.transport-tenant-msg-rate-limit'], + [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.customer-rest-limits'], + [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.ws-limit-updates-per-session'], + [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.cassandra-tenant-limits-configuration'], + ] +); + +export const editRateLimitTranslationMap = new Map( + [ + [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-msg-title'], + [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-telemetry-msg-title'], + [RateLimitsType.TENANT_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.edit-transport-tenant-telemetry-data-points-title'], + [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.edit-transport-device-msg-title'], + [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.edit-transport-device-telemetry-msg-title'], + [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + ] +); + +export const addRateLimitTranslationMap = new Map( + [ + [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.add-transport-tenant-msg-title'], + [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.add-transport-tenant-telemetry-msg-title'], + [RateLimitsType.TENANT_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.add-transport-tenant-telemetry-data-points-title'], + [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-msg-title'], + [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-telemetry-msg-title'], + [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + ] +); + +export function stringToRateLimitsArray(rateLimits: string): Array { + const result: Array = []; + if (rateLimits?.length > 0) { + let rateLimitsArrays = rateLimits.split(','); + for (let i = 0; i < rateLimitsArrays.length; i++) { + let valueTime = rateLimitsArrays[i].split(':'); + let value = valueTime[0]; + let time = valueTime[1]; + const rateLimitControl = { + value, + time + } + result.push(rateLimitControl); + } + } + return result; +} + +export function rateLimitsArrayToString(rateLimits: Array): string { + let result = ''; + for (let i = 0; i < rateLimits.length; i++) { + result = result.concat(rateLimits[i].value, ':', rateLimits[i].time); + if ((rateLimits.length > 1) && (i !== rateLimits.length - 1)) { + result = result.concat(','); + } + } + return result; +} + +export function rateLimitsArrayToHtml(translate: TranslateService, rateLimitsArray: Array): string { + const rateLimitsHtml = rateLimitsArray.map((rateLimits, index) => { + const isLast: boolean = index === rateLimitsArray.length-1; + return rateLimitsToHtml(translate, rateLimits, isLast); + }); + let result: string; + if (rateLimitsHtml.length > 1) { + const butLessThanText = translate.instant('tenant-profile.rate-limits.but-less-than'); + result = rateLimitsHtml.join(' ' + butLessThanText + ' '); + } else { + result = rateLimitsHtml[0]; + } + return result; +} + +function rateLimitsToHtml(translate: TranslateService, rateLimit: RateLimits, isLast: boolean): string { + const value = rateLimit.value; + const time = rateLimit.time; + const operation = translate.instant('tenant-profile.rate-limits.messages-per'); + const seconds = translate.instant('tenant-profile.rate-limits.sec'); + const comma = isLast ? '' : ','; + const result = `${value} + ${operation} + ${time} + ${seconds}${comma}
`; + return result; +} diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 6e76448847..4e83984480 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3187,7 +3187,41 @@ "ws-limit-max-subscriptions-per-customer": "Subscriptions per customer maximum number", "ws-limit-max-subscriptions-per-regular-user": "Subscriptions per regular user maximum number", "ws-limit-max-subscriptions-per-public-user": "Subscriptions per public user maximum number", - "ws-limit-updates-per-session": "WS updates per session" + "ws-limit-updates-per-session": "WS updates per session", + "rate-limits": { + "add-limit": "Add limit", + "add-transport-tenant-msg-title": "Add transport tenant messages rate limit", + "add-transport-tenant-telemetry-msg-title": "Add transport tenant telemetry messages rate limit", + "add-transport-tenant-telemetry-data-points-title": "Add transport tenant telemetry data points rate limit", + "add-transport-device-msg-title": "Add transport device messages rate limit", + "add-transport-device-telemetry-msg-title": "Add transport device telemetry messages rate limit", + "add-transport-device-telemetry-data-points-title": "Add transport device telemetry data points rate limit", + "advanced-settings": "Advanced settings", + "edit-limit": "Edit limit", + "but-less-than": "but less than", + "edit-transport-tenant-msg-title": "Edit transport tenant messages rate limit", + "edit-transport-tenant-telemetry-msg-title": "Edit transport tenant telemetry messages rate limit", + "edit-transport-tenant-telemetry-data-points-title": "Edit transport tenant telemetry data points rate limit", + "edit-transport-device-msg-title": "Edit transport device messages rate limit", + "edit-transport-device-telemetry-msg-title": "Edit transport device telemetry messages rate limit", + "edit-transport-device-telemetry-data-points-title": "Edit transport device telemetry data points rate limit", + "messages-per": "messages per", + "not-set": "Not set", + "number-of-messages": "Number of messages", + "number-of-messages-required": "Number of messages is required.", + "preview": "Preview", + "per-seconds": "Per seconds", + "per-seconds-required": "Time rate is required.", + "rate-limits": "Rate limits", + "remove-limit": "Remove rate limit", + "transport-tenant-msg": "Transport tenant messages", + "transport-tenant-telemetry-msg": "Transport tenant telemetry messages", + "transport-tenant-telemetry-data-points": "Transport tenant telemetry data points", + "transport-device-msg": "Transport device messages", + "transport-device-telemetry-msg": "Transport device telemetry messages", + "transport-device-telemetry-data-points": "Transport device telemetry data points", + "sec": "sec" + } }, "timeinterval": { "seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }", From 97e46e18cbd1b14c315981e2d01ca353c21838a1 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jul 2022 14:47:31 +0300 Subject: [PATCH 002/158] Rate limits translations updated --- .../app/shared/models/rate-limits.models.ts | 16 ++++----- .../assets/locale/locale.constant-en_US.json | 34 ++++++++++++------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts index 8b8eae794a..e6b4218773 100644 --- a/ui-ngx/src/app/shared/models/rate-limits.models.ts +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -57,10 +57,10 @@ export const editRateLimitTranslationMap = new Map( [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.edit-transport-device-msg-title'], [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.edit-transport-device-telemetry-msg-title'], [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], - [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], - [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], - [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], - [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-device-telemetry-data-points-title'], + [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-transport-tenant-msg-rate-limit-title'], + [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-customer-rest-limits-title'], + [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.edit-ws-limit-updates-per-session-title'], + [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-cassandra-tenant-limits-configuration-title'], ] ); @@ -72,10 +72,10 @@ export const addRateLimitTranslationMap = new Map( [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-msg-title'], [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-telemetry-msg-title'], [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], - [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], - [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], - [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], - [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], + [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-tenant-msg-rate-limit-title'], + [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-customer-rest-limits-title'], + [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.add-ws-limit-updates-per-session-title'], + [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-cassandra-tenant-limits-configuration-title'], ] ); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 4e83984480..8cd65a139e 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3190,21 +3190,29 @@ "ws-limit-updates-per-session": "WS updates per session", "rate-limits": { "add-limit": "Add limit", - "add-transport-tenant-msg-title": "Add transport tenant messages rate limit", - "add-transport-tenant-telemetry-msg-title": "Add transport tenant telemetry messages rate limit", - "add-transport-tenant-telemetry-data-points-title": "Add transport tenant telemetry data points rate limit", - "add-transport-device-msg-title": "Add transport device messages rate limit", - "add-transport-device-telemetry-msg-title": "Add transport device telemetry messages rate limit", - "add-transport-device-telemetry-data-points-title": "Add transport device telemetry data points rate limit", + "add-transport-tenant-msg-title": "Add transport tenant messages rate limits", + "add-transport-tenant-telemetry-msg-title": "Add transport tenant telemetry messages rate limits", + "add-transport-tenant-telemetry-data-points-title": "Add transport tenant telemetry data points rate limits", + "add-transport-device-msg-title": "Add transport device messages rate limits", + "add-transport-device-telemetry-msg-title": "Add transport device telemetry messages rate limits", + "add-transport-device-telemetry-data-points-title": "Add transport device telemetry data points rate limits", + "add-transport-tenant-msg-rate-limit-title": "Add transport tenant messages rate limits", + "add-customer-rest-limits-title": "Add REST requests for customer rate limits", + "add-ws-limit-updates-per-session-title": "Add WS updates per session rate limits", + "add-cassandra-tenant-limits-configuration-title": "Add Cassandra query for tenant rate limits", "advanced-settings": "Advanced settings", "edit-limit": "Edit limit", "but-less-than": "but less than", - "edit-transport-tenant-msg-title": "Edit transport tenant messages rate limit", - "edit-transport-tenant-telemetry-msg-title": "Edit transport tenant telemetry messages rate limit", - "edit-transport-tenant-telemetry-data-points-title": "Edit transport tenant telemetry data points rate limit", - "edit-transport-device-msg-title": "Edit transport device messages rate limit", - "edit-transport-device-telemetry-msg-title": "Edit transport device telemetry messages rate limit", - "edit-transport-device-telemetry-data-points-title": "Edit transport device telemetry data points rate limit", + "edit-transport-tenant-msg-title": "Edit transport tenant messages rate limits", + "edit-transport-tenant-telemetry-msg-title": "Edit transport tenant telemetry messages rate limits", + "edit-transport-tenant-telemetry-data-points-title": "Edit transport tenant telemetry data points rate limits", + "edit-transport-device-msg-title": "Edit transport device messages rate limits", + "edit-transport-device-telemetry-msg-title": "Edit transport device telemetry messages rate limits", + "edit-transport-device-telemetry-data-points-title": "Edit transport device telemetry data points rate limits", + "edit-transport-tenant-msg-rate-limit-title": "Edit transport tenant messages rate limits", + "edit-customer-rest-limits-title": "Edit REST requests for customer rate limits", + "edit-ws-limit-updates-per-session-title": "Edit WS updates per session rate limits", + "edit-cassandra-tenant-limits-configuration-title": "Edit Cassandra query for tenant rate limits", "messages-per": "messages per", "not-set": "Not set", "number-of-messages": "Number of messages", @@ -3213,7 +3221,7 @@ "per-seconds": "Per seconds", "per-seconds-required": "Time rate is required.", "rate-limits": "Rate limits", - "remove-limit": "Remove rate limit", + "remove-limit": "Remove limit", "transport-tenant-msg": "Transport tenant messages", "transport-tenant-telemetry-msg": "Transport tenant telemetry messages", "transport-tenant-telemetry-data-points": "Transport tenant telemetry data points", From 5a43971fe8e43744b8cb521eb7635a0feb27bdd3 Mon Sep 17 00:00:00 2001 From: devaskim Date: Mon, 11 Jul 2022 17:09:46 +0500 Subject: [PATCH 003/158] Add 'Process no-data' option to widget's type parameters. --- .../widget/widget-component.service.ts | 3 +++ .../home/components/widget/widget.component.ts | 18 +++++++++--------- ui-ngx/src/app/shared/models/widget.models.ts | 1 + 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts index de88b73e3b..5b608d71ba 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts @@ -502,6 +502,9 @@ export class WidgetComponentService { if (isUndefined(result.typeParameters.stateData)) { result.typeParameters.stateData = false; } + if (isUndefined(result.typeParameters.processNoDataByWidget)) { + result.typeParameters.processNoDataByWidget = false; + } if (isFunction(widgetTypeInstance.actionSources)) { result.actionSources = widgetTypeInstance.actionSources(); } else { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 0506feb02d..1552d1356b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -399,17 +399,17 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI } private displayWidgetInstance(): boolean { - if (this.widget.type !== widgetType.static) { - for (const id of Object.keys(this.widgetContext.subscriptions)) { - const subscription = this.widgetContext.subscriptions[id]; - if (subscription.isDataResolved()) { - return true; - } - } - return false; - } else { + if (this.widget.type === widgetType.static || this.typeParameters?.processNoDataByWidget) { return true; } + + for (const id of Object.keys(this.widgetContext.subscriptions)) { + const subscription = this.widgetContext.subscriptions[id]; + if (subscription.isDataResolved()) { + return true; + } + } + return false; } private onDestroy() { diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 703cffcaee..688e1b05cd 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -159,6 +159,7 @@ export interface WidgetTypeParameters { singleEntity?: boolean; warnOnPageDataOverflow?: boolean; ignoreDataUpdateOnIntervalTick?: boolean; + processNoDataByWidget?: boolean; } export interface WidgetControllerDescriptor { From c7daaa571e3d7f497ef6b84feb4bfd56153fee99 Mon Sep 17 00:00:00 2001 From: thingsboard Date: Mon, 11 Jul 2022 17:49:33 +0300 Subject: [PATCH 004/158] replace StringUtils usages with in-repository implementation --- .../actors/ruleChain/DefaultTbContext.java | 2 +- ...tomOAuth2AuthorizationRequestResolver.java | 2 +- .../config/RateLimitProcessingFilter.java | 2 +- .../controller/AbstractRpcController.java | 2 +- .../server/controller/AlarmController.java | 2 +- .../server/controller/AuditLogController.java | 2 +- .../server/controller/BaseController.java | 2 +- .../ComponentDescriptorController.java | 2 +- .../controller/DeviceProfileController.java | 2 +- .../controller/TelemetryController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 2 +- .../service/action/EntityActionService.java | 8 +-- .../apiusage/DefaultRateLimitService.java | 2 +- .../DefaultTbApiUsageStateService.java | 2 +- .../device/ClaimDevicesServiceImpl.java | 2 +- .../device/DeviceBulkImportService.java | 2 +- .../device/DeviceProvisionServiceImpl.java | 2 +- .../fetch/AdminSettingsEdgeEventFetcher.java | 2 +- .../rpc/processor/DeviceEdgeProcessor.java | 2 +- .../DefaultTbEntityViewService.java | 2 +- .../service/install/DatabaseHelper.java | 2 +- .../service/install/InstallScripts.java | 2 +- .../install/SqlTsDatabaseUpgradeService.java | 2 +- .../TimescaleTsDatabaseUpgradeService.java | 2 +- .../CassandraTsLatestToSqlMigrateService.java | 2 +- .../update/DefaultDataUpdateService.java | 2 +- .../install/update/RateLimitsUpdater.java | 2 +- .../service/mail/DefaultMailService.java | 2 +- .../resource/DefaultTbResourceService.java | 2 +- .../script/RuleNodeJsScriptEngine.java | 2 +- .../jwt/RefreshTokenProcessingFilter.java | 2 +- .../extractor/JwtHeaderTokenExtractor.java | 2 +- .../jwt/extractor/JwtQueryTokenExtractor.java | 2 +- .../auth/mfa/DefaultTwoFactorAuthService.java | 2 +- .../oauth2/AbstractOAuth2ClientMapper.java | 2 +- .../auth/oauth2/AppleOAuth2ClientMapper.java | 2 +- .../auth/oauth2/BasicMapperUtils.java | 2 +- .../auth/oauth2/CustomOAuth2ClientMapper.java | 2 +- .../auth/rest/RestLoginProcessingFilter.java | 2 +- .../rest/RestPublicLoginProcessingFilter.java | 2 +- .../security/model/token/JwtTokenFactory.java | 2 +- .../model/token/OAuth2AppTokenFactory.java | 2 +- .../system/DefaultSystemSecurityService.java | 2 +- .../server/service/sms/aws/AwsSmsSender.java | 2 +- .../service/sms/smpp/SmppSmsSender.java | 2 +- .../service/sms/twilio/TwilioSmsSender.java | 2 +- .../state/DefaultDeviceStateService.java | 2 +- .../csv/AbstractBulkImportService.java | 2 +- .../DefaultTelemetryWebSocketService.java | 2 +- .../server/controller/AbstractWebTest.java | 2 +- .../server/controller/TwoFactorAuthTest.java | 2 +- .../service/sms/smpp/SmppSmsSenderTest.java | 2 +- ...tractCoapServerSideRpcIntegrationTest.java | 2 +- .../mqtt/AbstractMqttIntegrationTest.java | 2 +- ...tractMqttServerSideRpcIntegrationTest.java | 2 +- .../cache/TBRedisClusterConfiguration.java | 2 +- .../TbCoapDtlsCertificateVerifier.java | 2 +- .../dao/cassandra/CassandraDriverOptions.java | 2 +- common/data/pom.xml | 10 ++++ .../server/common/data/StringUtils.java | 50 +++++++++++++++++++ .../SnmpDeviceTransportConfiguration.java | 2 +- .../common/data/sync/vc/EntityLoadError.java | 2 +- .../data/transport/snmp/SnmpMapping.java | 2 +- .../thingsboard/server/common/msg/TbMsg.java | 2 +- .../DefaultTbServiceInfoProvider.java | 2 +- .../kafka/TbKafkaConsumerStatsService.java | 2 +- .../queue/kafka/TbKafkaProducerTemplate.java | 2 +- common/stats/pom.xml | 4 ++ .../common/stats/DefaultStatsFactory.java | 2 +- .../coap/adaptors/CoapAdaptorUtils.java | 2 +- .../coap/adaptors/JsonCoapAdaptor.java | 2 +- .../coap/adaptors/ProtoCoapAdaptor.java | 2 +- .../transport/http/DeviceApiController.java | 2 +- .../lwm2m/utils/LwM2MTransportUtil.java | 2 +- .../lwm2m/utils/LwM2mValueConverterImpl.java | 2 +- .../mqtt/MqttSslHandlerProvider.java | 2 +- .../transport/mqtt/MqttTransportHandler.java | 4 +- .../mqtt/adaptors/JsonMqttAdaptor.java | 2 +- .../mqtt/adaptors/ProtoMqttAdaptor.java | 2 +- .../mqtt/session/GatewaySessionHandler.java | 2 +- .../transport/adaptor/JsonConverter.java | 2 +- .../transport/adaptor/ProtoConverter.java | 2 +- .../DefaultTransportRateLimitService.java | 2 +- .../sync/vc/DefaultGitRepositoryService.java | 2 +- .../server/service/sync/vc/GitRepository.java | 2 +- .../server/dao/audit/AuditLogServiceImpl.java | 2 +- .../audit/sink/ElasticsearchAuditLogSink.java | 2 +- .../server/dao/event/BaseEventService.java | 2 +- .../dao/model/sql/AbstractAlarmEntity.java | 2 +- .../server/dao/model/sql/DashboardEntity.java | 2 +- .../dao/model/sql/DashboardInfoEntity.java | 2 +- .../model/sql/OAuth2RegistrationEntity.java | 2 +- .../timescale/ts/TimescaleTsKvEntity.java | 2 +- .../server/dao/oauth2/OAuth2ServiceImpl.java | 2 +- .../dao/relation/BaseRelationService.java | 2 +- .../server/dao/service/DataValidator.java | 2 +- .../validator/AdminSettingsDataValidator.java | 2 +- .../service/validator/AlarmDataValidator.java | 2 +- .../service/validator/AssetDataValidator.java | 2 +- ...ientRegistrationTemplateDataValidator.java | 2 +- .../ComponentDescriptorDataValidator.java | 2 +- .../validator/CustomerDataValidator.java | 2 +- .../validator/DashboardDataValidator.java | 2 +- .../validator/DeviceDataValidator.java | 2 +- .../service/validator/EdgeDataValidator.java | 2 +- .../validator/EntityViewDataValidator.java | 2 +- .../service/validator/EventDataValidator.java | 2 +- .../validator/ResourceDataValidator.java | 2 +- .../validator/RuleChainDataValidator.java | 2 +- .../validator/TenantDataValidator.java | 2 +- .../validator/TenantProfileDataValidator.java | 2 +- .../UserCredentialsDataValidator.java | 2 +- .../service/validator/UserDataValidator.java | 2 +- .../validator/WidgetTypeDataValidator.java | 2 +- .../validator/WidgetsBundleDataValidator.java | 2 +- .../server/dao/sql/device/JpaDeviceDao.java | 2 +- .../dao/sql/device/JpaDeviceProfileDao.java | 2 +- .../dao/sql/edge/JpaBaseEdgeEventDao.java | 2 +- .../server/dao/sql/event/JpaBaseEventDao.java | 2 +- .../dao/sql/query/AlarmDataAdapter.java | 2 +- .../query/DefaultAlarmQueryRepository.java | 2 +- .../query/DefaultEntityQueryRepository.java | 2 +- .../dao/sql/query/EntityKeyMapping.java | 2 +- .../AbstractCassandraBaseTimeseriesDao.java | 2 +- .../dao/timeseries/BaseTimeseriesService.java | 2 +- .../dao/service/BaseEntityServiceTest.java | 2 +- .../thingsboard/rest/client/RestClient.java | 2 +- .../rule/engine/api/util/TbNodeUtils.java | 2 +- .../rule/engine/aws/sqs/TbSqsNode.java | 2 +- .../credentials/CertPemCredentials.java | 2 +- .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../rule/engine/kafka/TbKafkaNode.java | 2 +- .../rule/engine/mail/TbMsgToEmailNode.java | 2 +- .../rule/engine/mail/TbSendEmailNode.java | 2 +- .../engine/metadata/TbGetTelemetryNode.java | 2 +- .../rule/engine/mqtt/TbMqttNode.java | 2 +- .../engine/mqtt/azure/TbAzureIotHubNode.java | 2 +- .../rule/engine/profile/AlarmState.java | 2 +- .../rule/engine/profile/DeviceState.java | 2 +- .../rule/engine/rabbitmq/TbRabbitMqNode.java | 2 +- .../rule/engine/rest/TbHttpClient.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNode.java | 2 +- .../rule/engine/rpc/TbSendRPCRequestNode.java | 2 +- .../rpc/TbSendRpcReplyNodeConfiguration.java | 2 +- .../engine/telemetry/TbMsgAttributesNode.java | 2 +- .../engine/telemetry/TbMsgTimeseriesNode.java | 2 +- .../tools/migrator/DictionaryParser.java | 2 +- .../client/tools/migrator/PgCaMigrator.java | 2 +- .../tools/migrator/RelatedEntitiesParser.java | 2 +- 149 files changed, 212 insertions(+), 152 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index 3538800d38..b4a7fef8ed 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.netty.channel.EventLoopGroup; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.RuleEngineAlarmService; diff --git a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java index bbeed33449..bc91eb9908 100644 --- a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java +++ b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java @@ -33,7 +33,7 @@ import org.springframework.security.web.util.UrlUtils; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import org.thingsboard.server.dao.oauth2.OAuth2Configuration; diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java index 86675a79a8..232419a57e 100644 --- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java @@ -16,7 +16,7 @@ package org.thingsboard.server.config; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.BadCredentialsException; diff --git a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java index 965975c0ee..e5a217893e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java @@ -22,10 +22,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 5003aac526..50a69c5b17 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -18,7 +18,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java index db78b87f70..dbe948c26c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java @@ -17,7 +17,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 7d2d2cd255..5e1bc74992 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -23,7 +23,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.support.DefaultMessageSourceResolvable; diff --git a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java index b8e5da25de..069e8eb9eb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java @@ -17,7 +17,7 @@ package org.thingsboard.server.controller; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index 08568a28ce..150e013f6d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -19,7 +19,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index b9c929f909..aa9717dd39 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -35,7 +35,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index 578bfa5662..09fab07faa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -16,7 +16,7 @@ package org.thingsboard.server.controller.plugin; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 39064c210c..2f18fb56c8 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -20,14 +20,10 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; + import org.springframework.stereotype.Service; import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; -import org.thingsboard.server.common.data.HasTenantId; -import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.*; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java index 55b23a99cc..01dade4d71 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultRateLimitService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.apiusage; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 7ccfd6fe4d..4971331047 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -19,7 +19,7 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java index 68c9e3117e..a397a4d0e9 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java @@ -27,13 +27,13 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java index 8b2126905f..92ae09fa3f 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java @@ -22,7 +22,7 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java index 7fd42740c4..201b0341fd 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java @@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java index ee10c7859b..e7be46e2d6 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java @@ -23,7 +23,7 @@ import freemarker.template.Configuration; import freemarker.template.Template; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.text.WordUtils; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.EdgeUtils; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index 0e1dee7132..b0e3536e92 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -23,7 +23,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java index e098d6b605..8de6ec9aac 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java @@ -59,7 +59,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; -import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.thingsboard.server.common.data.StringUtils.isBlank; @Service @AllArgsConstructor diff --git a/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java b/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java index 2cff9841da..fa702cc2c6 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.UUIDConverter; import org.thingsboard.server.common.data.id.CustomerId; diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index f193b10a62..b12dc2243d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java index c1d41a6f6e..1ac003db61 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.install; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.SystemUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java index 245dc4503d..4cfa23f278 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.install; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.SystemUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java index 142bacd7ff..84e9458c78 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.install.migrate; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 9bfa86b3ba..19ed7da65e 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -78,7 +78,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; -import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.thingsboard.server.common.data.StringUtils.isBlank; @Service @Profile("install") diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java b/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java index c136f97b52..52031b252b 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/RateLimitsUpdater.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.service.install.update; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java index aa8e019317..6db4d741d2 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode; import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index d83508220b..e9b4e849b4 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.resource; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.eclipse.leshan.core.model.DDFFileParser; import org.eclipse.leshan.core.model.DefaultDDFFileValidator; import org.eclipse.leshan.core.model.InvalidDDFFileException; diff --git a/application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java b/application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java index 4b2bcb99da..c90e104ff4 100644 --- a/application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java +++ b/application/src/main/java/org/thingsboard/server/service/script/RuleNodeJsScriptEngine.java @@ -22,7 +22,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java index 28794fc77e..2128ab0fa3 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.jwt; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java index b29164fb6b..4f8d9425a6 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.service.security.auth.jwt.extractor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.stereotype.Component; import org.thingsboard.server.config.ThingsboardSecurityConfiguration; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java index 17ed090807..129e865631 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.service.security.auth.jwt.extractor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.stereotype.Component; import org.thingsboard.server.config.ThingsboardSecurityConfiguration; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java index 0972b378eb..7657a81e66 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.security.auth.mfa; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.LockedException; import org.springframework.stereotype.Service; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java index ede9f8746a..9b7912c6a7 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.Tenant; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java index 77b9a94aaa..5021f72f68 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java @@ -21,7 +21,7 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2Registration; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java index 2185387520..e8e1011a47 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicMapperUtils.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.oauth2; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.text.StrSubstitutor; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; import org.thingsboard.server.dao.oauth2.OAuth2User; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java index 39438b997d..377a761b43 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java @@ -22,7 +22,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.client.RestTemplate; import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java index 2fcb2516df..8b42a0d140 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationServiceException; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java index 8c5fb15aee..83b5f78868 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java index a8e6f9cb5c..182bf58609 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java @@ -25,7 +25,7 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.GrantedAuthority; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java index 1b25ea9d87..485cfa5c97 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java @@ -22,7 +22,7 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; -import io.micrometer.core.instrument.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java index e399c14d04..887b4d346e 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.passay.CharacterRule; import org.passay.EnglishCharacterData; import org.passay.LengthRule; diff --git a/application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java b/application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java index 41601d9f1c..3221c56a85 100644 --- a/application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java +++ b/application/src/main/java/org/thingsboard/server/service/sms/aws/AwsSmsSender.java @@ -23,7 +23,7 @@ import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sns.model.MessageAttributeValue; import com.amazonaws.services.sns.model.PublishRequest; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.sms.config.AwsSnsSmsProviderConfiguration; import org.thingsboard.rule.engine.api.sms.exception.SmsException; import org.thingsboard.rule.engine.api.sms.exception.SmsSendException; diff --git a/application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java b/application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java index 57c5c5d25c..88c73490ba 100644 --- a/application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java +++ b/application/src/main/java/org/thingsboard/server/service/sms/smpp/SmppSmsSender.java @@ -16,7 +16,7 @@ package org.thingsboard.server.service.sms.smpp; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.smpp.Connection; import org.smpp.Data; diff --git a/application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java b/application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java index fb2fd0376b..eb187f2f31 100644 --- a/application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java +++ b/application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java @@ -18,7 +18,7 @@ package org.thingsboard.server.service.sms.twilio; import com.twilio.http.TwilioRestClient; import com.twilio.rest.api.v2010.account.Message; import com.twilio.type.PhoneNumber; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.sms.exception.SmsParseException; import org.thingsboard.server.common.data.sms.config.TwilioSmsProviderConfiguration; import org.thingsboard.rule.engine.api.sms.exception.SmsException; diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index d74b0fca87..b62e8a6c11 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -25,7 +25,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.cluster.TbClusterService; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java index becf92771f..43bf002d6c 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java @@ -20,7 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import lombok.Data; import lombok.SneakyThrows; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContext; diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java index 0551d7e114..acfed379f4 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java @@ -26,7 +26,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.socket.CloseStatus; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardThreadFactory; diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 677303cc15..19e78626f7 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -27,7 +27,7 @@ import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwts; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.hamcrest.Matcher; import org.junit.After; import org.junit.Assert; diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java index 9c30ebbbd0..6e99d15c8f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.jboss.aerogear.security.otp.Totp; import org.junit.After; import org.junit.Before; diff --git a/application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java b/application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java index 7cbc8c03d2..f7cc80d02d 100644 --- a/application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sms/smpp/SmppSmsSenderTest.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.service.sms.smpp; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Ignore; diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java index beb4d3747c..96eb92757c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java @@ -22,7 +22,7 @@ import com.google.protobuf.DynamicMessage; import com.google.protobuf.InvalidProtocolBufferException; import com.squareup.wire.schema.internal.parser.ProtoFileElement; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.eclipse.californium.core.CoapHandler; import org.eclipse.californium.core.CoapObserveRelation; import org.eclipse.californium.core.CoapResponse; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java index 9fbdff3fa5..4c07cec3d4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java @@ -23,7 +23,7 @@ import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.springframework.test.context.TestPropertySource; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java index 0abd0f1d6c..78c63b6fd2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -25,7 +25,7 @@ import com.nimbusds.jose.util.StandardCharset; import com.squareup.wire.schema.internal.parser.ProtoFileElement; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.thingsboard.common.util.JacksonUtil; diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java index 2cf67e35aa..f68dabf9eb 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.cache; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java index ce8b093b4d..15807c4154 100644 --- a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java +++ b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java @@ -27,7 +27,7 @@ import org.eclipse.californium.scandium.dtls.HandshakeException; import org.eclipse.californium.scandium.dtls.HandshakeResultHandler; import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; import org.eclipse.californium.scandium.util.ServerNames; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.msg.EncryptionUtil; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java index 986be6d515..3c6d8ce1dd 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java @@ -23,7 +23,7 @@ import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBui import com.datastax.oss.driver.api.core.metrics.DefaultSessionMetric; import com.datastax.oss.driver.api.core.metrics.DefaultNodeMetric; import lombok.Data; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; diff --git a/common/data/pom.xml b/common/data/pom.xml index 539dd0d9e3..50755115a0 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -108,6 +108,16 @@ de.ruedigermoeller fst + + org.eclipse.leshan + leshan-core + + + com.amazonaws + aws-java-sdk-core + 1.11.747 + compile + diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index f76757f522..4b916df30e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java @@ -17,9 +17,12 @@ package org.thingsboard.server.common.data; import com.google.common.base.Splitter; +import java.nio.charset.Charset; + import static org.apache.commons.lang3.StringUtils.repeat; public class StringUtils { + public static Charset UTF8 = com.amazonaws.util.StringUtils.UTF8; public static final String EMPTY = ""; @@ -98,4 +101,51 @@ public class StringUtils { return Splitter.fixedLength(maxPartSize).split(value); } + public static boolean equalsIgnoreCase(String value, String aTrue) { + return org.eclipse.leshan.core.util.StringUtils.equalsIgnoreCase(value, aTrue); + } + + public static String join(String[] keyArray, String lwm2mSeparatorPath) { + return org.apache.commons.lang3.StringUtils.join(keyArray, lwm2mSeparatorPath); + } + + public static String trimToNull(String toString) { + return org.apache.commons.lang3.StringUtils.trimToNull(toString); + } + + public static boolean isNoneEmpty(String str) { + return org.apache.commons.lang3.StringUtils.isNoneEmpty(str); + } + + public static boolean endsWith(String str, String suffix) { + return org.apache.commons.lang3.StringUtils.endsWith(str, suffix); + } + + public static boolean hasLength(String str) { + return org.springframework.util.StringUtils.hasLength(str); + } + + public static boolean isNoneBlank(String str) { + return org.apache.commons.lang3.StringUtils.isNoneBlank(str); + } + + public static boolean hasText(String str) { + return org.springframework.util.StringUtils.hasText(str); + } + + public static String defaultString(String s, String defaultValue) { + return org.apache.commons.lang3.StringUtils.defaultString(s, defaultValue); + } + + public static boolean isNumeric(String str) { + return org.apache.commons.lang3.StringUtils.isNumeric(str); + } + + public static boolean equals(String str1, String str2) { + return org.apache.commons.lang3.StringUtils.equals(str1, str2); + } + + public static String substringAfterLast(String str, String sep) { + return org.apache.commons.lang3.StringUtils.substringAfterLast(str, sep); + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/SnmpDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/SnmpDeviceTransportConfiguration.java index 041fe4752c..0893157ef6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/SnmpDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/SnmpDeviceTransportConfiguration.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.ToString; import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.transport.snmp.AuthenticationProtocol; import org.thingsboard.server.common.data.transport.snmp.PrivacyProtocol; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/EntityLoadError.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/EntityLoadError.java index cbfe9f6457..1f54a7c262 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/EntityLoadError.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/EntityLoadError.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Builder; import lombok.Data; import org.apache.commons.lang3.ClassUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.EntityId; import java.io.Serializable; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/SnmpMapping.java b/common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/SnmpMapping.java index 44fe42512b..376311f75b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/SnmpMapping.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/transport/snmp/SnmpMapping.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.kv.DataType; import java.util.regex.Pattern; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java index bb3be80629..ba7c957d58 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsg.java @@ -22,7 +22,7 @@ import lombok.AccessLevel; import lombok.Data; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java index a3744c3946..ba8f103658 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbTransportService; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java index e62ee850fa..9c867fb5be 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java @@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.queue.ServiceType; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaProducerTemplate.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaProducerTemplate.java index d4946581e6..29aadcafd6 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaProducerTemplate.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaProducerTemplate.java @@ -23,7 +23,7 @@ import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.header.Header; import org.apache.kafka.common.header.internals.RecordHeader; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.queue.TbQueueAdmin; import org.thingsboard.server.queue.TbQueueCallback; diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 7802793d64..b5bb3c39b7 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -86,6 +86,10 @@ awaitility test + + org.thingsboard.common + data + diff --git a/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java b/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java index e71ac22d00..dff0212e99 100644 --- a/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java +++ b/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java @@ -19,7 +19,7 @@ import io.micrometer.core.instrument.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import javax.annotation.PostConstruct; import java.util.concurrent.atomic.AtomicInteger; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java index a23ca82234..1043cecc41 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java @@ -16,7 +16,7 @@ package org.thingsboard.server.transport.coap.adaptors; import org.eclipse.californium.core.coap.Request; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java index 3d4a4ee053..3568624289 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java @@ -27,7 +27,7 @@ import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.common.transport.adaptor.JsonConverter; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java index 1bd1ffb827..13c783675e 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java @@ -26,7 +26,7 @@ import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.common.transport.adaptor.JsonConverter; diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index de9619cb9f..17bc257ccb 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -28,7 +28,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java index ca001e3b83..43c40280a8 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java @@ -18,7 +18,7 @@ package org.thingsboard.server.transport.lwm2m.utils; import com.fasterxml.jackson.core.type.TypeReference; import com.google.gson.JsonElement; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.eclipse.leshan.core.attributes.Attribute; import org.eclipse.leshan.core.attributes.AttributeSet; import org.eclipse.leshan.core.model.LwM2mModel; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java index c4057be1fe..cd2bb87fc4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java @@ -23,7 +23,7 @@ import org.eclipse.leshan.core.node.ObjectLink; import org.eclipse.leshan.core.node.codec.CodecException; import org.eclipse.leshan.core.node.codec.LwM2mValueConverter; import org.eclipse.leshan.core.util.Hex; -import org.eclipse.leshan.core.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import java.math.BigInteger; import java.text.DateFormat; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index 8408c76a16..98aaca7f06 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -24,7 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.transport.TransportService; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index f37715efc8..b83cb4aa44 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -41,7 +41,7 @@ import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; @@ -89,7 +89,7 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.amazonaws.util.StringUtils.UTF8; +import static org.thingsboard.server.common.data.StringUtils.UTF8; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; import static io.netty.handler.codec.mqtt.MqttMessageType.CONNACK; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index 75c76c0cdb..b8e120f301 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -27,7 +27,7 @@ import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttPublishVariableHeader; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.adaptor.AdaptorException; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java index 175bf17c02..17ae0d75b5 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java @@ -25,7 +25,7 @@ import io.netty.handler.codec.mqtt.MqttMessage; import io.netty.handler.codec.mqtt.MqttPublishMessage; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.adaptor.AdaptorException; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java index d91935086b..fad67470ba 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java @@ -35,7 +35,7 @@ import io.netty.handler.codec.mqtt.MqttPublishMessage; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index 636b9554a5..3ba33d58da 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -23,7 +23,7 @@ import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import org.apache.commons.lang3.math.NumberUtils; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java index 137ceff337..6fe0f29cfc 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java @@ -25,7 +25,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.gen.transport.TransportApiProtos; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java index e3170797bd..92084db5af 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.transport.limits; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.DeviceId; diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java index d3615f7228..64f4e90cb8 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java @@ -18,7 +18,7 @@ package org.thingsboard.server.service.sync.vc; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.eclipse.jgit.api.errors.GitAPIException; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 7d1710a87b..d820659e77 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -20,7 +20,7 @@ import com.google.common.collect.Ordering; import com.google.common.collect.Streams; import lombok.Data; import lombok.Getter; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.sshd.common.util.security.SecurityUtils; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index e88c37d213..693a1c413c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -27,7 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java b/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java index 4d8bc9d6ac..7ef0204565 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.audit.sink; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 3937bbd9c3..671f063640 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.event; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java index e958b8422f..a10969eb22 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java @@ -21,7 +21,7 @@ import lombok.EqualsAndHashCode; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java index ccaea5524e..cf167a8b61 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java @@ -24,7 +24,7 @@ import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.id.DashboardId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java index de5dd6a22c..3aef6e0fb9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.id.DashboardId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OAuth2RegistrationEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OAuth2RegistrationEntity.java index 68b5baa9bf..59701a3ac8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OAuth2RegistrationEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OAuth2RegistrationEntity.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; -import io.micrometer.core.instrument.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Type; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java index 05c264a48b..88c1693e10 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.model.sqlts.timescale.ts; import lombok.Data; import lombok.EqualsAndHashCode; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import javax.persistence.ColumnResult; diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java index fd4b29817b..015f2e1101 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java @@ -19,7 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.oauth2.MapperType; diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index f60920a31d..90b3c290b9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -28,7 +28,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java index 81297b3594..ecdcf9b398 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.service; import com.fasterxml.jackson.databind.JsonNode; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.TenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidator.java index 8033688787..6c10a59917 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidator.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.id.TenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmDataValidator.java index a95f7a43aa..f9097cfcc0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmDataValidator.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.exception.DataValidationException; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AssetDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AssetDataValidator.java index 1f303cc79d..68525b871f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AssetDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AssetDataValidator.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.service.validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.asset.Asset; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ClientRegistrationTemplateDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ClientRegistrationTemplateDataValidator.java index b5d0247e28..2023ec353f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ClientRegistrationTemplateDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ClientRegistrationTemplateDataValidator.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.service.validator; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; import org.thingsboard.server.dao.exception.DataValidationException; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidator.java index f7eceec4d5..6071d7e9be 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/CustomerDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/CustomerDataValidator.java index 9cc8d6a0de..9d356e7484 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/CustomerDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/CustomerDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DashboardDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DashboardDataValidator.java index 23b960253c..b1453c870e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DashboardDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DashboardDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java index d30180a892..80c5c98862 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.service.validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EdgeDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EdgeDataValidator.java index b88724f7af..e64ff15409 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EdgeDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EdgeDataValidator.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.CustomerId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidator.java index 7532dda195..7d47df55be 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidator.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityView; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EventDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EventDataValidator.java index ae7b7542a4..e43cdcc9de 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/EventDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/EventDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.id.TenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ResourceDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ResourceDataValidator.java index 49de43dba3..512fa9275b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/ResourceDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/ResourceDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidator.java index 1581a61b80..0778d039e0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantDataValidator.java index 65770aefdb..bd07c6b597 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Tenant; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidator.java index feab5078e6..68af5fee48 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserCredentialsDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserCredentialsDataValidator.java index 5920ad552f..111e8af55c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserCredentialsDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserCredentialsDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserDataValidator.java index 21e2143f1a..3e6e4900f7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/UserDataValidator.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.service.validator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidator.java index 25c6b5db86..3e83518941 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidator.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidator.java index b950a12826..1b77c63f1f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidator.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.service.validator; import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetsBundle; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java index 8513e440b7..0430f3811f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java @@ -23,7 +23,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceInfo; import org.thingsboard.server.common.data.DeviceTransportType; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java index 07a680493f..8b3aff42e4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.dao.sql.device; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java index 36f834b8bc..6d90ac4d2d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sql.edge; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index 2b409006d2..30019202ff 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sql.event; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.PageRequest; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java index 7d660519eb..733ce25d6c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sql.query; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java index a1be8884ff..07b597e5a2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.sql.query; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.support.TransactionTemplate; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java index 8d6af88c59..fa8745164d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.sql.query; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java index 1499b7150f..78e90b3311 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.sql.query; import lombok.Data; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.query.BooleanFilterPredicate; diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java index 0b97a2874f..be960f4af8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.timeseries; import com.datastax.oss.driver.api.core.cql.Row; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.DoubleDataEntry; diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java index a74f51ce9e..8254b2bee0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java @@ -47,7 +47,7 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.thingsboard.server.common.data.StringUtils.isBlank; /** * @author Andrew Shvayka diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java index 808e499239..5c86799442 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java @@ -21,7 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assert; diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index a0f1d5dfa1..67ee202331 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -34,7 +34,7 @@ import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.support.HttpRequestWrapper; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import org.thingsboard.common.util.ThingsBoardExecutors; diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java index bc38db7fd6..940a5453b6 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java @@ -19,9 +19,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java index a03d853c09..06889bd6de 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java @@ -25,7 +25,7 @@ import com.amazonaws.services.sqs.model.SendMessageRequest; import com.amazonaws.services.sqs.model.SendMessageResult; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java index 3a38a286f2..528840d972 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java @@ -28,7 +28,7 @@ import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import org.bouncycastle.util.encoders.Hex; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import javax.crypto.Cipher; import javax.crypto.EncryptedPrivateKeyInfo; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index 80b319e087..32ec34ef39 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -19,7 +19,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.TbStopWatch; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.ScriptEngine; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java index 836497cced..b9c7d53b1d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.kafka; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.ProducerConfig; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java index 28732c53e9..fbdbb84cad 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbEmail; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java index bf65dc1fc3..10281be468 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.mail; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java index 320502005b..4d867562d8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java @@ -25,7 +25,7 @@ import com.google.gson.JsonParseException; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.api.RuleNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java index 1600f2271c..6dd632aa97 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java @@ -20,7 +20,7 @@ import io.netty.handler.codec.mqtt.MqttQoS; import io.netty.handler.ssl.SslContext; import io.netty.util.concurrent.Future; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.mqtt.MqttClient; import org.thingsboard.mqtt.MqttClientConfig; import org.thingsboard.mqtt.MqttConnectResult; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java index 1218518a12..80c75e08ba 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java @@ -18,7 +18,7 @@ package org.thingsboard.rule.engine.mqtt.azure; import io.netty.handler.codec.mqtt.MqttVersion; import io.netty.handler.ssl.SslContext; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.AzureIotHubUtil; import org.thingsboard.mqtt.MqttClientConfig; import org.thingsboard.rule.engine.api.RuleNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java index db41c0f6d5..81b5282aff 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.action.TbAlarmResult; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java index f0bbdfb66b..5ab5adc7fc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.profile; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.profile.state.PersistedAlarmState; import org.thingsboard.rule.engine.profile.state.PersistedDeviceState; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java index 0b3822352e..5ba55fe2d5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java @@ -22,7 +22,7 @@ import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.MessageProperties; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index e035d415ed..28c937c9ce 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -35,7 +35,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory; import org.springframework.http.client.Netty4ClientHttpRequestFactory; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.web.client.AsyncRestTemplate; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java index 36497df564..cdc3095443 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java @@ -16,7 +16,7 @@ package org.thingsboard.rule.engine.rpc; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java index 265475c0d9..7a1436a385 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java @@ -21,7 +21,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRpcReplyNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRpcReplyNodeConfiguration.java index a736759f1a..1a014eb323 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRpcReplyNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRpcReplyNodeConfiguration.java @@ -16,7 +16,7 @@ package org.thingsboard.rule.engine.rpc; import lombok.Data; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.DataConstants; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 56e1ca8577..fb819aed90 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.telemetry; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java index 22d9d1ac07..4a44d9f7b1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.telemetry; import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java index b6a1be84b1..2feaf7cd77 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java @@ -17,7 +17,7 @@ package org.thingsboard.client.tools.migrator; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import java.io.File; import java.io.IOException; diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java index 695356ed2d..77fc0837ed 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java @@ -19,7 +19,7 @@ import com.google.common.collect.Lists; import org.apache.cassandra.io.sstable.CQLSSTableWriter; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import java.io.File; diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/RelatedEntitiesParser.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/RelatedEntitiesParser.java index b0f786a2d3..c84020b6b5 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/RelatedEntitiesParser.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/RelatedEntitiesParser.java @@ -17,7 +17,7 @@ package org.thingsboard.client.tools.migrator; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; -import org.apache.commons.lang3.StringUtils; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.EntityType; import java.io.File; From bc88babd1120db4a43e41212cf8cfa65d8edb7e1 Mon Sep 17 00:00:00 2001 From: thingsboard Date: Tue, 12 Jul 2022 12:29:27 +0300 Subject: [PATCH 005/158] fix pr comments --- .../server/service/action/EntityActionService.java | 7 ++++++- common/data/pom.xml | 10 ---------- .../thingsboard/server/common/data/StringUtils.java | 8 ++------ .../server/transport/mqtt/MqttTransportHandler.java | 2 +- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 2f18fb56c8..e1e7ffbb55 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -23,7 +23,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.*; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; diff --git a/common/data/pom.xml b/common/data/pom.xml index 50755115a0..539dd0d9e3 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -108,16 +108,6 @@ de.ruedigermoeller fst - - org.eclipse.leshan - leshan-core - - - com.amazonaws - aws-java-sdk-core - 1.11.747 - compile - diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index 4b916df30e..77e4e7656c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java @@ -17,13 +17,9 @@ package org.thingsboard.server.common.data; import com.google.common.base.Splitter; -import java.nio.charset.Charset; - import static org.apache.commons.lang3.StringUtils.repeat; public class StringUtils { - public static Charset UTF8 = com.amazonaws.util.StringUtils.UTF8; - public static final String EMPTY = ""; public static final int INDEX_NOT_FOUND = -1; @@ -101,8 +97,8 @@ public class StringUtils { return Splitter.fixedLength(maxPartSize).split(value); } - public static boolean equalsIgnoreCase(String value, String aTrue) { - return org.eclipse.leshan.core.util.StringUtils.equalsIgnoreCase(value, aTrue); + public static boolean equalsIgnoreCase(String str1, String str2) { + return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); } public static String join(String[] keyArray, String lwm2mSeparatorPath) { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index b83cb4aa44..ad07c9f9a4 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -89,7 +89,7 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.thingsboard.server.common.data.StringUtils.UTF8; +import static com.amazonaws.util.StringUtils.UTF8; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; import static io.netty.handler.codec.mqtt.MqttMessageType.CONNACK; From d6244a84222cc048843da38be687704e62c2ff36 Mon Sep 17 00:00:00 2001 From: Dima Landiak Date: Tue, 12 Jul 2022 12:33:16 +0300 Subject: [PATCH 006/158] netty client - added channel reader idle state handling, fixed ping/pong keepalive logic --- netty-mqtt/pom.xml | 31 +++++++++ .../org/thingsboard/mqtt/MqttClientImpl.java | 14 +++++ .../org/thingsboard/mqtt/MqttPingHandler.java | 30 +++++---- .../thingsboard/mqtt/MqttPingHandlerTest.java | 63 +++++++++++++++++++ 4 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 netty-mqtt/src/test/java/org/thingsboard/mqtt/MqttPingHandlerTest.java diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 662d677f8b..e17b186067 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -53,6 +53,37 @@ com.google.guava guava + + org.slf4j + slf4j-api + + + org.slf4j + log4j-over-slf4j + + + ch.qos.logback + logback-core + + + ch.qos.logback + logback-classic + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.awaitility + awaitility + test + diff --git a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientImpl.java b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientImpl.java index e91af1c557..fb04ce889e 100644 --- a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientImpl.java +++ b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientImpl.java @@ -45,6 +45,7 @@ import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; +import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.HashSet; @@ -60,6 +61,7 @@ import java.util.concurrent.atomic.AtomicInteger; * Represents an MqttClientImpl connected to a single MQTT server. Will try to keep the connection going at all times */ @SuppressWarnings({"WeakerAccess", "unused"}) +@Slf4j final class MqttClientImpl implements MqttClient { private final Set serverSubscriptions = new HashSet<>(); @@ -131,6 +133,7 @@ final class MqttClientImpl implements MqttClient { } private Future connect(String host, int port, boolean reconnect) { + log.trace("[{}] Connecting to server, isReconnect - {}", channel != null ? channel.id() : "UNKNOWN", reconnect); if (this.eventLoop == null) { this.eventLoop = new NioEventLoopGroup(); } @@ -147,10 +150,12 @@ final class MqttClientImpl implements MqttClient { future.addListener((ChannelFutureListener) f -> { if (f.isSuccess()) { MqttClientImpl.this.channel = f.channel(); + log.debug("[{}][{}] Connected successfully {}!", host, port, this.channel.id()); MqttClientImpl.this.channel.closeFuture().addListener((ChannelFutureListener) channelFuture -> { if (isConnected()) { return; } + log.debug("[{}][{}] Channel is closed {}!", host, port, this.channel.id()); ChannelClosedException e = new ChannelClosedException("Channel is closed!"); if (callback != null) { callback.connectionLost(e); @@ -169,6 +174,7 @@ final class MqttClientImpl implements MqttClient { scheduleConnectIfRequired(host, port, true); }); } else { + log.debug("[{}][{}] Connect failed, trying reconnect!", host, port); scheduleConnectIfRequired(host, port, reconnect); } }); @@ -176,6 +182,7 @@ final class MqttClientImpl implements MqttClient { } private void scheduleConnectIfRequired(String host, int port, boolean reconnect) { + log.trace("[{}] Scheduling connect to server, isReconnect - {}", channel != null ? channel.id() : "UNKNOWN", reconnect); if (clientConfig.isReconnect() && !disconnected) { if (reconnect) { this.reconnect = true; @@ -191,6 +198,7 @@ final class MqttClientImpl implements MqttClient { @Override public Future reconnect() { + log.trace("[{}] Reconnecting to server, isReconnect - {}", channel != null ? channel.id() : "UNKNOWN", reconnect); if (host == null) { throw new IllegalStateException("Cannot reconnect. Call connect() first"); } @@ -281,6 +289,7 @@ final class MqttClientImpl implements MqttClient { */ @Override public Future off(String topic, MqttHandler handler) { + log.trace("[{}] Unsubscribing from {}", channel != null ? channel.id() : "UNKNOWN", topic); Promise future = new DefaultPromise<>(this.eventLoop.next()); for (MqttSubscription subscription : this.handlerToSubscription.get(handler)) { this.subscriptions.remove(topic, subscription); @@ -299,6 +308,7 @@ final class MqttClientImpl implements MqttClient { */ @Override public Future off(String topic) { + log.trace("[{}] Unsubscribing from {}", channel != null ? channel.id() : "UNKNOWN", topic); Promise future = new DefaultPromise<>(this.eventLoop.next()); ImmutableSet subscriptions = ImmutableSet.copyOf(this.subscriptions.get(topic)); for (MqttSubscription subscription : subscriptions) { @@ -360,6 +370,7 @@ final class MqttClientImpl implements MqttClient { */ @Override public Future publish(String topic, ByteBuf payload, MqttQoS qos, boolean retain) { + log.trace("[{}] Publishing message to {}", channel != null ? channel.id() : "UNKNOWN", topic); Promise future = new DefaultPromise<>(this.eventLoop.next()); MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retain, 0); MqttPublishVariableHeader variableHeader = new MqttPublishVariableHeader(topic, getNewMessageId().messageId()); @@ -404,6 +415,7 @@ final class MqttClientImpl implements MqttClient { @Override public void disconnect() { + log.trace("[{}] Disconnecting from server", channel != null ? channel.id() : "UNKNOWN"); disconnected = true; if (this.channel != null) { MqttMessage message = new MqttMessage(new MqttFixedHeader(MqttMessageType.DISCONNECT, false, MqttQoS.AT_MOST_ONCE, false, 0)); @@ -435,6 +447,7 @@ final class MqttClientImpl implements MqttClient { return null; } if (this.channel.isActive()) { + log.trace("[{}] Sending message {}", channel != null ? channel.id() : "UNKNOWN", message); return this.channel.writeAndFlush(message); } return this.channel.newFailedFuture(new ChannelClosedException("Channel is closed!")); @@ -450,6 +463,7 @@ final class MqttClientImpl implements MqttClient { } private Future createSubscription(String topic, MqttHandler handler, boolean once, MqttQoS qos) { + log.trace("[{}] Creating subscription to {}", channel != null ? channel.id() : "UNKNOWN", topic); if (this.pendingSubscribeTopics.contains(topic)) { Optional> subscriptionEntry = this.pendingSubscriptions.entrySet().stream().filter((e) -> e.getValue().getTopic().equals(topic)).findAny(); if (subscriptionEntry.isPresent()) { diff --git a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttPingHandler.java b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttPingHandler.java index 8ab69d8f35..c7e1b5eebb 100644 --- a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttPingHandler.java +++ b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttPingHandler.java @@ -26,9 +26,11 @@ import io.netty.handler.codec.mqtt.MqttQoS; import io.netty.handler.timeout.IdleStateEvent; import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.ScheduledFuture; +import lombok.extern.slf4j.Slf4j; import java.util.concurrent.TimeUnit; +@Slf4j final class MqttPingHandler extends ChannelInboundHandlerAdapter { private final int keepaliveSeconds; @@ -46,11 +48,11 @@ final class MqttPingHandler extends ChannelInboundHandlerAdapter { return; } MqttMessage message = (MqttMessage) msg; - if(message.fixedHeader().messageType() == MqttMessageType.PINGREQ){ + if (message.fixedHeader().messageType() == MqttMessageType.PINGREQ) { this.handlePingReq(ctx.channel()); - } else if(message.fixedHeader().messageType() == MqttMessageType.PINGRESP){ - this.handlePingResp(); - }else{ + } else if (message.fixedHeader().messageType() == MqttMessageType.PINGRESP) { + this.handlePingResp(ctx.channel()); + } else { ctx.fireChannelRead(ReferenceCountUtil.retain(msg)); } } @@ -59,23 +61,27 @@ final class MqttPingHandler extends ChannelInboundHandlerAdapter { public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { super.userEventTriggered(ctx, evt); - if(evt instanceof IdleStateEvent){ + if (evt instanceof IdleStateEvent) { IdleStateEvent event = (IdleStateEvent) evt; - switch(event.state()){ + switch (event.state()) { case READER_IDLE: + log.debug("[{}] No reads were performed for specified period for channel {}", event.state(), ctx.channel().id()); + this.sendPingReq(ctx.channel()); break; case WRITER_IDLE: + log.debug("[{}] No writes were performed for specified period for channel {}", event.state(), ctx.channel().id()); this.sendPingReq(ctx.channel()); break; } } } - private void sendPingReq(Channel channel){ + private void sendPingReq(Channel channel) { + log.trace("[{}] Sending ping request", channel.id()); MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PINGREQ, false, MqttQoS.AT_MOST_ONCE, false, 0); channel.writeAndFlush(new MqttMessage(fixedHeader)); - if(this.pingRespTimeout != null){ + if (this.pingRespTimeout == null) { this.pingRespTimeout = channel.eventLoop().schedule(() -> { MqttFixedHeader fixedHeader2 = new MqttFixedHeader(MqttMessageType.DISCONNECT, false, MqttQoS.AT_MOST_ONCE, false, 0); channel.writeAndFlush(new MqttMessage(fixedHeader2)).addListener(ChannelFutureListener.CLOSE); @@ -84,13 +90,15 @@ final class MqttPingHandler extends ChannelInboundHandlerAdapter { } } - private void handlePingReq(Channel channel){ + private void handlePingReq(Channel channel) { + log.trace("[{}] Handling ping request", channel.id()); MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PINGRESP, false, MqttQoS.AT_MOST_ONCE, false, 0); channel.writeAndFlush(new MqttMessage(fixedHeader)); } - private void handlePingResp(){ - if(this.pingRespTimeout != null && !this.pingRespTimeout.isCancelled() && !this.pingRespTimeout.isDone()){ + private void handlePingResp(Channel channel) { + log.trace("[{}] Handling ping response", channel.id()); + if (this.pingRespTimeout != null && !this.pingRespTimeout.isCancelled() && !this.pingRespTimeout.isDone()) { this.pingRespTimeout.cancel(true); this.pingRespTimeout = null; } diff --git a/netty-mqtt/src/test/java/org/thingsboard/mqtt/MqttPingHandlerTest.java b/netty-mqtt/src/test/java/org/thingsboard/mqtt/MqttPingHandlerTest.java new file mode 100644 index 0000000000..d665ff5378 --- /dev/null +++ b/netty-mqtt/src/test/java/org/thingsboard/mqtt/MqttPingHandlerTest.java @@ -0,0 +1,63 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.mqtt; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.DefaultEventLoop; +import io.netty.handler.timeout.IdleStateEvent; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class MqttPingHandlerTest { + + static final int KEEP_ALIVE_SECONDS = 0; + static final int PROCESS_SEND_DISCONNECT_MSG_TIME_MS = 500; + + MqttPingHandler mqttPingHandler; + + @BeforeEach + void setUp() { + mqttPingHandler = new MqttPingHandler(KEEP_ALIVE_SECONDS); + } + + @Test + void givenChannelReaderIdleState_whenNoPingResponse_thenDisconnectClient() throws Exception { + ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(ctx.channel()).thenReturn(channel); + when(channel.eventLoop()).thenReturn(new DefaultEventLoop()); + ChannelFuture channelFuture = mock(ChannelFuture.class); + when(channel.writeAndFlush(any())).thenReturn(channelFuture); + + mqttPingHandler.userEventTriggered(ctx, IdleStateEvent.FIRST_READER_IDLE_STATE_EVENT); + verify( + channelFuture, + after(TimeUnit.SECONDS.toMillis(KEEP_ALIVE_SECONDS) + PROCESS_SEND_DISCONNECT_MSG_TIME_MS) + ).addListener(eq(ChannelFutureListener.CLOSE)); + } +} \ No newline at end of file From 95faab9c2e78df45c9a6b233d1bb78a44886f03c Mon Sep 17 00:00:00 2001 From: thingsboard Date: Fri, 15 Jul 2022 12:54:41 +0300 Subject: [PATCH 007/158] fix pr comments --- .../java/org/thingsboard/server/common/data/StringUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index 77e4e7656c..e0b42d68a5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java @@ -121,7 +121,7 @@ public class StringUtils { return org.springframework.util.StringUtils.hasLength(str); } - public static boolean isNoneBlank(String str) { + public static boolean isNoneBlank(String... str) { return org.apache.commons.lang3.StringUtils.isNoneBlank(str); } From ffc18489c4b54778736ced2e48e6e838da427e14 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 15 Jul 2022 17:03:02 +0300 Subject: [PATCH 008/158] Check related rulechain during unassing from edge --- .../rulechains-table-config.resolver.ts | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts index 650d119b4b..a3ff812359 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts @@ -409,6 +409,31 @@ export class RuleChainsTableConfigResolver implements Resolve { + if (missingRuleChains && Object.keys(missingRuleChains).length > 0) { + const formattedMissingRuleChains: Array = new Array(); + for (const missingRuleChain of Object.keys(missingRuleChains)) { + const arrayOfMissingRuleChains = missingRuleChains[missingRuleChain]; + const tmp = '- \'' + missingRuleChain + '\': \'' + arrayOfMissingRuleChains.join('\', ') + '\''; + formattedMissingRuleChains.push(tmp); + } + const message = this.translate.instant('edge.missing-related-rule-chains-text', + {missingRuleChains: formattedMissingRuleChains.join('
')}); + this.dialogService.alert(this.translate.instant('edge.missing-related-rule-chains-title'), + message, this.translate.instant('action.close'), true).subscribe( + () => { + this.config.updateData(); + } + ); + } else { + this.config.updateData(); + } + } + ); + } + addRuleChainsToEdge($event: Event) { if ($event) { $event.stopPropagation(); @@ -424,28 +449,7 @@ export class RuleChainsTableConfigResolver implements Resolve { if (res) { - this.edgeService.findMissingToRelatedRuleChains(this.config.componentsData.edgeId).subscribe( - (missingRuleChains) => { - if (missingRuleChains && Object.keys(missingRuleChains).length > 0) { - const formattedMissingRuleChains: Array = new Array(); - for (const missingRuleChain of Object.keys(missingRuleChains)) { - const arrayOfMissingRuleChains = missingRuleChains[missingRuleChain]; - const tmp = '- \'' + missingRuleChain + '\': \'' + arrayOfMissingRuleChains.join('\', ') + '\''; - formattedMissingRuleChains.push(tmp); - } - const message = this.translate.instant('edge.missing-related-rule-chains-text', - {missingRuleChains: formattedMissingRuleChains.join('
')}); - this.dialogService.alert(this.translate.instant('edge.missing-related-rule-chains-title'), - message, this.translate.instant('action.close'), true).subscribe( - () => { - this.config.updateData(); - } - ); - } else { - this.config.updateData(); - } - } - ); + this.checkMissingToRelatedRuleChains(); } } ); @@ -465,7 +469,7 @@ export class RuleChainsTableConfigResolver implements Resolve { - this.config.updateData(this.config.componentsData.ruleChainScope !== 'tenant'); + this.checkMissingToRelatedRuleChains(); } ); } @@ -493,7 +497,7 @@ export class RuleChainsTableConfigResolver implements Resolve { - this.config.updateData(); + this.checkMissingToRelatedRuleChains(); } ); } From b08fd39bdc050774577e8d2139d9e1ff1c530518 Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Mon, 18 Jul 2022 15:05:47 +0300 Subject: [PATCH 009/158] fix_convertValue in EntityDataAdapter --- .../thingsboard/server/dao/sql/query/EntityDataAdapter.java | 5 ++++- .../server/dao/sql/query/EntityDataAdapterTest.java | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityDataAdapter.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityDataAdapter.java index 49640c1640..c30ecdd9a2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityDataAdapter.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityDataAdapter.java @@ -81,7 +81,10 @@ public class EntityDataAdapter { if (value != null) { String strVal = value.toString(); // check number - if (strVal.length() > 0 && NumberUtils.isParsable(strVal)) { + if (NumberUtils.isParsable(strVal)) { + if (strVal.startsWith("0") && !strVal.startsWith("0.")) { + return strVal; + } try { long longVal = Long.parseLong(strVal); return Long.toString(longVal); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java index 8965358e63..f140d66c83 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java @@ -25,5 +25,6 @@ public class EntityDataAdapterTest { public void testConvertValue() { assertThat(EntityDataAdapter.convertValue("500")).isEqualTo("500"); assertThat(EntityDataAdapter.convertValue("500D")).isEqualTo("500D"); //do not convert to Double !!! + assertThat(EntityDataAdapter.convertValue("0101010521130565")).isEqualTo("0101010521130565"); } -} +} \ No newline at end of file From ee95dc20df958a67d3f60b8e72d48f01f853d721 Mon Sep 17 00:00:00 2001 From: Yuriy Lytvynchuk Date: Mon, 18 Jul 2022 15:13:21 +0300 Subject: [PATCH 010/158] fix_convertValue in EntityDataAdapter --- .../thingsboard/server/dao/sql/query/EntityDataAdapterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java index f140d66c83..6d052db1d1 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/EntityDataAdapterTest.java @@ -27,4 +27,4 @@ public class EntityDataAdapterTest { assertThat(EntityDataAdapter.convertValue("500D")).isEqualTo("500D"); //do not convert to Double !!! assertThat(EntityDataAdapter.convertValue("0101010521130565")).isEqualTo("0101010521130565"); } -} \ No newline at end of file +} From c6be0aeba298322be729953988bc81d474b3dc9b Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 20 Jul 2022 17:12:39 +0300 Subject: [PATCH 011/158] UI: Improvement of mobile view in widgets setting --- ...larms-table-widget-settings.component.html | 4 +-- ...ities-table-widget-settings.component.html | 8 +++--- .../cards/label-widget-label.component.html | 2 +- ...eries-table-widget-settings.component.html | 4 +-- ...ghnut-chart-widget-settings.component.html | 2 +- .../chart/flot-key-settings.component.html | 10 +++---- .../flot-latest-key-settings.component.html | 2 +- .../flot-pie-widget-settings.component.html | 4 +-- .../chart/flot-threshold.component.html | 2 +- .../chart/flot-widget-settings.component.html | 12 +++++---- .../chart/label-data-key.component.html | 2 +- .../common/value-source.component.html | 3 ++- .../common/widget-font.component.html | 6 ++--- ...nob-control-widget-settings.component.html | 2 +- ...stent-table-widget-settings.component.html | 4 +-- .../control/rpc-button-style.component.html | 2 +- ...lide-toggle-widget-settings.component.html | 2 +- ...gue-compass-widget-settings.component.html | 6 ++--- ...logue-gauge-widget-settings.component.html | 22 ++++++++-------- ...gital-gauge-widget-settings.component.html | 4 +-- .../gauge/gauge-highlight.component.html | 2 +- .../settings/gpio/gpio-item.component.html | 4 +-- .../datakey-select-option.component.html | 2 +- ...amera-input-widget-settings.component.html | 4 +-- ...-attribute-general-settings.component.html | 12 ++++----- ...n-attribute-widget-settings.component.html | 2 +- ...e-attribute-widget-settings.component.html | 2 +- ...r-attribute-widget-settings.component.html | 2 +- ...n-attribute-widget-settings.component.html | 8 +++--- ...n-attribute-widget-settings.component.html | 6 ++--- ...ple-attributes-key-settings.component.html | 9 ++++--- ...-attributes-widget-settings.component.html | 6 ++--- ...g-attribute-widget-settings.component.html | 2 +- .../map/circle-settings.component.html | 4 +-- .../map/common-map-settings.component.html | 6 ++--- ...image-map-provider-settings.component.html | 2 +- .../map/map-editor-settings.component.html | 4 +-- .../marker-clustering-settings.component.html | 14 +++++----- .../map/markers-settings.component.html | 4 +-- .../map/polygon-settings.component.html | 4 +-- ...p-animation-common-settings.component.html | 4 +-- ...rip-animation-path-settings.component.html | 8 +++--- ...ip-animation-point-settings.component.html | 2 +- .../widget/lib/settings/widget-settings.scss | 26 ++++++++++++++++++- 44 files changed, 135 insertions(+), 107 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html index 3b5516c26c..5fc8104a80 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/alarm/alarms-table-widget-settings.component.html @@ -22,7 +22,7 @@ widgets.table.alarms-table-title -
+
{{ 'widgets.table.enable-alarms-selection' | translate }} @@ -67,7 +67,7 @@ {{ 'widgets.table.allow-alarms-clear' | translate }} -
+
{{ 'widgets.table.display-pagination' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html index e58f083bea..c84a87deac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html @@ -22,7 +22,7 @@ widgets.table.entities-table-title -
+
{{ 'widgets.table.enable-search' | translate }} @@ -52,7 +52,7 @@
-
+
{{ 'widgets.table.display-entity-name' | translate }} @@ -61,7 +61,7 @@
-
+
{{ 'widgets.table.display-entity-label' | translate }} @@ -73,7 +73,7 @@ {{ 'widgets.table.display-entity-type' | translate }} -
+
{{ 'widgets.table.display-pagination' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-widget-label.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-widget-label.component.html index 9aa9fcc68c..bbc3e1c090 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-widget-label.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-widget-label.component.html @@ -47,7 +47,7 @@
widgets.label-widget.label-position -
+
widgets.label-widget.x-pos diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html index c151a97402..a1ba27ce27 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html @@ -18,7 +18,7 @@
widgets.table.common-table-settings -
+
{{ 'widgets.table.enable-search' | translate }} @@ -51,7 +51,7 @@ {{ 'widgets.table.display-milliseconds' | translate }} -
+
{{ 'widgets.table.display-pagination' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-chart-widget-settings.component.html index 8a25d692c5..c3a20ce8f0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-chart-widget-settings.component.html @@ -24,7 +24,7 @@
widgets.chart.border-settings -
+
widgets.chart.border-width diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html index 9aec9b535f..05879cb124 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html @@ -46,7 +46,7 @@ -
+
widgets.chart.line-width @@ -74,7 +74,7 @@
-
+
widgets.chart.points-line-width @@ -137,7 +137,7 @@ widgets.chart.axis-title -
+
widgets.chart.min-scale-value @@ -160,7 +160,7 @@
widgets.chart.yaxis-tick-labels-settings -
+
widgets.chart.tick-step-size @@ -222,7 +222,7 @@ -
+
widgets.chart.comparison-values-label diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html index b5b9009bd6..d2589515ca 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html @@ -31,7 +31,7 @@ -
+
widgets.chart.threshold-line-width diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-pie-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-pie-widget-settings.component.html index 00f9573020..f03125303a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-pie-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-pie-widget-settings.component.html @@ -18,7 +18,7 @@
widgets.chart.common-pie-settings -
+
widgets.chart.radius @@ -41,7 +41,7 @@
widgets.chart.stroke-settings -
+
widgets.chart.width-pixels diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html index 46278cc45e..24d98d9619 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html @@ -41,7 +41,7 @@
-
+
widgets.chart.line-width diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index 3ecc56b602..beebf38268 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -21,7 +21,8 @@ {{ 'widgets.chart.enable-stacking-mode' | translate }} -
+
widgets.chart.line-shadow-size @@ -30,7 +31,8 @@ {{ 'widgets.chart.display-smooth-lines' | translate }}
-
+
widgets.chart.default-bar-width @@ -50,7 +52,7 @@
-
+
widgets.chart.default-font-size @@ -166,7 +168,7 @@ widgets.chart.axis-title -
+
widgets.chart.min-scale-value @@ -196,7 +198,7 @@ icon="format_color_fill" label="{{ 'widgets.chart.ticks-color' | translate }}" openOnInput colorClearButton> -
+
widgets.chart.tick-step-size diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.html index 50dc16d6fb..759f18ba6b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.html @@ -37,7 +37,7 @@
-
+
widgets.chart.key-name diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.html index d4e1e669f6..bc590c3ce2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.html @@ -31,7 +31,8 @@ widgets.value-source.value -
+
{{ 'widgets.value-source.source-entity-alias' | translate }}
-
+
widgets.widget-font.font-family @@ -26,7 +26,7 @@
-
+
widgets.widget-font.font-style @@ -68,7 +68,7 @@
-
+
widgets.rpc.initial-value -
+
widgets.rpc.min-value diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html index 7961dddf1f..47b3ef545d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/persistent-table-widget-settings.component.html @@ -18,7 +18,7 @@
widgets.persistent-table.general-settings -
+
{{ 'widgets.persistent-table.enable-filter' | translate }} @@ -43,7 +43,7 @@ {{ 'widgets.persistent-table.allow-delete-request' | translate }} -
+
{{ 'widgets.table.display-pagination' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/rpc-button-style.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/rpc-button-style.component.html index 1f027eb8b2..a8153c68fe 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/rpc-button-style.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/rpc-button-style.component.html @@ -24,7 +24,7 @@ {{ 'widgets.rpc.button-primary' | translate }} -
+
widgets.rpc.slide-toggle-label -
+
widgets.rpc.label-position diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html index 3311c4d4e7..d2f53cbaa7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/analogue-compass-widget-settings.component.html @@ -42,7 +42,7 @@ icon="format_color_fill" label="{{ 'widgets.gauge.major-ticks-color' | translate }}" openOnInput colorClearButton> -
+
widgets.gauge.minor-ticks-count @@ -71,7 +71,7 @@ {{ 'widgets.gauge.show-plate-border' | translate }} -
+
widgets.gauge.needle-circle-size -
+
widgets.gauge.ticks-settings -
+
widgets.gauge.min-value @@ -41,7 +41,7 @@
-
+
widgets.gauge.major-ticks-count @@ -52,7 +52,7 @@ label="{{ 'widgets.gauge.major-ticks-color' | translate }}" openOnInput colorClearButton>
-
+
widgets.gauge.minor-ticks-count @@ -127,7 +127,7 @@ widgets.gauge.value-font
-
+
-
+
widgets.gauge.needle-settings -
+
-
+
widgets.gauge.radial-gauge-settings -
+
widgets.gauge.start-ticks-angle @@ -314,7 +314,7 @@
widgets.gauge.linear-gauge-settings -
+
widgets.gauge.bar-stroke-width @@ -325,7 +325,7 @@ label="{{ 'widgets.gauge.bar-stroke-color' | translate }}" openOnInput colorClearButton>
-
+
-
+
widgets.gauge.common-settings -
+
widgets.gauge.min-value @@ -65,7 +65,7 @@ widgets.gauge.neon-glow-brightness -
+
widgets.gauge.stripes-thickness diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html index 13c6f6f7ef..a1ca29c6cf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.html @@ -40,7 +40,7 @@
-
+
widgets.gauge.highlight-from diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.html index 9ebbdeefd9..f46ba5cb57 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.html @@ -40,7 +40,7 @@
-
+
widgets.gpio.pin @@ -50,7 +50,7 @@
-
+
widgets.gpio.row diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.html index 68a1a6c5dc..aa440982ab 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.html @@ -37,7 +37,7 @@
-
+
widgets.input-widgets.option-value diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/photo-camera-input-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/photo-camera-input-widget-settings.component.html index d838c59bf7..7377746bf0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/photo-camera-input-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/photo-camera-input-widget-settings.component.html @@ -25,7 +25,7 @@
widgets.input-widgets.image-settings -
+
widgets.input-widgets.image-format @@ -45,7 +45,7 @@
-
+
widgets.input-widgets.max-image-width diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-attribute-general-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-attribute-general-settings.component.html index 14b63d2f14..7b2c9bdcd1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-attribute-general-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-attribute-general-settings.component.html @@ -22,20 +22,20 @@ widgets.input-widgets.widget-title -
- +
+ {{ 'widgets.input-widgets.show-label' | translate }} - + widgets.input-widgets.label
-
- +
+ {{ 'widgets.input-widgets.required' | translate }} - + widgets.input-widgets.required-error-message diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-boolean-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-boolean-attribute-widget-settings.component.html index d47e0a0d73..b9e7a208dd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-boolean-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-boolean-attribute-widget-settings.component.html @@ -28,7 +28,7 @@
widgets.input-widgets.checkbox-settings -
+
widgets.input-widgets.true-label diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-double-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-double-attribute-widget-settings.component.html index 8f5b543e41..be0c4a2b3b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-double-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-double-attribute-widget-settings.component.html @@ -22,7 +22,7 @@
widgets.input-widgets.double-field-settings -
+
widgets.input-widgets.min-value diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-integer-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-integer-attribute-widget-settings.component.html index 0e5c1deccd..f28f055995 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-integer-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-integer-attribute-widget-settings.component.html @@ -22,7 +22,7 @@
widgets.input-widgets.integer-field-settings -
+
widgets.input-widgets.min-value diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-json-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-json-attribute-widget-settings.component.html index cd967cff33..fd76c980ac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-json-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-json-attribute-widget-settings.component.html @@ -22,11 +22,11 @@ widgets.input-widgets.widget-title -
- +
+ {{ 'widgets.input-widgets.show-label' | translate }} - + widgets.input-widgets.label @@ -37,7 +37,7 @@
widgets.input-widgets.attribute-settings -
+
widgets.input-widgets.widget-mode diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-location-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-location-attribute-widget-settings.component.html index 5afb4cfc9d..22270a861f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-location-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-location-attribute-widget-settings.component.html @@ -25,7 +25,7 @@ {{ 'widgets.input-widgets.show-result-message' | translate }} -
+
widgets.input-widgets.latitude-key-name @@ -47,7 +47,7 @@ {{ 'widgets.input-widgets.show-label' | translate }} -
+
widgets.input-widgets.latitude-label @@ -68,7 +68,7 @@ -
+
{{ 'widgets.input-widgets.latitude-field-required' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html index 2f47998fba..22823ba778 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html @@ -21,7 +21,7 @@
widgets.input-widgets.general-settings -
+
widgets.input-widgets.datakey-type @@ -72,7 +72,7 @@ {{ 'widgets.input-widgets.value-is-required' | translate }} -
+
widgets.input-widgets.ability-to-edit-attribute @@ -140,7 +140,7 @@ (updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value === 'integer' || updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value === 'double')" class="fields-group"> widgets.input-widgets.numeric-field-settings -
+
widgets.input-widgets.step-interval @@ -162,7 +162,8 @@
+ updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value === 'double'" + class="row-fill" fxLayout="row" fxLayoutGap="8px"> widgets.input-widgets.min-value-error-message diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-widget-settings.component.html index 327879ed03..188a392718 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-widget-settings.component.html @@ -45,7 +45,7 @@ {{ 'widgets.input-widgets.update-all-values' | translate }} -
+
widgets.input-widgets.save-button-label @@ -61,7 +61,7 @@
widgets.input-widgets.group-settings -
+
{{ 'widgets.input-widgets.show-group-title' | translate }} @@ -73,7 +73,7 @@
widgets.input-widgets.fields-alignment -
+
widgets.input-widgets.fields-alignment diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-string-attribute-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-string-attribute-widget-settings.component.html index f80d319dab..a282117cab 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-string-attribute-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-string-attribute-widget-settings.component.html @@ -22,7 +22,7 @@
widgets.input-widgets.text-field-settings -
+
widgets.input-widgets.min-length diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/circle-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/circle-settings.component.html index 3f480cc347..827fb44129 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/circle-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/circle-settings.component.html @@ -119,7 +119,7 @@
widgets.maps.circle-fill-color -
+
widgets.maps.circle-stroke -
+
widgets.maps.common-map-settings -
+
- + widget-config.advanced-settings @@ -65,7 +65,7 @@
-
+
{{ 'widgets.maps.disable-scroll-zooming' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.html index a8c5318142..3c30bba518 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.html @@ -21,7 +21,7 @@
widgets.maps.image-map-background-from-entity-attribute -
+
widgets.maps.image-url-source-entity-alias
widgets.maps.editor-settings - + {{ 'widgets.maps.enable-snapping' | translate }} - + {{ 'widgets.maps.init-draggable-mode' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/marker-clustering-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/marker-clustering-settings.component.html index 9ceb172090..f0dd8e50c5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/marker-clustering-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/marker-clustering-settings.component.html @@ -34,7 +34,7 @@ {{ 'widgets.maps.zoom-on-cluster-click' | translate }} -
+
widgets.maps.max-cluster-zoom @@ -44,23 +44,23 @@
-
- +
+ {{ 'widgets.maps.cluster-zoom-animation' | translate }} - + {{ 'widgets.maps.show-markers-bounds-on-cluster-mouse-over' | translate }}
- + {{ 'widgets.maps.spiderfy-max-zoom-level' | translate }}
widgets.maps.load-optimization - + {{ 'widgets.maps.cluster-chunked-loading' | translate }} - + {{ 'widgets.maps.cluster-markers-lazy-load' | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/markers-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/markers-settings.component.html index ea955f5f7f..ed6c29d9cb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/markers-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/markers-settings.component.html @@ -18,7 +18,7 @@
widgets.maps.markers-settings -
+
widgets.maps.marker-offset-x @@ -113,7 +113,7 @@ functionTitle="{{ 'widgets.maps.tooltip-function' | translate }}" helpId="widget/lib/map/tooltip_fn"> -
+
widgets.maps.tooltip-offset-x diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/polygon-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/polygon-settings.component.html index 8f3f74b1ff..e1553b2615 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/polygon-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/polygon-settings.component.html @@ -119,7 +119,7 @@
widgets.maps.polygon-color -
+
widgets.maps.polygon-stroke -
+
widgets.maps.normalization-step -
+
-
+
widgets.maps.path-settings -
+
-
+
widgets.maps.decorator-symbol @@ -84,7 +84,7 @@
-
+
{{ 'widgets.maps.use-path-decorator-custom-color' | translate }} @@ -95,7 +95,7 @@ label="{{ 'widgets.maps.decorator-custom-color' | translate }}" openOnInput colorClearButton>
-
+
widgets.maps.decorator-offset diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/trip-animation-point-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/trip-animation-point-settings.component.html index e48c690823..efae78727b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/trip-animation-point-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/trip-animation-point-settings.component.html @@ -31,7 +31,7 @@ -
+
Date: Thu, 21 Jul 2022 13:07:15 +0300 Subject: [PATCH 012/158] Rate limits added tenant entity version/load --- ...enant-profile-configuration.component.html | 20 ++++++------------- ...-tenant-profile-configuration.component.ts | 4 ++-- .../rate-limits-details-dialog.component.html | 4 ++-- .../rate-limits-list.component.html | 7 +++++++ .../rate-limits-list.component.scss | 12 +++++------ .../rate-limits/rate-limits.component.html | 13 ++++++------ .../rate-limits/rate-limits.component.scss | 4 ++++ .../app/shared/models/rate-limits.models.ts | 8 ++++++++ .../assets/locale/locale.constant-en_US.json | 6 ++++++ 9 files changed, 47 insertions(+), 31 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html index 5484aaed28..34015f71ad 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html @@ -469,20 +469,12 @@
- - tenant-profile.tenant-entity-export-rate-limit - - - - tenant-profile.tenant-entity-import-rate-limit - - - + + + +
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts index ac2702ca43..5652f7dd71 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts @@ -71,8 +71,8 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA transportDeviceMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], transportDeviceTelemetryMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], transportDeviceTelemetryDataPointsRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - tenantEntityExportRateLimit: [null, []], - tenantEntityImportRateLimit: [null, []], + tenantEntityExportRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], + tenantEntityImportRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], maxTransportMessages: [null, [Validators.required, Validators.min(0)]], maxTransportDataPoints: [null, [Validators.required, Validators.min(0)]], maxREExecutions: [null, [Validators.required, Validators.min(0)]], diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html index 911b44ecd8..751ffe0e2c 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html @@ -15,9 +15,9 @@ limitations under the License. --> -
+ -

{{ title }}

+

{{ title | translate }}

-
- -
+ diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss index 6d45b33b73..1d7e817839 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.scss @@ -28,4 +28,8 @@ font-size: 12px; } } + + .tb-rate-limits-button { + margin-top: 0.5em; + } } diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts index e6b4218773..ffde8a3c87 100644 --- a/ui-ngx/src/app/shared/models/rate-limits.models.ts +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -32,6 +32,8 @@ export enum RateLimitsType { CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION = 'CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION', WS_UPDATE_PER_SESSION_RATE_LIMIT = 'WS_UPDATE_PER_SESSION_RATE_LIMIT', CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION = 'CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION', + TENANT_ENTITY_EXPORT_RATE_LIMIT = 'TENANT_ENTITY_EXPORT_RATE_LIMIT', + TENANT_ENTITY_IMPORT_RATE_LIMIT = 'TENANT_ENTITY_IMPORT_RATE_LIMIT' } export const rateLimitLabelTranslationMap = new Map( @@ -46,6 +48,8 @@ export const rateLimitLabelTranslationMap = new Map( [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.customer-rest-limits'], [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.ws-limit-updates-per-session'], [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.cassandra-tenant-limits-configuration'], + [RateLimitsType.TENANT_ENTITY_EXPORT_RATE_LIMIT, 'tenant-profile.tenant-entity-export-rate-limit'], + [RateLimitsType.TENANT_ENTITY_IMPORT_RATE_LIMIT, 'tenant-profile.tenant-entity-import-rate-limit'], ] ); @@ -61,6 +65,8 @@ export const editRateLimitTranslationMap = new Map( [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-customer-rest-limits-title'], [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.edit-ws-limit-updates-per-session-title'], [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.edit-cassandra-tenant-limits-configuration-title'], + [RateLimitsType.TENANT_ENTITY_EXPORT_RATE_LIMIT, 'tenant-profile.rate-limits.edit-tenant-entity-export-rate-limit-title'], + [RateLimitsType.TENANT_ENTITY_IMPORT_RATE_LIMIT, 'tenant-profile.rate-limits.edit-tenant-entity-import-rate-limit-title'], ] ); @@ -76,6 +82,8 @@ export const addRateLimitTranslationMap = new Map( [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-customer-rest-limits-title'], [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.add-ws-limit-updates-per-session-title'], [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-cassandra-tenant-limits-configuration-title'], + [RateLimitsType.TENANT_ENTITY_EXPORT_RATE_LIMIT, 'tenant-profile.rate-limits.add-tenant-entity-export-rate-limit-title'], + [RateLimitsType.TENANT_ENTITY_IMPORT_RATE_LIMIT, 'tenant-profile.rate-limits.add-tenant-entity-import-rate-limit-title'], ] ); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 8cd65a139e..371ade779c 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3200,6 +3200,8 @@ "add-customer-rest-limits-title": "Add REST requests for customer rate limits", "add-ws-limit-updates-per-session-title": "Add WS updates per session rate limits", "add-cassandra-tenant-limits-configuration-title": "Add Cassandra query for tenant rate limits", + "add-tenant-entity-export-rate-limit-title": "Add entity version creation rate limits", + "add-tenant-entity-import-rate-limit-title": "Add entity version load rate limits", "advanced-settings": "Advanced settings", "edit-limit": "Edit limit", "but-less-than": "but less than", @@ -3213,13 +3215,17 @@ "edit-customer-rest-limits-title": "Edit REST requests for customer rate limits", "edit-ws-limit-updates-per-session-title": "Edit WS updates per session rate limits", "edit-cassandra-tenant-limits-configuration-title": "Edit Cassandra query for tenant rate limits", + "edit-tenant-entity-export-rate-limit-title": "Edit entity version creation rate limits", + "edit-tenant-entity-import-rate-limit-title": "Edit entity version load rate limits", "messages-per": "messages per", "not-set": "Not set", "number-of-messages": "Number of messages", "number-of-messages-required": "Number of messages is required.", + "number-of-messages-min": "Minimum value is 1.", "preview": "Preview", "per-seconds": "Per seconds", "per-seconds-required": "Time rate is required.", + "per-seconds-min": "Minimum value is 1.", "rate-limits": "Rate limits", "remove-limit": "Remove limit", "transport-tenant-msg": "Transport tenant messages", From e74eeed6a8b3c6a3f5e05a1e9acd4f8f5d061a8e Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 13:09:55 +0300 Subject: [PATCH 013/158] Removed Add rate limit titles --- .../rate-limits/rate-limits.component.html | 4 ++-- .../tenant/rate-limits/rate-limits.component.ts | 14 ++------------ .../src/app/shared/models/rate-limits.models.ts | 17 ----------------- .../assets/locale/locale.constant-en_US.json | 12 ------------ 4 files changed, 4 insertions(+), 43 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html index 2c4b82e4ab..3a6591790f 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html @@ -19,14 +19,14 @@
{{ label | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts index 34cbadb755..75318c41cb 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts @@ -30,7 +30,6 @@ import { RateLimitsDetailsDialogData } from '@home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component'; import { - addRateLimitTranslationMap, editRateLimitTranslationMap, rateLimitLabelTranslationMap, RateLimitsType, @@ -106,11 +105,11 @@ export class RateLimitsComponent implements ControlValueAccessor, OnInit, Valida return null; } - public onClick($event: Event, action: string) { + public onClick($event: Event) { if ($event) { $event.stopPropagation(); } - const title = this.setTitle(action); + const title = editRateLimitTranslationMap.get(this.type); this.dialog.open(RateLimitsDetailsDialogComponent, { disableClose: true, @@ -128,15 +127,6 @@ export class RateLimitsComponent implements ControlValueAccessor, OnInit, Valida }); } - private setTitle(action: string): string { - switch (action) { - case 'add': - return addRateLimitTranslationMap.get(this.type); - case 'edit': - return editRateLimitTranslationMap.get(this.type); - } - } - private updateRateLimitsInfo() { this.rateLimitsFormGroup.patchValue( { diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts index ffde8a3c87..f035d9f67c 100644 --- a/ui-ngx/src/app/shared/models/rate-limits.models.ts +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -70,23 +70,6 @@ export const editRateLimitTranslationMap = new Map( ] ); -export const addRateLimitTranslationMap = new Map( - [ - [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.add-transport-tenant-msg-title'], - [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.add-transport-tenant-telemetry-msg-title'], - [RateLimitsType.TENANT_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.add-transport-tenant-telemetry-data-points-title'], - [RateLimitsType.DEVICE_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-msg-title'], - [RateLimitsType.DEVICE_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.add-transport-device-telemetry-msg-title'], - [RateLimitsType.DEVICE_TELEMETRY_DATA_POINTS, 'tenant-profile.rate-limits.add-transport-device-telemetry-data-points-title'], - [RateLimitsType.TENANT_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-transport-tenant-msg-rate-limit-title'], - [RateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-customer-rest-limits-title'], - [RateLimitsType.WS_UPDATE_PER_SESSION_RATE_LIMIT, 'tenant-profile.rate-limits.add-ws-limit-updates-per-session-title'], - [RateLimitsType.CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION, 'tenant-profile.rate-limits.add-cassandra-tenant-limits-configuration-title'], - [RateLimitsType.TENANT_ENTITY_EXPORT_RATE_LIMIT, 'tenant-profile.rate-limits.add-tenant-entity-export-rate-limit-title'], - [RateLimitsType.TENANT_ENTITY_IMPORT_RATE_LIMIT, 'tenant-profile.rate-limits.add-tenant-entity-import-rate-limit-title'], - ] -); - export function stringToRateLimitsArray(rateLimits: string): Array { const result: Array = []; if (rateLimits?.length > 0) { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 371ade779c..612823b803 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3190,18 +3190,6 @@ "ws-limit-updates-per-session": "WS updates per session", "rate-limits": { "add-limit": "Add limit", - "add-transport-tenant-msg-title": "Add transport tenant messages rate limits", - "add-transport-tenant-telemetry-msg-title": "Add transport tenant telemetry messages rate limits", - "add-transport-tenant-telemetry-data-points-title": "Add transport tenant telemetry data points rate limits", - "add-transport-device-msg-title": "Add transport device messages rate limits", - "add-transport-device-telemetry-msg-title": "Add transport device telemetry messages rate limits", - "add-transport-device-telemetry-data-points-title": "Add transport device telemetry data points rate limits", - "add-transport-tenant-msg-rate-limit-title": "Add transport tenant messages rate limits", - "add-customer-rest-limits-title": "Add REST requests for customer rate limits", - "add-ws-limit-updates-per-session-title": "Add WS updates per session rate limits", - "add-cassandra-tenant-limits-configuration-title": "Add Cassandra query for tenant rate limits", - "add-tenant-entity-export-rate-limit-title": "Add entity version creation rate limits", - "add-tenant-entity-import-rate-limit-title": "Add entity version load rate limits", "advanced-settings": "Advanced settings", "edit-limit": "Edit limit", "but-less-than": "but less than", From 9ada3562d56788298036317460cd88a53dd3659c Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 13:11:40 +0300 Subject: [PATCH 014/158] Rate limit dialog minor title refactor --- .../profile/tenant/rate-limits/rate-limits.component.ts | 4 ++-- ui-ngx/src/app/shared/models/rate-limits.models.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts index 75318c41cb..2c320bcbe2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts @@ -30,7 +30,7 @@ import { RateLimitsDetailsDialogData } from '@home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component'; import { - editRateLimitTranslationMap, + rateLimitDialogTitleTranslationMap, rateLimitLabelTranslationMap, RateLimitsType, stringToRateLimitsArray @@ -109,7 +109,7 @@ export class RateLimitsComponent implements ControlValueAccessor, OnInit, Valida if ($event) { $event.stopPropagation(); } - const title = editRateLimitTranslationMap.get(this.type); + const title = rateLimitDialogTitleTranslationMap.get(this.type); this.dialog.open(RateLimitsDetailsDialogComponent, { disableClose: true, diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts index f035d9f67c..272728c647 100644 --- a/ui-ngx/src/app/shared/models/rate-limits.models.ts +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -53,7 +53,7 @@ export const rateLimitLabelTranslationMap = new Map( ] ); -export const editRateLimitTranslationMap = new Map( +export const rateLimitDialogTitleTranslationMap = new Map( [ [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-msg-title'], [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-telemetry-msg-title'], From acadd0f8278a19eef4b5053ee5fbbcc54891885e Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 13:31:00 +0300 Subject: [PATCH 015/158] Rate limits fix close null bug --- .../rate-limits-details-dialog.component.ts | 2 +- .../tenant/rate-limits/rate-limits.component.ts | 11 ++++++----- ui-ngx/src/app/shared/models/rate-limits.models.ts | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts index 69bf5cda4f..790ca57838 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts @@ -72,7 +72,7 @@ export class RateLimitsDetailsDialogComponent extends DialogComponent(RateLimitsDetailsDialogComponent, { disableClose: true, @@ -120,7 +121,7 @@ export class RateLimitsComponent implements ControlValueAccessor, OnInit, Valida readonly: this.disabled } }).afterClosed().subscribe((result) => { - if (result) { + if (result || result === null) { this.modelValue = result; this.updateModel(); } diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/shared/models/rate-limits.models.ts index 272728c647..7185dbdd44 100644 --- a/ui-ngx/src/app/shared/models/rate-limits.models.ts +++ b/ui-ngx/src/app/shared/models/rate-limits.models.ts @@ -36,7 +36,7 @@ export enum RateLimitsType { TENANT_ENTITY_IMPORT_RATE_LIMIT = 'TENANT_ENTITY_IMPORT_RATE_LIMIT' } -export const rateLimitLabelTranslationMap = new Map( +export const rateLimitsLabelTranslationMap = new Map( [ [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.transport-tenant-msg'], [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.transport-tenant-telemetry-msg'], @@ -53,7 +53,7 @@ export const rateLimitLabelTranslationMap = new Map( ] ); -export const rateLimitDialogTitleTranslationMap = new Map( +export const rateLimitsDialogTitleTranslationMap = new Map( [ [RateLimitsType.TENANT_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-msg-title'], [RateLimitsType.TENANT_TELEMETRY_MESSAGES, 'tenant-profile.rate-limits.edit-transport-tenant-telemetry-msg-title'], From b331bbbb2491373a52096590cf02f331c2dcb955 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 13:50:17 +0300 Subject: [PATCH 016/158] Rate limits: changed order --- ...t-tenant-profile-configuration.component.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html index 34015f71ad..847aae7bf1 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html @@ -460,14 +460,6 @@ [type]="rateLimitsType.CUSTOMER_SERVER_REST_LIMITS_CONFIGURATION"> -
- - - - -
@@ -476,6 +468,14 @@ [type]="rateLimitsType.TENANT_ENTITY_IMPORT_RATE_LIMIT">
+
+ + + + +
From 913db7a0d329f132218beaecdc55a2b0098c8d5b Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 15:45:00 +0300 Subject: [PATCH 017/158] - Fixed diabled button in the edit rate limits; - Removed validation by the pattern for the rate limits --- ...-tenant-profile-configuration.component.ts | 25 +++++++++---------- .../rate-limits-list.component.html | 2 ++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts index 5652f7dd71..d44715cc63 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts @@ -36,7 +36,6 @@ import { RateLimitsType } from '@shared/models/rate-limits.models'; export class DefaultTenantProfileConfigurationComponent implements ControlValueAccessor, OnInit { defaultTenantProfileConfigurationFormGroup: FormGroup; - rateLimitsPattern = '([1-9]\\d*:[1-9]\\d*)(,[1-9]\\d*:[1-9]\\d*)*'; private requiredValue: boolean; get required(): boolean { @@ -65,14 +64,14 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA maxRuleChains: [null, [Validators.required, Validators.min(0)]], maxResourcesInBytes: [null, [Validators.required, Validators.min(0)]], maxOtaPackagesInBytes: [null, [Validators.required, Validators.min(0)]], - transportTenantMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - transportTenantTelemetryMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - transportTenantTelemetryDataPointsRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - transportDeviceMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - transportDeviceTelemetryMsgRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - transportDeviceTelemetryDataPointsRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - tenantEntityExportRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - tenantEntityImportRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], + transportTenantMsgRateLimit: [null, []], + transportTenantTelemetryMsgRateLimit: [null, []], + transportTenantTelemetryDataPointsRateLimit: [null, []], + transportDeviceMsgRateLimit: [null, []], + transportDeviceTelemetryMsgRateLimit: [null, []], + transportDeviceTelemetryDataPointsRateLimit: [null, []], + tenantEntityExportRateLimit: [null, []], + tenantEntityImportRateLimit: [null, []], maxTransportMessages: [null, [Validators.required, Validators.min(0)]], maxTransportDataPoints: [null, [Validators.required, Validators.min(0)]], maxREExecutions: [null, [Validators.required, Validators.min(0)]], @@ -85,8 +84,8 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA defaultStorageTtlDays: [null, [Validators.required, Validators.min(0)]], alarmsTtlDays: [null, [Validators.required, Validators.min(0)]], rpcTtlDays: [null, [Validators.required, Validators.min(0)]], - tenantServerRestLimitsConfiguration: [null, [Validators.pattern(this.rateLimitsPattern)]], - customerServerRestLimitsConfiguration: [null, [Validators.pattern(this.rateLimitsPattern)]], + tenantServerRestLimitsConfiguration: [null, []], + customerServerRestLimitsConfiguration: [null, []], maxWsSessionsPerTenant: [null, [Validators.min(0)]], maxWsSessionsPerCustomer: [null, [Validators.min(0)]], maxWsSessionsPerRegularUser: [null, [Validators.min(0)]], @@ -96,8 +95,8 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA maxWsSubscriptionsPerCustomer: [null, [Validators.min(0)]], maxWsSubscriptionsPerRegularUser: [null, [Validators.min(0)]], maxWsSubscriptionsPerPublicUser: [null, [Validators.min(0)]], - wsUpdatesPerSessionRateLimit: [null, [Validators.pattern(this.rateLimitsPattern)]], - cassandraQueryTenantRateLimitsConfiguration: [null, [Validators.pattern(this.rateLimitsPattern)]] + wsUpdatesPerSessionRateLimit: [null, []], + cassandraQueryTenantRateLimitsConfiguration: [null, []] }); this.defaultTenantProfileConfigurationFormGroup.valueChanges.subscribe(() => { this.updateModel(); diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html index 7d1f3e4561..768b351070 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html @@ -47,6 +47,7 @@ class="tb-rate-limits-button" *ngIf="!rateLimitsFormArray().disabled" (click)="removeRateLimits($index)" + [disabled]="disabled" [matTooltip]="'tenant-profile.rate-limits.remove-limit' | translate" matTooltipPosition="above"> remove_circle_outline @@ -55,6 +56,7 @@
From a0fd18221de1c4a0cc43f3dd35f554e473ec8b74 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 21 Jul 2022 16:29:40 +0300 Subject: [PATCH 018/158] Remove redundant import --- .../profile/tenant/rate-limits/rate-limits.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts index 9029d36a9f..753ef133a9 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts @@ -35,7 +35,6 @@ import { RateLimitsType, stringToRateLimitsArray } from '@shared/models/rate-limits.models'; -import { isNull } from 'util'; @Component({ selector: 'tb-rate-limits', From 41c86f3ba491815c8244c21939aa4d65df0d2bb4 Mon Sep 17 00:00:00 2001 From: devaskim Date: Thu, 21 Jul 2022 19:08:26 +0500 Subject: [PATCH 019/158] Add relation tab to user details. --- .../src/app/modules/home/pages/user/user-tabs.component.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui-ngx/src/app/modules/home/pages/user/user-tabs.component.html b/ui-ngx/src/app/modules/home/pages/user/user-tabs.component.html index 6417c2ac9f..7a9243e8a7 100644 --- a/ui-ngx/src/app/modules/home/pages/user/user-tabs.component.html +++ b/ui-ngx/src/app/modules/home/pages/user/user-tabs.component.html @@ -32,6 +32,10 @@ [entityName]="entity.name"> + + + From a720009b55678d30ab5f685ba3acc65934011b2d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 22 Jul 2022 18:53:41 +0300 Subject: [PATCH 020/158] Initial DB structure --- .../server/actors/ActorSystemContext.java | 159 +++++----- .../server/actors/stats/StatsActor.java | 18 +- .../server/controller/EventController.java | 8 +- .../controller/RuleChainController.java | 7 +- .../server/actors/stats/StatsActorTest.java | 3 +- .../AbstractRuleEngineControllerTest.java | 12 +- ...AbstractRuleEngineFlowIntegrationTest.java | 19 +- ...actRuleEngineLifecycleIntegrationTest.java | 18 +- .../server/dao/event/EventService.java | 13 +- .../data/{Event.java => EventInfo.java} | 8 +- .../server/common/data/event/ErrorEvent.java | 48 +++ .../server/common/data/event/Event.java | 42 +++ .../server/common/data/event/EventType.java | 12 +- .../common/data/event/LifecycleEvent.java | 51 ++++ .../data/event/RuleChainDebugEvent.java | 50 +++ .../common/data/event/RuleNodeDebugEvent.java | 75 +++++ .../common/data/event/StatisticsEvent.java | 47 +++ .../server/dao/event/BaseEventService.java | 59 +++- .../server/dao/event/EventDao.java | 13 +- .../server/dao/model/sql/EventEntity.java | 9 +- .../service/validator/EventDataValidator.java | 12 +- .../dao/sql/event/EventInsertRepository.java | 201 ++++++++++-- .../server/dao/sql/event/JpaBaseEventDao.java | 287 ++++++++++-------- .../insert/sql/SqlPartitioningRepository.java | 4 +- .../dao/sqlts/sql/JpaSqlTimeseriesDao.java | 2 +- .../server/dao/timeseries/SqlPartition.java | 10 +- .../main/resources/sql/schema-entities.sql | 68 ++++- .../dao/service/AbstractServiceTest.java | 20 +- .../service/event/BaseEventServiceTest.java | 50 +-- .../dao/sql/event/JpaBaseEventDaoTest.java | 249 ++++++++------- .../thingsboard/rest/client/RestClient.java | 10 +- 31 files changed, 1074 insertions(+), 510 deletions(-) rename common/data/src/main/java/org/thingsboard/server/common/data/{Event.java => EventInfo.java} (93%) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index a38de7b839..e6f207d960 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -37,10 +37,11 @@ import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; import org.thingsboard.server.actors.service.ActorService; import org.thingsboard.server.actors.tenant.DebugTbRateLimits; import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.LifecycleEvent; +import org.thingsboard.server.common.data.event.RuleChainDebugEvent; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.TbActorMsg; @@ -112,6 +113,29 @@ import java.util.concurrent.TimeUnit; @Component public class ActorSystemContext { + private static final FutureCallback RULE_CHAIN_DEBUG_EVENT_ERROR_CALLBACK = new FutureCallback<>() { + @Override + public void onSuccess(@Nullable Void event) { + + } + + @Override + public void onFailure(Throwable th) { + log.error("Could not save debug Event for Rule Chain", th); + } + }; + private static final FutureCallback RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK = new FutureCallback<>() { + @Override + public void onSuccess(@Nullable Void event) { + + } + + @Override + public void onFailure(Throwable th) { + log.error("Could not save debug Event for Node", th); + } + }; + protected final ObjectMapper mapper = new ObjectMapper(); private final ConcurrentMap debugPerTenantLimits = new ConcurrentHashMap<>(); @@ -462,25 +486,28 @@ public class ActorSystemContext { } public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) { - Event event = new Event(); - event.setTenantId(tenantId); - event.setEntityId(entityId); - event.setType(DataConstants.ERROR); - event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), method, toString(e))); - persistEvent(event); + eventService.saveAsync(ErrorEvent.builder() + .tenantId(tenantId) + .entityId(entityId) + .serviceId(getServiceId()) + .method(method) + .error(toString(e)).build()); } public void persistLifecycleEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent lcEvent, Exception e) { - Event event = new Event(); - event.setTenantId(tenantId); - event.setEntityId(entityId); - event.setType(DataConstants.LC_EVENT); - event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), lcEvent, Optional.ofNullable(e))); - persistEvent(event); - } + LifecycleEvent.LifecycleEventBuilder event = LifecycleEvent.builder() + .tenantId(tenantId) + .entityId(entityId) + .serviceId(getServiceId()) + .lcEventType(lcEvent.name()); + + if (e != null) { + event.success(false).error(toString(e)); + } else { + event.success(false); + } - private void persistEvent(Event event) { - eventService.saveAsync(event); + eventService.saveAsync(event.build()); } private String toString(Throwable e) { @@ -489,21 +516,6 @@ public class ActorSystemContext { return sw.toString(); } - private JsonNode toBodyJson(String serviceId, ComponentLifecycleEvent event, Optional e) { - ObjectNode node = mapper.createObjectNode().put("server", serviceId).put("event", event.name()); - if (e.isPresent()) { - node = node.put("success", false); - node = node.put("error", toString(e.get())); - } else { - node = node.put("success", true); - } - return node; - } - - private JsonNode toBodyJson(String serviceId, String method, String body) { - return mapper.createObjectNode().put("server", serviceId).put("method", method).put("error", body); - } - public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) { return partitionService.resolve(serviceType, tenantId, entityId); } @@ -539,44 +551,27 @@ public class ActorSystemContext { private void persistDebugAsync(TenantId tenantId, EntityId entityId, String type, TbMsg tbMsg, String relationType, Throwable error, String failureMessage) { if (checkLimits(tenantId, tbMsg, error)) { try { - Event event = new Event(); - event.setTenantId(tenantId); - event.setEntityId(entityId); - event.setType(DataConstants.DEBUG_RULE_NODE); - - String metadata = mapper.writeValueAsString(tbMsg.getMetaData().getData()); - - ObjectNode node = mapper.createObjectNode() - .put("type", type) - .put("server", getServiceId()) - .put("entityId", tbMsg.getOriginator().getId().toString()) - .put("entityName", tbMsg.getOriginator().getEntityType().name()) - .put("msgId", tbMsg.getId().toString()) - .put("msgType", tbMsg.getType()) - .put("dataType", tbMsg.getDataType().name()) - .put("relationType", relationType) - .put("data", tbMsg.getData()) - .put("metadata", metadata); + RuleNodeDebugEvent.RuleNodeDebugEventBuilder event = RuleNodeDebugEvent.builder() + .tenantId(tenantId) + .entityId(entityId) + .serviceId(getServiceId()) + .eventType(type) + .eventEntity(tbMsg.getOriginator()) + .msgId(tbMsg.getId()) + .msgType(tbMsg.getType()) + .dataType(tbMsg.getDataType().name()) + .relationType(relationType) + .data(tbMsg.getData()) + .metadata(mapper.writeValueAsString(tbMsg.getMetaData().getData())); if (error != null) { - node = node.put("error", toString(error)); + event.error(toString(error)); } else if (failureMessage != null) { - node = node.put("error", failureMessage); + event.error(failureMessage); } - event.setBody(node); - ListenableFuture future = eventService.saveAsync(event); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable Void event) { - - } - - @Override - public void onFailure(Throwable th) { - log.error("Could not save debug Event for Node", th); - } - }, MoreExecutors.directExecutor()); + ListenableFuture future = eventService.saveAsync(event.build()); + Futures.addCallback(future, RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor()); } catch (IOException ex) { log.warn("Failed to persist rule node debug message", ex); } @@ -603,33 +598,17 @@ public class ActorSystemContext { } private void persistRuleChainDebugModeEvent(TenantId tenantId, EntityId entityId, Throwable error) { - Event event = new Event(); - event.setTenantId(tenantId); - event.setEntityId(entityId); - event.setType(DataConstants.DEBUG_RULE_CHAIN); - - ObjectNode node = mapper.createObjectNode() - //todo: what fields are needed here? - .put("server", getServiceId()) - .put("message", "Reached debug mode rate limit!"); - + RuleChainDebugEvent.RuleChainDebugEventBuilder event = RuleChainDebugEvent.builder() + .tenantId(tenantId) + .entityId(entityId) + .serviceId(getServiceId()) + .message("Reached debug mode rate limit!"); if (error != null) { - node = node.put("error", toString(error)); + event.error(toString(error)); } - event.setBody(node); - ListenableFuture future = eventService.saveAsync(event); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable Void event) { - - } - - @Override - public void onFailure(Throwable th) { - log.error("Could not save debug Event for Rule Chain", th); - } - }, MoreExecutors.directExecutor()); + ListenableFuture future = eventService.saveAsync(event.build()); + Futures.addCallback(future, RULE_CHAIN_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor()); } public static Exception toException(Throwable error) { diff --git a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java index 8cdf5cec02..fa5dedf66f 100644 --- a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java @@ -20,13 +20,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActor; -import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorId; import org.thingsboard.server.actors.TbStringActorId; import org.thingsboard.server.actors.service.ContextAwareActor; import org.thingsboard.server.actors.service.ContextBasedCreator; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.common.msg.MsgType; import org.thingsboard.server.common.msg.TbActorMsg; @@ -54,12 +54,14 @@ public class StatsActor extends ContextAwareActor { if (msg.isEmpty()) { return; } - Event event = new Event(); - event.setEntityId(msg.getEntityId()); - event.setTenantId(msg.getTenantId()); - event.setType(DataConstants.STATS); - event.setBody(toBodyJson(systemContext.getServiceInfoProvider().getServiceId(), msg.getMessagesProcessed(), msg.getErrorsOccurred())); - systemContext.getEventService().saveAsync(event); + systemContext.getEventService().saveAsync(StatisticsEvent.builder() + .tenantId(msg.getTenantId()) + .entityId(msg.getEntityId()) + .serviceId(systemContext.getServiceInfoProvider().getServiceId()) + .messagesProcessed(msg.getMessagesProcessed()) + .errorsOccurred(msg.getErrorsOccurred()) + .build() + ); } private JsonNode toBodyJson(String serviceId, long messagesProcessed, long errorsOccurred) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index ac56978536..dd6c05749f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.event.EventFilter; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EntityId; @@ -110,7 +110,7 @@ public class EventController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET) @ResponseBody - public PageData getEvents( + public PageData getEvents( @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @@ -153,7 +153,7 @@ public class EventController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody - public PageData getEvents( + public PageData getEvents( @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @@ -198,7 +198,7 @@ public class EventController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) @ResponseBody - public PageData getEvents( + public PageData getEvents( @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index faa1711fd9..143844504a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -40,7 +40,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.tenant.DebugTbRateLimits; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -70,7 +70,6 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -353,10 +352,10 @@ public class RuleChainController extends BaseController { RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId)); checkRuleNode(ruleNodeId, Operation.READ); TenantId tenantId = getCurrentUser().getTenantId(); - List events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2); + List events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2); JsonNode result = null; if (events != null) { - for (Event event : events) { + for (EventInfo event : events) { JsonNode body = event.getBody(); if (body.has("type") && body.get("type").asText().equals("IN")) { result = body; diff --git a/application/src/test/java/org/thingsboard/server/actors/stats/StatsActorTest.java b/application/src/test/java/org/thingsboard/server/actors/stats/StatsActorTest.java index 0e928b7dd6..d4d9456a3f 100644 --- a/application/src/test/java/org/thingsboard/server/actors/stats/StatsActorTest.java +++ b/application/src/test/java/org/thingsboard/server/actors/stats/StatsActorTest.java @@ -18,7 +18,8 @@ package org.thingsboard.server.actors.stats; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.thingsboard.server.actors.ActorSystemContext; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java index ab902b82c6..7335c10d13 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; @@ -60,20 +60,20 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle return doGet("/api/ruleChain/metadata/" + ruleChainId.getId().toString(), RuleChainMetaData.class); } - protected PageData getDebugEvents(TenantId tenantId, EntityId entityId, int limit) throws Exception { + protected PageData getDebugEvents(TenantId tenantId, EntityId entityId, int limit) throws Exception { return getEvents(tenantId, entityId, DataConstants.DEBUG_RULE_NODE, limit); } - protected PageData getEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) throws Exception { + protected PageData getEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) throws Exception { TimePageLink pageLink = new TimePageLink(limit); return doGetTypedWithTimePageLink("/api/events/{entityType}/{entityId}/{eventType}?tenantId={tenantId}&", - new TypeReference>() { + new TypeReference>() { }, pageLink, entityId.getEntityType(), entityId.getId(), eventType, tenantId.getId()); } - protected JsonNode getMetadata(Event outEvent) { + protected JsonNode getMetadata(EventInfo outEvent) { String metaDataStr = outEvent.getBody().get("metadata").asText(); try { return mapper.readTree(metaDataStr); @@ -82,7 +82,7 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle } } - protected Predicate filterByCustomEvent() { + protected Predicate filterByCustomEvent() { return event -> event.getBody().get("msgType").textValue().equals("CUSTOM"); } diff --git a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java index 9d96fe9d9c..24c94adba6 100644 --- a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java @@ -30,9 +30,10 @@ import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.page.PageData; @@ -177,15 +178,15 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule actorSystem.tell(qMsg); Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); - PageData eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000); - List events = eventsPage.getData().stream().filter(filterByCustomEvent()).collect(Collectors.toList()); + PageData eventsPage = getDebugEvents(savedTenant.getId(), ruleChain.getFirstRuleNodeId(), 1000); + List events = eventsPage.getData().stream().filter(filterByCustomEvent()).collect(Collectors.toList()); Assert.assertEquals(2, events.size()); - Event inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); + EventInfo inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); Assert.assertEquals(ruleChain.getFirstRuleNodeId(), inEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), inEvent.getBody().get("entityId").asText()); - Event outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); + EventInfo outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); Assert.assertEquals(ruleChain.getFirstRuleNodeId(), outEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), outEvent.getBody().get("entityId").asText()); @@ -299,16 +300,16 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule Mockito.verify(tbMsgCallback, Mockito.timeout(10000)).onSuccess(); - PageData eventsPage = getDebugEvents(savedTenant.getId(), rootRuleChain.getFirstRuleNodeId(), 1000); - List events = eventsPage.getData().stream().filter(filterByCustomEvent()).collect(Collectors.toList()); + PageData eventsPage = getDebugEvents(savedTenant.getId(), rootRuleChain.getFirstRuleNodeId(), 1000); + List events = eventsPage.getData().stream().filter(filterByCustomEvent()).collect(Collectors.toList()); Assert.assertEquals(2, events.size()); - Event inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); + EventInfo inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); Assert.assertEquals(rootRuleChain.getFirstRuleNodeId(), inEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), inEvent.getBody().get("entityId").asText()); - Event outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); + EventInfo outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); Assert.assertEquals(rootRuleChain.getFirstRuleNodeId(), outEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), outEvent.getBody().get("entityId").asText()); diff --git a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java index 5d86e6a2a5..c840cf4c9a 100644 --- a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java @@ -20,18 +20,14 @@ import org.awaitility.Awaitility; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.ClassRule; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.context.support.TestPropertySourceUtils; -import org.testcontainers.containers.GenericContainer; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.rule.RuleChain; @@ -109,11 +105,11 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac Assert.assertNotNull(ruleChainFinal.getFirstRuleNodeId()); //TODO find out why RULE_NODE update event did not appear all the time - List rcEvents = Awaitility.await("Rule Node started successfully") + List rcEvents = Awaitility.await("Rule Node started successfully") .pollInterval(10, MILLISECONDS) .atMost(TIMEOUT, TimeUnit.SECONDS) .until(() -> { - List debugEvents = getEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), DataConstants.LC_EVENT, 1000) + List debugEvents = getEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), DataConstants.LC_EVENT, 1000) .getData().stream().filter(e -> { var body = e.getBody(); return body.has("event") && body.get("event").asText().equals("STARTED") @@ -145,11 +141,11 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac log.warn("awaiting tbMsgCallback"); Mockito.verify(tbMsgCallback, Mockito.timeout(TimeUnit.SECONDS.toMillis(TIMEOUT))).onSuccess(); log.warn("awaiting events"); - List events = Awaitility.await("get debug by custom event") + List events = Awaitility.await("get debug by custom event") .pollInterval(10, MILLISECONDS) .atMost(TIMEOUT, TimeUnit.SECONDS) .until(() -> { - List debugEvents = getDebugEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), 1000) + List debugEvents = getDebugEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), 1000) .getData().stream().filter(filterByCustomEvent()).collect(Collectors.toList()); log.warn("filtered debug events [{}]", debugEvents.size()); debugEvents.forEach((e) -> log.warn("event: {}", e)); @@ -158,11 +154,11 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac x -> x.size() == 2); log.warn("asserting.."); - Event inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); + EventInfo inEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.IN)).findFirst().get(); Assert.assertEquals(ruleChainFinal.getFirstRuleNodeId(), inEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), inEvent.getBody().get("entityId").asText()); - Event outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); + EventInfo outEvent = events.stream().filter(e -> e.getBody().get("type").asText().equals(DataConstants.OUT)).findFirst().get(); Assert.assertEquals(ruleChainFinal.getFirstRuleNodeId(), outEvent.getEntityId()); Assert.assertEquals(device.getId().getId().toString(), outEvent.getBody().get("entityId").asText()); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 83624df8e3..0d157e755d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -16,7 +16,8 @@ package org.thingsboard.server.dao.event; import com.google.common.util.concurrent.ListenableFuture; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.event.EventFilter; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -30,15 +31,15 @@ public interface EventService { ListenableFuture saveAsync(Event event); - Optional findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid); + Optional findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid); - PageData findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink); + PageData findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink); - PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink); + PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink); - List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit); + List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit); - PageData findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); + PageData findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); void removeEvents(TenantId tenantId, EntityId entityId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Event.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java similarity index 93% rename from common/data/src/main/java/org/thingsboard/server/common/data/Event.java rename to common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 29ab33d075..f6c4ee69fb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Event.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; */ @Data @ApiModel -public class Event extends BaseData { +public class EventInfo extends BaseData { @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @@ -41,15 +41,15 @@ public class Event extends BaseData { @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode") private transient JsonNode body; - public Event() { + public EventInfo() { super(); } - public Event(EventId id) { + public EventInfo(EventId id) { super(id); } - public Event(Event event) { + public EventInfo(EventInfo event) { super(event); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java new file mode 100644 index 0000000000..8e06177ca6 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java @@ -0,0 +1,48 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +@ToString +@EqualsAndHashCode(callSuper = true) +public class ErrorEvent extends Event { + + private static final long serialVersionUID = 960461434033192571L; + + @Builder + private ErrorEvent(TenantId tenantId, EntityId entityId, String serviceId, String method, String error) { + super(tenantId, entityId, serviceId); + this.method = method; + this.error = error; + } + + @Getter @Setter + private String method; + @Getter @Setter + private String error; + + @Override + public EventType getType() { + return EventType.ERROR; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java new file mode 100644 index 0000000000..9c013e1486 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java @@ -0,0 +1,42 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.thingsboard.server.common.data.BaseData; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EventId; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@EqualsAndHashCode(callSuper = true) +public abstract class Event extends BaseData { + + private final TenantId tenantId; + private final EntityId entityId; + private final String serviceId; + + public Event(TenantId tenantId, EntityId entityId, String serviceId) { + super(); + this.tenantId = tenantId != null ? tenantId : TenantId.SYS_TENANT_ID; + this.entityId = entityId; + this.serviceId = serviceId; + } + + public abstract EventType getType(); + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java index 2645e7cce3..8d58158521 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java @@ -15,6 +15,16 @@ */ package org.thingsboard.server.common.data.event; +import lombok.Getter; + public enum EventType { - ERROR, LC_EVENT, STATS, DEBUG_RULE_NODE, DEBUG_RULE_CHAIN + ERROR("error_event"), LC_EVENT("lc_event"), STATS("stats_event"), DEBUG_RULE_NODE("rule_node_debug_event"), DEBUG_RULE_CHAIN("rule_chain_debug_event"); + + @Getter + private final String table; + + EventType(String table) { + this.table = table; + } + } \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java new file mode 100644 index 0000000000..217955af96 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java @@ -0,0 +1,51 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +@ToString +@EqualsAndHashCode(callSuper = true) +public class LifecycleEvent extends Event { + + private static final long serialVersionUID = -3247420461850911549L; + + @Builder + private LifecycleEvent(TenantId tenantId, EntityId entityId, String serviceId, String lcEventType, boolean success, String error) { + super(tenantId, entityId, serviceId); + this.lcEventType = lcEventType; + this.success = success; + this.error = error; + } + + @Getter + private final String lcEventType; + @Getter + private final boolean success; + @Getter @Setter + private String error; + + @Override + public EventType getType() { + return EventType.LC_EVENT; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java new file mode 100644 index 0000000000..ac8c16c2e5 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java @@ -0,0 +1,50 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +import java.util.UUID; + +@ToString +@EqualsAndHashCode(callSuper = true) +public class RuleChainDebugEvent extends Event { + + private static final long serialVersionUID = -386392236201116767L; + + @Builder + private RuleChainDebugEvent(TenantId tenantId, EntityId entityId, String serviceId, String message, String error) { + super(tenantId, entityId, serviceId); + this.message = message; + this.error = error; + } + + @Getter @Setter + private String message; + @Getter @Setter + private String error; + + @Override + public EventType getType() { + return EventType.DEBUG_RULE_CHAIN; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java new file mode 100644 index 0000000000..f9280d2d6b --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java @@ -0,0 +1,75 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +import java.util.UUID; + +@ToString +@EqualsAndHashCode(callSuper = true) +public class RuleNodeDebugEvent extends Event { + + private static final long serialVersionUID = -6575797430064573984L; + + @Builder + private RuleNodeDebugEvent(TenantId tenantId, EntityId entityId, String serviceId, + String eventType, EntityId eventEntity, UUID msgId, + String msgType, String dataType, String relationType, + String data, String metadata, String error) { + super(tenantId, entityId, serviceId); + this.eventType = eventType; + this.eventEntity = eventEntity; + this.msgId = msgId; + this.msgType = msgType; + this.dataType = dataType; + this.relationType = relationType; + this.data = data; + this.metadata = metadata; + this.error = error; + } + + @Getter + private final String eventType; + @Getter + private final EntityId eventEntity; + @Getter + private final UUID msgId; + @Getter + private final String msgType; + @Getter + private final String dataType; + @Getter + private final String relationType; + @Getter @Setter + private String data; + @Getter @Setter + private String metadata; + @Getter @Setter + private String error; + + //TODO: rename the enum constant + @Override + public EventType getType() { + return EventType.DEBUG_RULE_NODE; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java new file mode 100644 index 0000000000..b0194762de --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java @@ -0,0 +1,47 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +@ToString +@EqualsAndHashCode(callSuper = true) +public class StatisticsEvent extends Event { + + private static final long serialVersionUID = 6683733979448910631L; + + @Builder + private StatisticsEvent(TenantId tenantId, EntityId entityId, String serviceId, long messagesProcessed, long errorsOccurred) { + super(tenantId, entityId, serviceId); + this.messagesProcessed = messagesProcessed; + this.errorsOccurred = errorsOccurred; + } + + @Getter + private final long messagesProcessed; + @Getter + private final long errorsOccurred; + + @Override + public EventType getType() { + return EventType.STATS; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 3937bbd9c3..d7f0885bdc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -15,15 +15,19 @@ */ package org.thingsboard.server.dao.event; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.event.EventFilter; +import org.thingsboard.server.common.data.event.LifecycleEvent; +import org.thingsboard.server.common.data.event.RuleChainDebugEvent; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.IdBased; import org.thingsboard.server.common.data.id.TenantId; @@ -34,6 +38,8 @@ import org.thingsboard.server.dao.service.DataValidator; import java.util.List; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; import java.util.stream.Collectors; @Service @@ -57,18 +63,41 @@ public class BaseEventService implements EventService { } private void checkAndTruncateDebugEvent(Event event) { - if (event.getType().startsWith("DEBUG") && event.getBody() != null && event.getBody().has("data")) { - String dataStr = event.getBody().get("data").asText(); - int length = dataStr.length(); + switch (event.getType()) { + case DEBUG_RULE_NODE: + RuleNodeDebugEvent rnEvent = (RuleNodeDebugEvent) event; + truncateField(rnEvent, RuleNodeDebugEvent::getData, RuleNodeDebugEvent::setData); + truncateField(rnEvent, RuleNodeDebugEvent::getMetadata, RuleNodeDebugEvent::setMetadata); + truncateField(rnEvent, RuleNodeDebugEvent::getError, RuleNodeDebugEvent::setError); + break; + case DEBUG_RULE_CHAIN: + RuleChainDebugEvent rcEvent = (RuleChainDebugEvent) event; + truncateField(rcEvent, RuleChainDebugEvent::getMessage, RuleChainDebugEvent::setMessage); + truncateField(rcEvent, RuleChainDebugEvent::getError, RuleChainDebugEvent::setError); + break; + case LC_EVENT: + LifecycleEvent lcEvent = (LifecycleEvent) event; + truncateField(lcEvent, LifecycleEvent::getError, LifecycleEvent::setError); + break; + case ERROR: + ErrorEvent eEvent = (ErrorEvent) event; + truncateField(eEvent, ErrorEvent::getError, ErrorEvent::setError); + break; + } + } + + private void truncateField(T event, Function getter, BiConsumer setter) { + var str = getter.apply(event); + if (StringUtils.isNotEmpty(str)) { + var length = str.length(); if (length > maxDebugEventSymbols) { - ((ObjectNode) event.getBody()).put("data", dataStr.substring(0, maxDebugEventSymbols) + "...[truncated " + (length - maxDebugEventSymbols) + " symbols]"); - log.trace("[{}] Event was truncated: {}", event.getId(), dataStr); + setter.accept(event, str.substring(0, maxDebugEventSymbols) + "...[truncated " + (length - maxDebugEventSymbols) + " symbols]"); } } } @Override - public Optional findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid) { + public Optional findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid) { if (tenantId == null) { throw new DataValidationException("Tenant id should be specified!."); } @@ -81,27 +110,27 @@ public class BaseEventService implements EventService { if (StringUtils.isEmpty(eventUid)) { throw new DataValidationException("Event uid should be specified!."); } - Event event = eventDao.findEvent(tenantId.getId(), entityId, eventType, eventUid); + EventInfo event = eventDao.findEvent(tenantId.getId(), entityId, eventType, eventUid); return event != null ? Optional.of(event) : Optional.empty(); } @Override - public PageData findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) { + public PageData findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) { return eventDao.findEvents(tenantId.getId(), entityId, pageLink); } @Override - public PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { + public PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { return eventDao.findEvents(tenantId.getId(), entityId, eventType, pageLink); } @Override - public List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) { + public List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) { return eventDao.findLatestEvents(tenantId.getId(), entityId, eventType, limit); } @Override - public PageData findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) { + public PageData findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) { return eventDao.findEventByFilter(tenantId.getId(), entityId, eventFilter, pageLink); } @@ -113,7 +142,7 @@ public class BaseEventService implements EventService { @Override public void removeEvents(TenantId tenantId, EntityId entityId, EventFilter eventFilter, Long startTime, Long endTime) { TimePageLink eventsPageLink = new TimePageLink(1000, 0, null, null, startTime, endTime); - PageData eventsPageData; + PageData eventsPageData; do { if (eventFilter == null) { eventsPageData = findEvents(tenantId, entityId, eventsPageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java b/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java index 86eb0d91ec..30815bd15e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java @@ -16,7 +16,8 @@ package org.thingsboard.server.dao.event; import com.google.common.util.concurrent.ListenableFuture; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.event.EventFilter; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.page.PageData; @@ -48,7 +49,7 @@ public interface EventDao extends Dao { * @param eventUid the eventUid * @return the event */ - Event findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid); + EventInfo findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid); /** * Find events by tenantId, entityId and pageLink. @@ -58,7 +59,7 @@ public interface EventDao extends Dao { * @param pageLink the pageLink * @return the event list */ - PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink); + PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink); /** * Find events by tenantId, entityId, eventType and pageLink. @@ -69,9 +70,9 @@ public interface EventDao extends Dao { * @param pageLink the pageLink * @return the event list */ - PageData findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink); + PageData findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink); - PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); + PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); /** * Find latest events by tenantId, entityId and eventType. @@ -82,7 +83,7 @@ public interface EventDao extends Dao { * @param limit the limit * @return the event list */ - List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit); + List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit); /** * Executes stored procedure to cleanup old events. Uses separate ttl for debug and other events. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java index b452ec5bda..bf08333e7b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java @@ -22,7 +22,8 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EventId; import org.thingsboard.server.common.data.id.TenantId; @@ -78,7 +79,7 @@ public class EventEntity extends BaseSqlEntity implements BaseEntity implements BaseEntity { @Override protected void validateDataImpl(TenantId tenantId, Event event) { + if (event.getTenantId() == null) { + throw new DataValidationException("Tenant id should be specified!."); + } if (event.getEntityId() == null) { throw new DataValidationException("Entity id should be specified!."); } - if (StringUtils.isEmpty(event.getType())) { - throw new DataValidationException("Event type should be specified!."); - } - if (event.getBody() == null) { - throw new DataValidationException("Event body should be specified!."); + if (StringUtils.isEmpty(event.getServiceId())) { + throw new DataValidationException("Service id should be specified!."); } } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java index 6234db58da..e69b8578df 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.dao.sql.event; +import org.jetbrains.annotations.NotNull; +import org.postgresql.core.Oid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.BatchPreparedStatementSetter; @@ -24,12 +26,24 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import org.thingsboard.server.dao.model.sql.EventEntity; +import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.Event; +import org.thingsboard.server.common.data.event.EventType; +import org.thingsboard.server.common.data.event.LifecycleEvent; +import org.thingsboard.server.common.data.event.RuleChainDebugEvent; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; +import org.thingsboard.server.common.data.event.StatisticsEvent; +import javax.annotation.PostConstruct; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.Types; import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; +import java.util.stream.Collectors; @Repository @Transactional @@ -39,10 +53,7 @@ public class EventInsertRepository { private static final String EMPTY_STR = ""; - private static final String INSERT = - "INSERT INTO event (id, created_time, body, entity_id, entity_type, event_type, event_uid, tenant_id, ts) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " + - "ON CONFLICT DO NOTHING;"; + private final Map insertStmtMap = new ConcurrentHashMap<>(); @Autowired protected JdbcTemplate jdbcTemplate; @@ -53,34 +64,172 @@ public class EventInsertRepository { @Value("${sql.remove_null_chars:true}") private boolean removeNullChars; - protected void save(List entities) { + @PostConstruct + public void init() { + insertStmtMap.put(EventType.ERROR, "INSERT INTO " + EventType.ERROR.getTable() + + " (id, tenant_id, ts, entity_id, service_id, e_method, e_error) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;"); + insertStmtMap.put(EventType.LC_EVENT, "INSERT INTO " + EventType.LC_EVENT.getTable() + + " (id, tenant_id, ts, entity_id, service_id, e_type, e_success, e_error) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;"); + insertStmtMap.put(EventType.STATS, "INSERT INTO " + EventType.STATS.getTable() + + " (id, tenant_id, ts, entity_id, service_id, e_messages_processed, e_errors_occured) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;"); + insertStmtMap.put(EventType.DEBUG_RULE_NODE, "INSERT INTO " + EventType.DEBUG_RULE_NODE.getTable() + + " (id, tenant_id, ts, entity_id, service_id, e_type, e_entity_id, e_entity_type, e_msg_id, e_msg_type, e_data_type, e_relation_type, e_data, e_metadata, e_error) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;"); + insertStmtMap.put(EventType.DEBUG_RULE_CHAIN, "INSERT INTO " + EventType.DEBUG_RULE_CHAIN.getTable() + + " (id, tenant_id, ts, entity_id, service_id, e_message, e_error) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;"); + } + + protected void save(List entities) { + Map> eventsByType = entities.stream().collect(Collectors.groupingBy(Event::getType, Collectors.toList())); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { - jdbcTemplate.batchUpdate(INSERT, new BatchPreparedStatementSetter() { - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - EventEntity event = entities.get(i); - ps.setObject(1, event.getId()); - ps.setLong(2, event.getCreatedTime()); - ps.setString(3, replaceNullChars(event.getBody().toString())); - ps.setObject(4, event.getEntityId()); - ps.setString(5, event.getEntityType().name()); - ps.setString(6, event.getEventType()); - ps.setString(7, event.getEventUid()); - ps.setObject(8, event.getTenantId()); - ps.setLong(9, event.getTs()); - } - - @Override - public int getBatchSize() { - return entities.size(); - } - }); + for (var entry : eventsByType.entrySet()) { + jdbcTemplate.batchUpdate(insertStmtMap.get(entry.getKey()), getStatementSetter(entry.getKey(), entry.getValue())); + } } }); } + private BatchPreparedStatementSetter getStatementSetter(EventType eventType, List events) { + switch (eventType) { + case ERROR: + return getErrorEventSetter(events); + case LC_EVENT: + return getLcEventSetter(events); + case STATS: + return getStatsEventSetter(events); + case DEBUG_RULE_NODE: + return getRuleNodeEventSetter(events); + case DEBUG_RULE_CHAIN: + return getRuleChainEventSetter(events); + default: + throw new RuntimeException(eventType + " support is not implemented!"); + } + } + + private BatchPreparedStatementSetter getErrorEventSetter(List events) { + return new BatchPreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + ErrorEvent event = (ErrorEvent) events.get(i); + setCommonEventFields(ps, event); + safePutString(ps, 6, event.getMethod()); + safePutString(ps, 7, event.getError()); + } + + @Override + public int getBatchSize() { + return events.size(); + } + }; + } + + private BatchPreparedStatementSetter getLcEventSetter(List events) { + return new BatchPreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + LifecycleEvent event = (LifecycleEvent) events.get(i); + setCommonEventFields(ps, event); + safePutString(ps, 6, event.getLcEventType()); + ps.setBoolean(7, event.isSuccess()); + safePutString(ps, 8, event.getError()); + } + + @Override + public int getBatchSize() { + return events.size(); + } + }; + } + + private BatchPreparedStatementSetter getStatsEventSetter(List events) { + return new BatchPreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + StatisticsEvent event = (StatisticsEvent) events.get(i); + setCommonEventFields(ps, event); + ps.setLong(6, event.getMessagesProcessed()); + ps.setLong(7, event.getErrorsOccurred()); + } + + @Override + public int getBatchSize() { + return events.size(); + } + }; + } + + private BatchPreparedStatementSetter getRuleNodeEventSetter(List events) { + return new BatchPreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + RuleNodeDebugEvent event = (RuleNodeDebugEvent) events.get(i); + setCommonEventFields(ps, event); + safePutString(ps, 6, event.getEventType()); + safePutUUID(ps, 7, event.getEntityId() != null ? event.getEntityId().getId() : null); + safePutString(ps, 8, event.getEntityId() != null ? event.getEntityId().getEntityType().name() : null); + safePutUUID(ps, 9, event.getMsgId()); + safePutString(ps, 10, event.getMsgType()); + safePutString(ps, 11, event.getDataType()); + safePutString(ps, 12, event.getRelationType()); + safePutString(ps, 13, event.getData()); + safePutString(ps, 14, event.getMetadata()); + safePutString(ps, 15, event.getError()); + } + + @Override + public int getBatchSize() { + return events.size(); + } + }; + } + + private BatchPreparedStatementSetter getRuleChainEventSetter(List events) { + return new BatchPreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + RuleChainDebugEvent event = (RuleChainDebugEvent) events.get(i); + setCommonEventFields(ps, event); + safePutString(ps, 6, event.getMessage()); + safePutString(ps, 7, event.getError()); + } + + @Override + public int getBatchSize() { + return events.size(); + } + }; + } + + void safePutString(PreparedStatement ps, int parameterIdx, String value) throws SQLException { + if (value != null) { + ps.setString(parameterIdx, replaceNullChars(value)); + } else { + ps.setNull(parameterIdx, Types.VARCHAR); + } + } + + void safePutUUID(PreparedStatement ps, int parameterIdx, UUID value) throws SQLException { + if (value != null) { + ps.setObject(parameterIdx, value); + } else { + ps.setNull(parameterIdx, Types.OTHER); + } + } + + private void setCommonEventFields(PreparedStatement ps, Event event) throws SQLException { + ps.setObject(1, event.getId().getId()); + ps.setObject(2, event.getTenantId().getId()); + ps.setLong(3, event.getCreatedTime()); + ps.setObject(4, event.getEntityId().getId()); + ps.setString(5, event.getServiceId()); + } + private String replaceNullChars(String strValue) { if (removeNullChars && strValue != null) { return PATTERN_THREAD_LOCAL.get().matcher(strValue).replaceAll(EMPTY_STR); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index 2b409006d2..deb3c87402 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java @@ -19,15 +19,19 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.event.DebugEvent; import org.thingsboard.server.common.data.event.ErrorEventFilter; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.event.EventFilter; +import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.event.LifeCycleEventFilter; import org.thingsboard.server.common.data.event.StatisticsEventFilter; import org.thingsboard.server.common.data.id.EntityId; @@ -42,17 +46,27 @@ import org.thingsboard.server.dao.sql.JpaAbstractDao; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; +import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; +import org.thingsboard.server.dao.timeseries.SqlPartition; +import org.thingsboard.server.dao.timeseries.SqlTsPartitionDate; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; - /** * Created by Valerii Sosliuk on 5/3/2017. */ @@ -60,7 +74,12 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @Component public class JpaBaseEventDao extends JpaAbstractDao implements EventDao { - private final UUID systemTenantId = NULL_UUID; + private static final long PARTITION_DURATION = TimeUnit.HOURS.toMillis(1); + private final Map> partitionsByEventType = new ConcurrentHashMap<>(); + private static final ReentrantLock partitionCreationLock = new ReentrantLock(); + + @Autowired + private SqlPartitioningRepository partitioningRepository; @Autowired private EventRepository eventRepository; @@ -102,10 +121,13 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen @Value("${sql.batch_sort:false}") private boolean batchSortEnabled; - private TbSqlBlockingQueueWrapper queue; + private TbSqlBlockingQueueWrapper queue; @PostConstruct private void init() { + for (EventType eventType : EventType.values()) { + partitionsByEventType.put(eventType, new ConcurrentHashMap<>()); + } TbSqlBlockingQueueParams params = TbSqlBlockingQueueParams.builder() .logName("Events") .batchSize(batchSize) @@ -114,11 +136,9 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen .statsNamePrefix("events") .batchSortEnabled(batchSortEnabled) .build(); - Function hashcodeFunction = entity -> entity.getEntityId().hashCode(); + Function hashcodeFunction = entity -> Objects.hash(super.hashCode(), entity.getTenantId(), entity.getEntityId()); queue = new TbSqlBlockingQueueWrapper<>(params, hashcodeFunction, batchThreads, statsFactory); - queue.init(logExecutor, v -> eventInsertRepository.save(v), - Comparator.comparing((EventEntity eventEntity) -> eventEntity.getTs()) - ); + queue.init(logExecutor, v -> eventInsertRepository.save(v), Comparator.comparing(Event::getCreatedTime)); } @PreDestroy @@ -143,68 +163,80 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen event.setCreatedTime(System.currentTimeMillis()); } } - if (StringUtils.isEmpty(event.getUid())) { - event.setUid(event.getId().toString()); - } - - return save(new EventEntity(event)); + savePartitionIfNotExist(event); + return queue.add(event); } - private ListenableFuture save(EventEntity entity) { - log.debug("Save event [{}] ", entity); - if (entity.getTenantId() == null) { - log.trace("Save system event with predefined id {}", systemTenantId); - entity.setTenantId(systemTenantId); - } - if (entity.getUuid() == null) { - entity.setUuid(Uuids.timeBased()); - } - if (StringUtils.isEmpty(entity.getEventUid())) { - entity.setEventUid(entity.getUuid().toString()); + private void savePartitionIfNotExist(Event event) { + var partitionsMap = partitionsByEventType.get(event.getType()); + long partitionStartTs = event.getCreatedTime() - (event.getCreatedTime() % PARTITION_DURATION); + if (partitionsMap.get(partitionStartTs) == null) { + long partitionEndTs = partitionStartTs + PARTITION_DURATION; + savePartition(partitionsMap, new SqlPartition(event.getType().getTable(), partitionStartTs, partitionEndTs, Long.toString(partitionStartTs))); } - return addToQueue(entity); } - private ListenableFuture addToQueue(EventEntity entity) { - return queue.add(entity); + private void savePartition(Map partitionsMap, SqlPartition sqlPartition) { + if (!partitionsMap.containsKey(sqlPartition.getStart())) { + partitionCreationLock.lock(); + try { + log.trace("Saving partition: {}", sqlPartition); + partitioningRepository.save(sqlPartition); + log.trace("Adding partition to map: {}", sqlPartition); + partitionsMap.put(sqlPartition.getStart(), sqlPartition); + } catch (DataIntegrityViolationException ex) { + log.trace("Error occurred during partition save:", ex); + if (ex.getCause() instanceof ConstraintViolationException) { + log.warn("Saving partition [{}] rejected. Event data will save to the DEFAULT partition.", sqlPartition.getPartitionDate()); + partitionsMap.put(sqlPartition.getStart(), sqlPartition); + } else { + throw new RuntimeException(ex); + } + } finally { + partitionCreationLock.unlock(); + } + } } @Override - public Event findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid) { - return DaoUtil.getData(eventRepository.findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid( - tenantId, entityId.getEntityType(), entityId.getId(), eventType, eventUid)); + public EventInfo findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid) { + return null; +// return DaoUtil.getData(eventRepository.findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid( +// tenantId, entityId.getEntityType(), entityId.getId(), eventType, eventUid)); } @Override - public PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) { - return DaoUtil.toPageData( - eventRepository - .findEventsByTenantIdAndEntityId( - tenantId, - entityId.getEntityType(), - entityId.getId(), - Objects.toString(pageLink.getTextSearch(), ""), - pageLink.getStartTime(), - pageLink.getEndTime(), - DaoUtil.toPageable(pageLink))); + public PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) { + return null; +// return DaoUtil.toPageData( +// eventRepository +// .findEventsByTenantIdAndEntityId( +// tenantId, +// entityId.getEntityType(), +// entityId.getId(), +// Objects.toString(pageLink.getTextSearch(), ""), +// pageLink.getStartTime(), +// pageLink.getEndTime(), +// DaoUtil.toPageable(pageLink))); } @Override - public PageData findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { - return DaoUtil.toPageData( - eventRepository - .findEventsByTenantIdAndEntityIdAndEventType( - tenantId, - entityId.getEntityType(), - entityId.getId(), - eventType, - pageLink.getStartTime(), - pageLink.getEndTime(), - DaoUtil.toPageable(pageLink))); + public PageData findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { + return null; +// return DaoUtil.toPageData( +// eventRepository +// .findEventsByTenantIdAndEntityIdAndEventType( +// tenantId, +// entityId.getEntityType(), +// entityId.getId(), +// eventType, +// pageLink.getStartTime(), +// pageLink.getEndTime(), +// DaoUtil.toPageable(pageLink))); } @Override - public PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) { + public PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) { if (eventFilter.hasFilterForJsonBody()) { switch (eventFilter.getEventType()) { case DEBUG_RULE_NODE: @@ -224,86 +256,91 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen } } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, DebugEvent eventFilter, TimePageLink pageLink) { - return DaoUtil.toPageData( - eventRepository.findDebugRuleNodeEvents( - tenantId, - entityId.getId(), - entityId.getEntityType().name(), - eventFilter.getEventType().name(), - notNull(pageLink.getStartTime()), - notNull(pageLink.getEndTime()), - eventFilter.getMsgDirectionType(), - eventFilter.getServer(), - eventFilter.getEntityName(), - eventFilter.getRelationType(), - eventFilter.getEntityId(), - eventFilter.getMsgType(), - eventFilter.isError(), - eventFilter.getErrorStr(), - eventFilter.getDataSearch(), - eventFilter.getMetadataSearch(), - DaoUtil.toPageable(pageLink))); + private PageData findEventByFilter(UUID tenantId, EntityId entityId, DebugEvent eventFilter, TimePageLink pageLink) { + return null; +// return DaoUtil.toPageData( +// eventRepository.findDebugRuleNodeEvents( +// tenantId, +// entityId.getId(), +// entityId.getEntityType().name(), +// eventFilter.getEventType().name(), +// notNull(pageLink.getStartTime()), +// notNull(pageLink.getEndTime()), +// eventFilter.getMsgDirectionType(), +// eventFilter.getServer(), +// eventFilter.getEntityName(), +// eventFilter.getRelationType(), +// eventFilter.getEntityId(), +// eventFilter.getMsgType(), +// eventFilter.isError(), +// eventFilter.getErrorStr(), +// eventFilter.getDataSearch(), +// eventFilter.getMetadataSearch(), +// DaoUtil.toPageable(pageLink))); } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, ErrorEventFilter eventFilter, TimePageLink pageLink) { - return DaoUtil.toPageData( - eventRepository.findErrorEvents( - tenantId, - entityId.getId(), - entityId.getEntityType().name(), - notNull(pageLink.getStartTime()), - notNull(pageLink.getEndTime()), - eventFilter.getServer(), - eventFilter.getMethod(), - eventFilter.getErrorStr(), - DaoUtil.toPageable(pageLink)) - ); + private PageData findEventByFilter(UUID tenantId, EntityId entityId, ErrorEventFilter eventFilter, TimePageLink pageLink) { + return null; +// return DaoUtil.toPageData( +// eventRepository.findErrorEvents( +// tenantId, +// entityId.getId(), +// entityId.getEntityType().name(), +// notNull(pageLink.getStartTime()), +// notNull(pageLink.getEndTime()), +// eventFilter.getServer(), +// eventFilter.getMethod(), +// eventFilter.getErrorStr(), +// DaoUtil.toPageable(pageLink)) +// ); } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, LifeCycleEventFilter eventFilter, TimePageLink pageLink) { - boolean statusFilterEnabled = !StringUtils.isEmpty(eventFilter.getStatus()); - boolean statusFilter = statusFilterEnabled && eventFilter.getStatus().equalsIgnoreCase("Success"); - return DaoUtil.toPageData( - eventRepository.findLifeCycleEvents( - tenantId, - entityId.getId(), - entityId.getEntityType().name(), - notNull(pageLink.getStartTime()), - notNull(pageLink.getEndTime()), - eventFilter.getServer(), - eventFilter.getEvent(), - statusFilterEnabled, - statusFilter, - eventFilter.getErrorStr(), - DaoUtil.toPageable(pageLink)) - ); + private PageData findEventByFilter(UUID tenantId, EntityId entityId, LifeCycleEventFilter eventFilter, TimePageLink pageLink) { + return null; +// boolean statusFilterEnabled = !StringUtils.isEmpty(eventFilter.getStatus()); +// boolean statusFilter = statusFilterEnabled && eventFilter.getStatus().equalsIgnoreCase("Success"); +// return DaoUtil.toPageData( +// eventRepository.findLifeCycleEvents( +// tenantId, +// entityId.getId(), +// entityId.getEntityType().name(), +// notNull(pageLink.getStartTime()), +// notNull(pageLink.getEndTime()), +// eventFilter.getServer(), +// eventFilter.getEvent(), +// statusFilterEnabled, +// statusFilter, +// eventFilter.getErrorStr(), +// DaoUtil.toPageable(pageLink)) +// ); } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) { - return DaoUtil.toPageData( - eventRepository.findStatisticsEvents( - tenantId, - entityId.getId(), - entityId.getEntityType().name(), - notNull(pageLink.getStartTime()), - notNull(pageLink.getEndTime()), - eventFilter.getServer(), - notNull(eventFilter.getMessagesProcessed()), - notNull(eventFilter.getErrorsOccurred()), - DaoUtil.toPageable(pageLink)) - ); + private PageData findEventByFilter(UUID tenantId, EntityId entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) { + return null; +// return DaoUtil.toPageData( +// eventRepository.findStatisticsEvents( +// tenantId, +// entityId.getId(), +// entityId.getEntityType().name(), +// notNull(pageLink.getStartTime()), +// notNull(pageLink.getEndTime()), +// eventFilter.getServer(), +// notNull(eventFilter.getMessagesProcessed()), +// notNull(eventFilter.getErrorsOccurred()), +// DaoUtil.toPageable(pageLink)) +// ); } @Override - public List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit) { - List latest = eventRepository.findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType( - tenantId, - entityId.getEntityType(), - entityId.getId(), - eventType, - PageRequest.of(0, limit)); - return DaoUtil.convertDataList(latest); + public List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit) { + return null; +// List latest = eventRepository.findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType( +// tenantId, +// entityId.getEntityType(), +// entityId.getId(), +// eventType, +// PageRequest.of(0, limit)); +// return DaoUtil.convertDataList(latest); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java index 899a195538..805e5e4f4f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java @@ -23,7 +23,6 @@ import org.thingsboard.server.dao.util.SqlTsDao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; -@SqlTsDao @Repository @Transactional public class SqlPartitioningRepository { @@ -32,8 +31,7 @@ public class SqlPartitioningRepository { private EntityManager entityManager; public void save(SqlPartition partition) { - entityManager.createNativeQuery(partition.getQuery()) - .executeUpdate(); + entityManager.createNativeQuery(partition.getQuery()).executeUpdate(); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java index ce173e046b..64d1669eae 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java @@ -132,7 +132,7 @@ public class JpaSqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao long partitionEndTs = toMills(localDateTimeEnd); ZonedDateTime zonedDateTime = localDateTimeStart.atZone(ZoneOffset.UTC); String partitionDate = zonedDateTime.format(DateTimeFormatter.ofPattern(tsFormat.getPattern())); - savePartition(new SqlPartition(partitionStartTs, partitionEndTs, partitionDate)); + savePartition(new SqlPartition(SqlPartition.TS_KV, partitionStartTs, partitionEndTs, partitionDate)); } } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java index 5c47689b6d..dcdb335784 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java @@ -20,21 +20,21 @@ import lombok.Data; @Data public class SqlPartition { - private static final String TABLE_REGEX = "ts_kv_"; + public static final String TS_KV = "ts_kv"; private long start; private long end; private String partitionDate; private String query; - public SqlPartition(long start, long end, String partitionDate) { + public SqlPartition(String table, long start, long end, String partitionDate) { this.start = start; this.end = end; this.partitionDate = partitionDate; - this.query = createStatement(start, end, partitionDate); + this.query = createStatement(table, start, end, partitionDate); } - private String createStatement(long start, long end, String partitionDate) { - return "CREATE TABLE IF NOT EXISTS " + TABLE_REGEX + partitionDate + " PARTITION OF ts_kv FOR VALUES FROM (" + start + ") TO (" + end + ")"; + private String createStatement(String table, long start, long end, String partitionDate) { + return "CREATE TABLE IF NOT EXISTS " + table + "_" + partitionDate + " PARTITION OF " + table + " FOR VALUES FROM (" + start + ") TO (" + end + ")"; } } \ No newline at end of file diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index a9b25a66f7..9494e4bdd6 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -323,18 +323,64 @@ CREATE TABLE IF NOT EXISTS device_credentials ( CONSTRAINT device_credentials_device_id_unq_key UNIQUE (device_id) ); -CREATE TABLE IF NOT EXISTS event ( - id uuid NOT NULL CONSTRAINT event_pkey PRIMARY KEY, - created_time bigint NOT NULL, - body varchar(10000000), - entity_id uuid, - entity_type varchar(255), - event_type varchar(255), - event_uid varchar(255), - tenant_id uuid, +CREATE TABLE IF NOT EXISTS rule_node_debug_event ( + id uuid NOT NULL CONSTRAINT rule_node_debug_event_pkey PRIMARY KEY, + tenant_id uuid NOT NULL , ts bigint NOT NULL, - CONSTRAINT event_unq_key UNIQUE (tenant_id, entity_type, entity_id, event_type, event_uid) -); + entity_id uuid NOT NULL, + service_id varchar, + e_type varchar, + e_entity_id uuid, + e_entity_type varchar, + e_msg_id uuid, + e_msg_type varchar, + e_data_type varchar, + e_relation_type varchar, + e_data varchar NOT NULL, + e_metadata varchar NOT NULL, + e_error varchar NOT NULL +) PARTITION BY RANGE (ts); + +CREATE TABLE IF NOT EXISTS rule_chain_debug_event ( + id uuid NOT NULL CONSTRAINT rule_chain_debug_event_pkey PRIMARY KEY, + tenant_id uuid NOT NULL, + ts bigint NOT NULL, + entity_id uuid NOT NULL, + service_id varchar NOT NULL, + e_message varchar, + e_error varchar +) PARTITION BY RANGE (ts); + +CREATE TABLE IF NOT EXISTS stats_event ( + id uuid NOT NULL CONSTRAINT stats_event_pkey PRIMARY KEY, + tenant_id uuid NOT NULL, + ts bigint NOT NULL, + entity_id uuid NOT NULL, + service_id varchar NOT NULL, + e_messages_processed bigint NOT NULL, + e_errors_occured bigint NOT NULL +) PARTITION BY RANGE (ts); + +CREATE TABLE IF NOT EXISTS lc_event ( + id uuid NOT NULL CONSTRAINT lc_event_pkey PRIMARY KEY, + tenant_id uuid NOT NULL, + ts bigint NOT NULL, + entity_id uuid NOT NULL, + service_id varchar NOT NULL, + e_type varchar NOT NULL, + e_success boolean NOT NULL, + e_error varchar +) PARTITION BY RANGE (ts); + +CREATE TABLE IF NOT EXISTS error_event ( + id uuid NOT NULL CONSTRAINT error_event_pkey PRIMARY KEY, + tenant_id uuid NOT NULL, + ts bigint NOT NULL, + entity_id uuid NOT NULL, + service_id varchar NOT NULL, + e_method varchar NOT NULL, + e_error varchar +) PARTITION BY RANGE (ts); CREATE TABLE IF NOT EXISTS relation ( from_id uuid, diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index 964e6229f1..1276f46621 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -28,17 +28,20 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.event.Event; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; @@ -185,17 +188,16 @@ public abstract class AbstractServiceTest { } - protected Event generateEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid) throws IOException { + protected RuleNodeDebugEvent generateEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid) throws IOException { if (tenantId == null) { tenantId = TenantId.fromUUID(Uuids.timeBased()); } - Event event = new Event(); - event.setTenantId(tenantId); - event.setEntityId(entityId); - event.setType(eventType); - event.setUid(eventUid); - event.setBody(readFromResource("TestJsonData.json")); - return event; + return RuleNodeDebugEvent.builder() + .tenantId(tenantId) + .entityId(entityId) + .serviceId("server A") + .data(JacksonUtil.toString(readFromResource("TestJsonData.json"))) + .build(); } // // private ComponentDescriptor getOrCreateDescriptor(ComponentScope scope, ComponentType type, String clazz, String configurationDescriptorResource) throws IOException { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java index f3f6dd8ff8..ffd15ff5ba 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java @@ -16,12 +16,13 @@ package org.thingsboard.server.dao.service.event; import com.datastax.oss.driver.api.core.uuid.Uuids; -import org.apache.commons.lang3.time.DateFormatUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; @@ -33,9 +34,6 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.service.AbstractServiceTest; import java.text.ParseException; -import java.time.LocalDateTime; -import java.time.Month; -import java.time.ZoneOffset; import java.util.Optional; import static org.apache.commons.lang3.time.DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT; @@ -59,14 +57,15 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest { @Test public void saveEvent() throws Exception { DeviceId devId = new DeviceId(Uuids.timeBased()); - Event event = generateEvent(null, devId, "ALARM", Uuids.timeBased().toString()); + RuleNodeDebugEvent event = generateEvent(null, devId, "ALARM", Uuids.timeBased().toString()); eventService.saveAsync(event).get(); - Optional loaded = eventService.findEvent(event.getTenantId(), event.getEntityId(), event.getType(), event.getUid()); - Assert.assertTrue(loaded.isPresent()); - Assert.assertNotNull(loaded.get()); - Assert.assertEquals(event.getEntityId(), loaded.get().getEntityId()); - Assert.assertEquals(event.getType(), loaded.get().getType()); - Assert.assertEquals(event.getBody(), loaded.get().getBody()); + throw new RuntimeException("fix me!"); +// Optional loaded = eventService.findEvent(event.getTenantId(), event.getEntityId(), event.getType(), event.getUid()); +// Assert.assertTrue(loaded.isPresent()); +// Assert.assertNotNull(loaded.get()); +// Assert.assertEquals(event.getEntityId(), loaded.get().getEntityId()); +// Assert.assertEquals(event.getType(), loaded.get().getType()); +// Assert.assertEquals(event.getBody(), loaded.get().getBody()); } @Test @@ -74,14 +73,14 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest { CustomerId customerId = new CustomerId(Uuids.timeBased()); TenantId tenantId = TenantId.fromUUID(Uuids.timeBased()); saveEventWithProvidedTime(timeBeforeStartTime, customerId, tenantId); - Event savedEvent = saveEventWithProvidedTime(eventTime, customerId, tenantId); - Event savedEvent2 = saveEventWithProvidedTime(eventTime + 1, customerId, tenantId); - Event savedEvent3 = saveEventWithProvidedTime(eventTime + 2, customerId, tenantId); + EventInfo savedEvent = saveEventWithProvidedTime(eventTime, customerId, tenantId); + EventInfo savedEvent2 = saveEventWithProvidedTime(eventTime + 1, customerId, tenantId); + EventInfo savedEvent3 = saveEventWithProvidedTime(eventTime + 2, customerId, tenantId); saveEventWithProvidedTime(timeAfterEndTime, customerId, tenantId); TimePageLink timePageLink = new TimePageLink(2, 0, "", new SortOrder("createdTime"), startTime, endTime); - PageData events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, + PageData events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, timePageLink); Assert.assertNotNull(events.getData()); @@ -105,14 +104,14 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest { CustomerId customerId = new CustomerId(Uuids.timeBased()); TenantId tenantId = TenantId.fromUUID(Uuids.timeBased()); saveEventWithProvidedTime(timeBeforeStartTime, customerId, tenantId); - Event savedEvent = saveEventWithProvidedTime(eventTime, customerId, tenantId); - Event savedEvent2 = saveEventWithProvidedTime(eventTime + 1, customerId, tenantId); - Event savedEvent3 = saveEventWithProvidedTime(eventTime + 2, customerId, tenantId); + EventInfo savedEvent = saveEventWithProvidedTime(eventTime, customerId, tenantId); + EventInfo savedEvent2 = saveEventWithProvidedTime(eventTime + 1, customerId, tenantId); + EventInfo savedEvent3 = saveEventWithProvidedTime(eventTime + 2, customerId, tenantId); saveEventWithProvidedTime(timeAfterEndTime, customerId, tenantId); TimePageLink timePageLink = new TimePageLink(2, 0, "", new SortOrder("createdTime", SortOrder.Direction.DESC), startTime, endTime); - PageData events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, + PageData events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, timePageLink); Assert.assertNotNull(events.getData()); @@ -131,10 +130,11 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest { eventService.cleanupEvents(timeBeforeStartTime - 1, timeAfterEndTime + 1, timeBeforeStartTime - 1, timeAfterEndTime + 1); } - private Event saveEventWithProvidedTime(long time, EntityId entityId, TenantId tenantId) throws Exception { - Event event = generateEvent(tenantId, entityId, DataConstants.STATS, null); - event.setId(new EventId(Uuids.startOf(time))); - eventService.saveAsync(event).get(); - return event; + private EventInfo saveEventWithProvidedTime(long time, EntityId entityId, TenantId tenantId) throws Exception { + throw new RuntimeException("fix me!"); +// EventInfo event = generateEvent(tenantId, entityId, DataConstants.STATS, null); +// event.setId(new EventId(Uuids.startOf(time))); +// eventService.saveAsync(event).get(); +// return event; } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java index eb5f004714..4381aab18f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java @@ -23,7 +23,7 @@ import org.junit.After; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; @@ -35,9 +35,7 @@ import org.thingsboard.server.dao.event.EventDao; import java.io.IOException; import java.util.List; -import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -58,128 +56,129 @@ public class JpaBaseEventDaoTest extends AbstractJpaDaoTest { @After public void deleteEvents() { - List events = eventDao.find(TenantId.fromUUID(tenantId)); - for (Event event : events) { - eventDao.removeById(TenantId.fromUUID(tenantId), event.getUuidId()); - } + throw new RuntimeException("fix me!"); +// List events = eventDao.find(TenantId.fromUUID(tenantId)); +// for (EventInfo event : events) { +// eventDao.removeById(TenantId.fromUUID(tenantId), event.getUuidId()); +// } } - @Test - public void findEvent() { - UUID entityId = Uuids.timeBased(); - Event savedEvent = eventDao.save(TenantId.fromUUID(tenantId), getEvent(entityId, tenantId, entityId)); - Event foundEvent = eventDao.findEvent(tenantId, new DeviceId(entityId), DataConstants.STATS, savedEvent.getUid()); - assertNotNull("Event expected to be not null", foundEvent); - assertEquals(savedEvent.getId(), foundEvent.getId()); - } - - @Test - public void findEventsByEntityIdAndPageLink() throws Exception { - UUID entityId1 = Uuids.timeBased(); - UUID entityId2 = Uuids.timeBased(); - long startTime = System.currentTimeMillis(); - long endTime = createEventsTwoEntities(tenantId, entityId1, entityId2, 20); - - TimePageLink pageLink1 = new TimePageLink(30); - PageData events1 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink1); - assertEquals(10, events1.getData().size()); - - TimePageLink pageLink2 = new TimePageLink(30, 0, "", null, startTime, null); - PageData events2 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink2); - assertEquals(10, events2.getData().size()); - - TimePageLink pageLink3 = new TimePageLink(30, 0, "", null, startTime, endTime); - PageData events3 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink3); - assertEquals(10, events3.getData().size()); - - TimePageLink pageLink4 = new TimePageLink(5, 0, "", null, startTime, endTime); - PageData events4 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); - assertEquals(5, events4.getData().size()); - - pageLink4 = pageLink4.nextPageLink(); - PageData events5 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); - assertEquals(5, events5.getData().size()); - - pageLink4 = pageLink4.nextPageLink(); - PageData events6 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); - assertEquals(0, events6.getData().size()); - - } - - @Test - public void findEventsByEntityIdAndEventTypeAndPageLink() throws Exception { - UUID entityId1 = Uuids.timeBased(); - UUID entityId2 = Uuids.timeBased(); - long startTime = System.currentTimeMillis(); - long endTime = createEventsTwoEntitiesTwoTypes(tenantId, entityId1, entityId2, 20); - - TimePageLink pageLink1 = new TimePageLink(30); - PageData events1 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink1); - assertEquals(5, events1.getData().size()); - - TimePageLink pageLink2 = new TimePageLink(30, 0, "", null, startTime, null); - PageData events2 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink2); - assertEquals(5, events2.getData().size()); - - TimePageLink pageLink3 = new TimePageLink(30, 0, "", null, startTime, endTime); - PageData events3 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink3); - assertEquals(5, events3.getData().size()); - - TimePageLink pageLink4 = new TimePageLink(4, 0, "", null, startTime, endTime); - PageData events4 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink4); - assertEquals(4, events4.getData().size()); - - pageLink4 = pageLink4.nextPageLink(); - PageData events5 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink4); - assertEquals(1, events5.getData().size()); - } - - private long createEventsTwoEntitiesTwoTypes(UUID tenantId, UUID entityId1, UUID entityId2, int count) throws Exception { - for (int i = 0; i < count / 2; i++) { - String type = i % 2 == 0 ? STATS : ALARM; - UUID eventId1 = Uuids.timeBased(); - Event event1 = getEvent(eventId1, tenantId, entityId1, type); - eventDao.saveAsync(event1).get(); - UUID eventId2 = Uuids.timeBased(); - Event event2 = getEvent(eventId2, tenantId, entityId2, type); - eventDao.saveAsync(event2).get(); - } - return System.currentTimeMillis(); - } - - private long createEventsTwoEntities(UUID tenantId, UUID entityId1, UUID entityId2, int count) throws Exception { - for (int i = 0; i < count / 2; i++) { - UUID eventId1 = Uuids.timeBased(); - Event event1 = getEvent(eventId1, tenantId, entityId1); - eventDao.saveAsync(event1).get(); - UUID eventId2 = Uuids.timeBased(); - Event event2 = getEvent(eventId2, tenantId, entityId2); - eventDao.saveAsync(event2).get(); - } - return System.currentTimeMillis(); - } - - private Event getEvent(UUID eventId, UUID tenantId, UUID entityId, String type) { - Event event = getEvent(eventId, tenantId, entityId); - event.setType(type); - return event; - } - - private Event getEvent(UUID eventId, UUID tenantId, UUID entityId) { - Event event = new Event(); - event.setId(new EventId(eventId)); - event.setTenantId(TenantId.fromUUID(tenantId)); - EntityId deviceId = new DeviceId(entityId); - event.setEntityId(deviceId); - event.setUid(event.getId().getId().toString()); - event.setType(STATS); - ObjectMapper mapper = new ObjectMapper(); - try { - JsonNode jsonNode = mapper.readTree("{\"key\":\"value\"}"); - event.setBody(jsonNode); - } catch (IOException e) { - log.error(e.getMessage(), e); - } - return event; - } +// @Test +// public void findEvent() { +// UUID entityId = Uuids.timeBased(); +// EventInfo savedEvent = eventDao.save(TenantId.fromUUID(tenantId), getEvent(entityId, tenantId, entityId)); +// EventInfo foundEvent = eventDao.findEvent(tenantId, new DeviceId(entityId), DataConstants.STATS, savedEvent.getUid()); +// assertNotNull("Event expected to be not null", foundEvent); +// assertEquals(savedEvent.getId(), foundEvent.getId()); +// } +// +// @Test +// public void findEventsByEntityIdAndPageLink() throws Exception { +// UUID entityId1 = Uuids.timeBased(); +// UUID entityId2 = Uuids.timeBased(); +// long startTime = System.currentTimeMillis(); +// long endTime = createEventsTwoEntities(tenantId, entityId1, entityId2, 20); +// +// TimePageLink pageLink1 = new TimePageLink(30); +// PageData events1 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink1); +// assertEquals(10, events1.getData().size()); +// +// TimePageLink pageLink2 = new TimePageLink(30, 0, "", null, startTime, null); +// PageData events2 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink2); +// assertEquals(10, events2.getData().size()); +// +// TimePageLink pageLink3 = new TimePageLink(30, 0, "", null, startTime, endTime); +// PageData events3 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink3); +// assertEquals(10, events3.getData().size()); +// +// TimePageLink pageLink4 = new TimePageLink(5, 0, "", null, startTime, endTime); +// PageData events4 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); +// assertEquals(5, events4.getData().size()); +// +// pageLink4 = pageLink4.nextPageLink(); +// PageData events5 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); +// assertEquals(5, events5.getData().size()); +// +// pageLink4 = pageLink4.nextPageLink(); +// PageData events6 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4); +// assertEquals(0, events6.getData().size()); +// +// } +// +// @Test +// public void findEventsByEntityIdAndEventTypeAndPageLink() throws Exception { +// UUID entityId1 = Uuids.timeBased(); +// UUID entityId2 = Uuids.timeBased(); +// long startTime = System.currentTimeMillis(); +// long endTime = createEventsTwoEntitiesTwoTypes(tenantId, entityId1, entityId2, 20); +// +// TimePageLink pageLink1 = new TimePageLink(30); +// PageData events1 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink1); +// assertEquals(5, events1.getData().size()); +// +// TimePageLink pageLink2 = new TimePageLink(30, 0, "", null, startTime, null); +// PageData events2 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink2); +// assertEquals(5, events2.getData().size()); +// +// TimePageLink pageLink3 = new TimePageLink(30, 0, "", null, startTime, endTime); +// PageData events3 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink3); +// assertEquals(5, events3.getData().size()); +// +// TimePageLink pageLink4 = new TimePageLink(4, 0, "", null, startTime, endTime); +// PageData events4 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink4); +// assertEquals(4, events4.getData().size()); +// +// pageLink4 = pageLink4.nextPageLink(); +// PageData events5 = eventDao.findEvents(tenantId, new DeviceId(entityId1), ALARM, pageLink4); +// assertEquals(1, events5.getData().size()); +// } +// +// private long createEventsTwoEntitiesTwoTypes(UUID tenantId, UUID entityId1, UUID entityId2, int count) throws Exception { +// for (int i = 0; i < count / 2; i++) { +// String type = i % 2 == 0 ? STATS : ALARM; +// UUID eventId1 = Uuids.timeBased(); +// EventInfo event1 = getEvent(eventId1, tenantId, entityId1, type); +// eventDao.saveAsync(event1).get(); +// UUID eventId2 = Uuids.timeBased(); +// EventInfo event2 = getEvent(eventId2, tenantId, entityId2, type); +// eventDao.saveAsync(event2).get(); +// } +// return System.currentTimeMillis(); +// } +// +// private long createEventsTwoEntities(UUID tenantId, UUID entityId1, UUID entityId2, int count) throws Exception { +// for (int i = 0; i < count / 2; i++) { +// UUID eventId1 = Uuids.timeBased(); +// EventInfo event1 = getEvent(eventId1, tenantId, entityId1); +// eventDao.saveAsync(event1).get(); +// UUID eventId2 = Uuids.timeBased(); +// EventInfo event2 = getEvent(eventId2, tenantId, entityId2); +// eventDao.saveAsync(event2).get(); +// } +// return System.currentTimeMillis(); +// } +// +// private EventInfo getEvent(UUID eventId, UUID tenantId, UUID entityId, String type) { +// EventInfo event = getEvent(eventId, tenantId, entityId); +// event.setType(type); +// return event; +// } +// +// private EventInfo getEvent(UUID eventId, UUID tenantId, UUID entityId) { +// EventInfo event = new EventInfo(); +// event.setId(new EventId(eventId)); +// event.setTenantId(TenantId.fromUUID(tenantId)); +// EntityId deviceId = new DeviceId(entityId); +// event.setEntityId(deviceId); +// event.setUid(event.getId().getId().toString()); +// event.setType(STATS); +// ObjectMapper mapper = new ObjectMapper(); +// try { +// JsonNode jsonNode = mapper.readTree("{\"key\":\"value\"}"); +// event.setBody(jsonNode); +// } catch (IOException e) { +// log.error(e.getMessage(), e); +// } +// return event; +// } } diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index a0f1d5dfa1..f2f446e534 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -54,7 +54,7 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; -import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; @@ -1811,7 +1811,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { } } - public PageData getEvents(EntityId entityId, String eventType, TenantId tenantId, TimePageLink pageLink) { + public PageData getEvents(EntityId entityId, String eventType, TenantId tenantId, TimePageLink pageLink) { Map params = new HashMap<>(); params.put("entityType", entityId.getEntityType().name()); params.put("entityId", entityId.getId().toString()); @@ -1823,12 +1823,12 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { baseURL + "/api/events/{entityType}/{entityId}/{eventType}?tenantId={tenantId}&" + getTimeUrlParams(pageLink), HttpMethod.GET, HttpEntity.EMPTY, - new ParameterizedTypeReference>() { + new ParameterizedTypeReference>() { }, params).getBody(); } - public PageData getEvents(EntityId entityId, TenantId tenantId, TimePageLink pageLink) { + public PageData getEvents(EntityId entityId, TenantId tenantId, TimePageLink pageLink) { Map params = new HashMap<>(); params.put("entityType", entityId.getEntityType().name()); params.put("entityId", entityId.getId().toString()); @@ -1839,7 +1839,7 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { baseURL + "/api/events/{entityType}/{entityId}?tenantId={tenantId}&" + getTimeUrlParams(pageLink), HttpMethod.GET, HttpEntity.EMPTY, - new ParameterizedTypeReference>() { + new ParameterizedTypeReference>() { }, params).getBody(); } From 33fe04a7a0e11e6d8ff7e1db09982f145b2e7afc Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 25 Jul 2022 13:34:40 +0300 Subject: [PATCH 021/158] UI: Not redirect to the previous link after login with 2FA --- ui-ngx/src/app/core/auth/auth.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/core/auth/auth.service.ts b/ui-ngx/src/app/core/auth/auth.service.ts index c7b1a283d3..172e4d5ac9 100644 --- a/ui-ngx/src/app/core/auth/auth.service.ts +++ b/ui-ngx/src/app/core/auth/auth.service.ts @@ -268,7 +268,9 @@ export class AuthService { public defaultUrl(isAuthenticated: boolean, authState?: AuthState, path?: string, params?: any): UrlTree { let result: UrlTree = null; if (isAuthenticated) { - if (!path || path === 'login' || this.forceDefaultPlace(authState, path, params)) { + if (authState.authUser.authority === Authority.PRE_VERIFICATION_TOKEN) { + result = this.router.parseUrl('login/mfa'); + } else if (!path || path === 'login' || this.forceDefaultPlace(authState, path, params)) { if (this.redirectUrl) { const redirectUrl = this.redirectUrl; this.redirectUrl = null; From b3fdc881f48a8b985acd6ab15e24cca6ddb71de7 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Mon, 25 Jul 2022 17:19:07 +0300 Subject: [PATCH 022/158] Fixed bugs, removed redundant code --- ...enant-profile-configuration.component.html | 24 +++++++------- ...-tenant-profile-configuration.component.ts | 2 +- .../rate-limits-details-dialog.component.html | 10 ++---- .../rate-limits-details-dialog.component.ts | 21 +++--------- .../rate-limits-list.component.html | 22 ++++++------- .../rate-limits/rate-limits-list.component.ts | 32 +++++++------------ .../rate-limits-text.component.html | 2 +- .../rate-limits-text.component.scss | 8 ----- .../rate-limits/rate-limits-text.component.ts | 25 ++------------- .../rate-limits/rate-limits.component.ts | 2 +- .../tenant/rate-limits}/rate-limits.models.ts | 0 11 files changed, 47 insertions(+), 101 deletions(-) rename ui-ngx/src/app/{shared/models => modules/home/components/profile/tenant/rate-limits}/rate-limits.models.ts (100%) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html index 847aae7bf1..a3f285bece 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html @@ -422,18 +422,18 @@ {{ 'tenant-profile.rate-limits.rate-limits' | translate }}
- -
- -
@@ -445,34 +445,34 @@
- -
- -
- -
- -
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts index d44715cc63..9649966bd1 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts @@ -21,7 +21,7 @@ import { AppState } from '@app/core/core.state'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { DefaultTenantProfileConfiguration, TenantProfileConfiguration } from '@shared/models/tenant.model'; import { isDefinedAndNotNull } from '@core/utils'; -import { RateLimitsType } from '@shared/models/rate-limits.models'; +import { RateLimitsType } from './rate-limits/rate-limits.models'; @Component({ selector: 'tb-default-tenant-profile-configuration', diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html index 751ffe0e2c..6cbe5472c2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html @@ -25,14 +25,11 @@ close - -
-
+
+ formControlName="rateLimits">
@@ -40,12 +37,11 @@
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts index 790ca57838..80b9e1ba34 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts @@ -19,7 +19,7 @@ import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms'; +import { FormBuilder, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { TranslateService } from '@ngx-translate/core'; @@ -31,16 +31,12 @@ export interface RateLimitsDetailsDialogData { } @Component({ - templateUrl: './rate-limits-details-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: RateLimitsDetailsDialogComponent}] + templateUrl: './rate-limits-details-dialog.component.html' }) -export class RateLimitsDetailsDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { +export class RateLimitsDetailsDialogComponent extends DialogComponent implements OnInit { editDetailsFormGroup: FormGroup; - submitted: boolean = false; - rateLimits: string = this.data.rateLimits; title: string = this.data.title; @@ -49,7 +45,7 @@ export class RateLimitsDetailsDialogComponent extends DialogComponent, + public dialogRef: MatDialogRef, private fb: FormBuilder, public translate: TranslateService) { super(store, router, dialogRef); @@ -65,18 +61,11 @@ export class RateLimitsDetailsDialogComponent extends DialogComponent -
-
-
+
+
+
tenant-profile.rate-limits.but-less-than
@@ -45,7 +45,7 @@
-
- -
+
tenant-profile.rate-limits.preview
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts index eb7a37cfde..dd5f52dbc2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts @@ -32,7 +32,7 @@ import { RateLimits, rateLimitsArrayToString, stringToRateLimitsArray -} from '@shared/models/rate-limits.models'; +} from './rate-limits.models'; import { isDefinedAndNotNull } from '@core/utils'; @Component({ @@ -68,17 +68,17 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, } ngOnInit(): void { - this.rateLimitsListFormGroup = this.fb.group({}); - this.rateLimitsListFormGroup.addControl('rateLimits', - this.fb.array([])); + this.rateLimitsListFormGroup = this.fb.group({ + rateLimits: this.fb.array([]) + }); this.rateLimitsControl = this.fb.control(null); - this.rateLimitsListFormGroup.valueChanges.subscribe((value) => { + this.valueChangeSubscription = this.rateLimitsListFormGroup.valueChanges.subscribe((value) => { this.updateView(value?.rateLimits); } ); } - rateLimitsFormArray(): FormArray { + get rateLimitsFormArray(): FormArray { return this.rateLimitsListFormGroup.get('rateLimits') as FormArray; } @@ -107,16 +107,11 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, } writeValue(value: string) { - if (this.valueChangeSubscription) { - this.valueChangeSubscription.unsubscribe(); - } const rateLimitsControls: Array = []; if (value) { let rateLimitsArray = value.split(','); for (let i = 0; i < rateLimitsArray.length; i++) { - let valueTime = rateLimitsArray[i].split(':'); - let value = valueTime[0]; - let time = valueTime[1]; + const [value, time] = rateLimitsArray[i].split(':'); const rateLimitsControl = this.fb.group({ value: [value, [Validators.required]], time: [time, [Validators.required]] @@ -127,11 +122,8 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, rateLimitsControls.push(rateLimitsControl); } } - this.rateLimitsListFormGroup.setControl('rateLimits', this.fb.array(rateLimitsControls)); + this.rateLimitsListFormGroup.setControl('rateLimits', this.fb.array(rateLimitsControls), {emitEvent: false}); this.rateLimitsControl.patchValue(stringToRateLimitsArray(value), {emitEvent: false}); - this.valueChangeSubscription = this.rateLimitsListFormGroup.valueChanges.subscribe((value) => { - this.updateView(value?.rateLimits); - }); } public removeRateLimits(index: number) { @@ -139,17 +131,17 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, } public addRateLimits() { - const rateLimitsArray = this.rateLimitsListFormGroup.get('rateLimits') as FormArray; - rateLimitsArray.push(this.fb.group({ + this.rateLimitsFormArray.push(this.fb.group({ value: [null, [Validators.required]], time: [null, [Validators.required]] })); - this.rateLimitsListFormGroup.updateValueAndValidity(); } updateView(rateLimitsArray: Array) { if (rateLimitsArray.length > 0) { - const notNullRateLimits = rateLimitsArray.filter(rateLimits => isDefinedAndNotNull(rateLimits.value) && isDefinedAndNotNull(rateLimits.time)); + const notNullRateLimits = rateLimitsArray.filter(rateLimits => + isDefinedAndNotNull(rateLimits.value) && isDefinedAndNotNull(rateLimits.time) + ); const rateLimitsString = rateLimitsArrayToString(notNullRateLimits); this.propagateChange(rateLimitsString); this.rateLimitsControl.patchValue(stringToRateLimitsArray(rateLimitsString), {emitEvent: false}); diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html index 98a30b055e..077ede2e0b 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html @@ -15,5 +15,5 @@ limitations under the License. --> -
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss index a8f8f8553f..b78f1033bd 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.scss @@ -20,14 +20,6 @@ &.disabled { opacity: 0.7; } - &.required { - color: #f44336; - padding: 0 4px; - } - &.nowrap { - white-space: nowrap; - overflow: hidden; - } } } diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts index 9ab7e9b56b..604318d6fd 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts @@ -18,8 +18,7 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; -import { coerceBooleanProperty } from '@angular/cdk/coercion'; -import { RateLimits, rateLimitsArrayToHtml } from '@shared/models/rate-limits.models'; +import { RateLimits, rateLimitsArrayToHtml } from './rate-limits.models'; @Component({ selector: 'tb-rate-limits-text', @@ -35,26 +34,11 @@ import { RateLimits, rateLimitsArrayToHtml } from '@shared/models/rate-limits.mo }) export class RateLimitsTextComponent implements ControlValueAccessor, OnInit { - private requiredValue: boolean; - get required(): boolean { - return this.requiredValue; - } - @Input() - set required(value: boolean) { - this.requiredValue = coerceBooleanProperty(value); - } - @Input() disabled: boolean; - @Input() noRateLimitsText = this.translate.instant('tenant-profile.rate-limits.not-set'); - @Input() - nowrap = false; - - requiredClass = false; - public rateLimitsText: string; private propagateChange = (v: any) => { }; @@ -83,15 +67,10 @@ export class RateLimitsTextComponent implements ControlValueAccessor, OnInit { } private updateText(value: Array) { - this.requiredClass = false; if (value && value.length) { this.rateLimitsText = rateLimitsArrayToHtml(this.translate, value); } else { - if (this.required && !this.disabled) { - this.requiredClass = true; - } else { - this.rateLimitsText = this.noRateLimitsText; - } + this.rateLimitsText = this.noRateLimitsText; } } diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts index 753ef133a9..dcf0403a22 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.ts @@ -34,7 +34,7 @@ import { rateLimitsLabelTranslationMap, RateLimitsType, stringToRateLimitsArray -} from '@shared/models/rate-limits.models'; +} from './rate-limits.models'; @Component({ selector: 'tb-rate-limits', diff --git a/ui-ngx/src/app/shared/models/rate-limits.models.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts similarity index 100% rename from ui-ngx/src/app/shared/models/rate-limits.models.ts rename to ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts From 88599262daa26a19e365acadd2375d44666c9d0b Mon Sep 17 00:00:00 2001 From: deaflynx Date: Mon, 25 Jul 2022 17:55:15 +0300 Subject: [PATCH 023/158] Rate limits update styles --- .../rate-limits-details-dialog.component.html | 5 +++-- .../rate-limits-details-dialog.component.ts | 13 ++----------- .../rate-limits/rate-limits-list.component.scss | 4 ++++ .../tenant/rate-limits/rate-limits.component.ts | 3 ++- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html index 6cbe5472c2..e69b95a3e2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.html @@ -20,7 +20,7 @@

{{ title | translate }}

@@ -37,7 +37,8 @@
-
-
- - -
-
+
tenant-profile.rate-limits.preview -
- -
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss index 64f9c7afe2..2a53096c17 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.scss @@ -27,7 +27,7 @@ span { padding-left: 1em; } - div { + tb-rate-limits-text { border: 1px groove rgba(0, 0, 0, .25); border-radius: 4px; padding: 1em; diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html index 077ede2e0b..e154a7ce54 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.html @@ -15,5 +15,4 @@ limitations under the License. --> -
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts index 604318d6fd..0b65e97d5d 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts @@ -14,64 +14,41 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; -import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { RateLimits, rateLimitsArrayToHtml } from './rate-limits.models'; @Component({ selector: 'tb-rate-limits-text', templateUrl: './rate-limits-text.component.html', - styleUrls: ['./rate-limits-text.component.scss'], - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => RateLimitsTextComponent), - multi: true - } - ] + styleUrls: ['./rate-limits-text.component.scss'] }) -export class RateLimitsTextComponent implements ControlValueAccessor, OnInit { +export class RateLimitsTextComponent implements OnChanges { @Input() - disabled: boolean; - - noRateLimitsText = this.translate.instant('tenant-profile.rate-limits.not-set'); - - public rateLimitsText: string; - - private propagateChange = (v: any) => { }; - - constructor(private dialog: MatDialog, - private fb: FormBuilder, - private translate: TranslateService) { - } - - registerOnChange(fn: any): void { - this.propagateChange = fn; - } + rateLimitsArray: Array; - registerOnTouched(fn: any): void { - } + @Input() + disabled: boolean; - ngOnInit() { - } + rateLimitsText: string; - setDisabledState(isDisabled: boolean): void { - this.disabled = isDisabled; - } + constructor(private translate: TranslateService) {} - writeValue(value: Array): void { - this.updateText(value); + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + if (propName === 'rateLimitsArray') { + const change = changes[propName]; + this.updateView(change.currentValue); + } + } } - private updateText(value: Array) { - if (value && value.length) { + private updateView(value: Array): void { + if (value?.length) { this.rateLimitsText = rateLimitsArrayToHtml(this.translate, value); } else { - this.rateLimitsText = this.noRateLimitsText; + this.rateLimitsText = this.translate.instant('tenant-profile.rate-limits.not-set'); } } - } diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html index 3a6591790f..ac341c8b69 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html @@ -21,7 +21,7 @@
- +
tenant-profile.rate-limits.preview - +
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts index 0d8abf6657..0c135d0d9a 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts @@ -95,6 +95,10 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, return this.rateLimitsListFormGroup.get('rateLimits') as FormArray; } + get rateLimitsArray(): Array { + return this.rateLimitsControl.value; + } + registerOnChange(fn: any): void { this.propagateChange = fn; } From c2f0d4725531da8bd307769defd24912d3f68567 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Tue, 26 Jul 2022 15:44:51 +0300 Subject: [PATCH 029/158] Code cleanup --- .../rate-limits/rate-limits-details-dialog.component.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts index 9d01ddcd5b..46a50bf484 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts @@ -15,14 +15,12 @@ /// import { Component, Inject, SkipSelf } from '@angular/core'; -import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; -import { TranslateService } from '@ngx-translate/core'; export interface RateLimitsDetailsDialogData { rateLimits: string; @@ -44,10 +42,8 @@ export class RateLimitsDetailsDialogComponent extends DialogComponent, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: RateLimitsDetailsDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, - private fb: FormBuilder, - public translate: TranslateService) { + private fb: FormBuilder) { super(store, router, dialogRef); this.editDetailsFormGroup = this.fb.group({ rateLimits: [this.rateLimits, []] From 4811a3d56cbe44d2c5a6576748273554ef15855e Mon Sep 17 00:00:00 2001 From: deaflynx Date: Tue, 26 Jul 2022 16:04:55 +0300 Subject: [PATCH 030/158] Code cleanup --- .../tenant/rate-limits/rate-limits-details-dialog.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts index 46a50bf484..4818304491 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-details-dialog.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, Inject, SkipSelf } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; From 219e97ff4a293c4ab300712ab4b3f32ef3eb7d6d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 26 Jul 2022 16:28:55 +0300 Subject: [PATCH 031/158] Implementation of Rule Chain and Rule Node debug events --- .../controller/RuleChainController.java | 1 - .../AbstractRuleEngineControllerTest.java | 1 - .../common/data/event/DebugEventFilter.java | 47 +++++ .../data/event/DebugRuleNodeEventFilter.java | 26 --- .../common/data/event/ErrorEventFilter.java | 2 +- .../server/common/data/event/Event.java | 8 + .../server/common/data/event/EventFilter.java | 6 +- .../data/event/LifeCycleEventFilter.java | 2 +- .../data/event/RuleChainDebugEvent.java | 14 +- ...er.java => RuleChainDebugEventFilter.java} | 17 +- .../common/data/event/RuleNodeDebugEvent.java | 29 ++- ...ent.java => RuleNodeDebugEventFilter.java} | 47 +++-- .../data/event/StatisticsEventFilter.java | 2 +- .../server/dao/event/BaseEventService.java | 6 +- .../server/dao/event/EventDao.java | 12 +- .../server/dao/model/ModelConstants.java | 10 + .../dao/model/sql/AdminSettingsEntity.java | 1 - .../dao/model/sql/DeviceProfileEntity.java | 1 - .../dao/model/sql/ErrorEventEntity.java | 9 - .../server/dao/model/sql/EventEntity.java | 3 - .../dao/model/sql/LifecycleEventEntity.java | 3 - .../model/sql/RuleChainDebugEventEntity.java | 63 ++++++ .../model/sql/RuleNodeDebugEventEntity.java | 109 +++++++++++ .../dao/model/sql/StatisticsEventEntity.java | 8 - .../dao/sql/event/ErrorEventRepository.java | 14 +- .../dao/sql/event/EventInsertRepository.java | 2 - .../server/dao/sql/event/EventRepository.java | 58 +----- .../server/dao/sql/event/JpaBaseEventDao.java | 185 ++++++++---------- .../sql/event/LifecycleEventRepository.java | 12 +- .../event/RuleChainDebugEventRepository.java | 82 ++++++++ .../event/RuleNodeDebugEventRepository.java | 103 ++++++++++ .../sql/event/StatisticsEventRepository.java | 49 ++++- .../sql/schema-entities-idx-psql-addon.sql | 10 +- .../main/resources/sql/schema-entities.sql | 6 +- .../components/event/event-table-config.ts | 4 +- ui-ngx/src/app/shared/models/event.models.ts | 2 +- 36 files changed, 667 insertions(+), 287 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java delete mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleNodeEventFilter.java rename common/data/src/main/java/org/thingsboard/server/common/data/event/{DebugRuleChainEventFilter.java => RuleChainDebugEventFilter.java} (61%) rename common/data/src/main/java/org/thingsboard/server/common/data/event/{DebugEvent.java => RuleNodeDebugEventFilter.java} (59%) create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleChainDebugEventRepository.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleNodeDebugEventRepository.java diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index bcca7965b3..5c79f9eca7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -39,7 +39,6 @@ import org.springframework.web.bind.annotation.RestController; import org.thingsboard.rule.engine.api.ScriptEngine; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.tenant.DebugTbRateLimits; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.edge.Edge; diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java index ca0d5a6215..a3edae8ed6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.id.EntityId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java new file mode 100644 index 0000000000..c895b61c78 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java @@ -0,0 +1,47 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.event; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.data.domain.Page; +import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.StringUtils; + +import java.util.UUID; + +@Data +@ApiModel +public abstract class DebugEventFilter implements EventFilter { + + @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + protected String server; + @ApiModelProperty(position = 10, value = "Boolean value to filter the errors", allowableValues = "false, true") + protected boolean isError; + @ApiModelProperty(position = 11, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + protected String errorStr; + + public void setIsError(boolean isError) { + this.isError = isError; + } + + @Override + public boolean isNotEmpty() { + return !StringUtils.isEmpty(server) || isError || !StringUtils.isEmpty(errorStr); + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleNodeEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleNodeEventFilter.java deleted file mode 100644 index ec55c8d1a2..0000000000 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleNodeEventFilter.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.common.data.event; - -import io.swagger.annotations.ApiModel; - -@ApiModel -public class DebugRuleNodeEventFilter extends DebugEvent { - @Override - public EventType getEventType() { - return EventType.DEBUG_RULE_NODE; - } -} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java index 9332cd283a..c8f2106764 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java @@ -37,7 +37,7 @@ public class ErrorEventFilter implements EventFilter { } @Override - public boolean hasFilterForJsonBody() { + public boolean isNotEmpty() { return !StringUtils.isEmpty(server) || !StringUtils.isEmpty(method) || !StringUtils.isEmpty(errorStr); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java index 6e41a3750e..801289791a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.event; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; @@ -56,8 +57,15 @@ public abstract class Event extends BaseData { eventInfo.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId)); eventInfo.setType(getType().getOldName()); eventInfo.setId(id); + eventInfo.setUid(id.toString()); eventInfo.setCreatedTime(createdTime); eventInfo.setBody(OBJECT_MAPPER.createObjectNode().put("server", getServiceId())); return eventInfo; } + + protected static void putNotNull(ObjectNode json, String key, String value) { + if (value != null) { + json.put(key, value); + } + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java index 5d02fbcd13..39502eba3b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java @@ -26,8 +26,8 @@ import io.swagger.annotations.ApiModelProperty; include = JsonTypeInfo.As.PROPERTY, property = "eventType") @JsonSubTypes({ - @JsonSubTypes.Type(value = DebugRuleNodeEventFilter.class, name = "DEBUG_RULE_NODE"), - @JsonSubTypes.Type(value = DebugRuleChainEventFilter.class, name = "DEBUG_RULE_CHAIN"), + @JsonSubTypes.Type(value = RuleNodeDebugEventFilter.class, name = "DEBUG_RULE_NODE"), + @JsonSubTypes.Type(value = RuleChainDebugEventFilter.class, name = "DEBUG_RULE_CHAIN"), @JsonSubTypes.Type(value = ErrorEventFilter.class, name = "ERROR"), @JsonSubTypes.Type(value = LifeCycleEventFilter.class, name = "LC_EVENT"), @JsonSubTypes.Type(value = StatisticsEventFilter.class, name = "STATS") @@ -37,6 +37,6 @@ public interface EventFilter { @ApiModelProperty(position = 1, required = true, value = "String value representing the event type", example = "STATS") EventType getEventType(); - boolean hasFilterForJsonBody(); + boolean isNotEmpty(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java index de50f1579f..104939d202 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java @@ -39,7 +39,7 @@ public class LifeCycleEventFilter implements EventFilter { } @Override - public boolean hasFilterForJsonBody() { + public boolean isNotEmpty() { return !StringUtils.isEmpty(server) || !StringUtils.isEmpty(event) || !StringUtils.isEmpty(status) || !StringUtils.isEmpty(errorStr); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java index 52c961c1c8..7de37d1b5b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data.event; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,7 +23,6 @@ import lombok.Setter; import lombok.ToString; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EventInfo; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import java.util.UUID; @@ -40,9 +40,11 @@ public class RuleChainDebugEvent extends Event { this.error = error; } - @Getter @Setter + @Getter + @Setter private String message; - @Getter @Setter + @Getter + @Setter private String error; @Override @@ -52,6 +54,10 @@ public class RuleChainDebugEvent extends Event { @Override public EventInfo toInfo(EntityType entityType) { - return null; + EventInfo eventInfo = super.toInfo(entityType); + var json = (ObjectNode) eventInfo.getBody(); + putNotNull(json, "message", message); + putNotNull(json, "error", error); + return eventInfo; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleChainEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java similarity index 61% rename from common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleChainEventFilter.java rename to common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java index 3569e097d0..f40471a35f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugRuleChainEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java @@ -16,11 +16,26 @@ package org.thingsboard.server.common.data.event; import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.thingsboard.server.common.data.StringUtils; +@Data +@EqualsAndHashCode(callSuper = true) @ApiModel -public class DebugRuleChainEventFilter extends DebugEvent { +public class RuleChainDebugEventFilter extends DebugEventFilter { + + @ApiModelProperty(position = 2, value = "String value representing the message") + protected String message; + @Override public EventType getEventType() { return EventType.DEBUG_RULE_CHAIN; } + + @Override + public boolean isNotEmpty() { + return super.isNotEmpty() || !StringUtils.isEmpty(message); + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java index 891ece5f22..fdca84239d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data.event; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -62,14 +63,16 @@ public class RuleNodeDebugEvent extends Event { private final String dataType; @Getter private final String relationType; - @Getter @Setter + @Getter + @Setter private String data; - @Getter @Setter + @Getter + @Setter private String metadata; - @Getter @Setter + @Getter + @Setter private String error; - //TODO: rename the enum constant @Override public EventType getType() { return EventType.DEBUG_RULE_NODE; @@ -77,6 +80,22 @@ public class RuleNodeDebugEvent extends Event { @Override public EventInfo toInfo(EntityType entityType) { - return null; + EventInfo eventInfo = super.toInfo(entityType); + var json = (ObjectNode) eventInfo.getBody(); + json.put("type", eventType); + if (eventEntity != null) { + json.put("entityId", eventEntity.getId().toString()).put("entityType", eventEntity.getEntityType().name()); + } + if (msgId != null) { + json.put("msgId", msgId.toString()); + } + putNotNull(json, "msgType", msgType); + putNotNull(json, "dataType", dataType); + putNotNull(json, "relationType", relationType); + putNotNull(json, "data", data); + putNotNull(json, "metadata", metadata); + putNotNull(json, "error", error); + return eventInfo; } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java similarity index 59% rename from common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEvent.java rename to common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java index 90bbff0bd5..aa44141365 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEvent.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java @@ -18,41 +18,40 @@ package org.thingsboard.server.common.data.event; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; @Data +@EqualsAndHashCode(callSuper = true) @ApiModel -public abstract class DebugEvent implements EventFilter { +public class RuleNodeDebugEventFilter extends DebugEventFilter { - @ApiModelProperty(position = 1, value = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") + @ApiModelProperty(position = 2, value = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") protected String msgDirectionType; - @ApiModelProperty(position = 2, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") - protected String server; - @ApiModelProperty(position = 3, value = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") - protected String dataSearch; - @ApiModelProperty(position = 4, value = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") - protected String metadataSearch; - @ApiModelProperty(position = 5, value = "String value representing the entity type", allowableValues = "DEVICE") - protected String entityName; - @ApiModelProperty(position = 6, value = "String value representing the type of message routing", example = "Success") - protected String relationType; - @ApiModelProperty(position = 7, value = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + @ApiModelProperty(position = 3, value = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") protected String entityId; - @ApiModelProperty(position = 8, value = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") + @ApiModelProperty(position = 4, value = "String value representing the entity type", allowableValues = "DEVICE") + protected String entityType; + @ApiModelProperty(position = 5, value = "String value representing the message id in the rule engine", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + protected String msgId; + @ApiModelProperty(position = 6, value = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") protected String msgType; - @ApiModelProperty(position = 9, value = "Boolean value to filter the errors", allowableValues = "false, true") - protected boolean isError; - @ApiModelProperty(position = 10, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") - protected String errorStr; + @ApiModelProperty(position = 7, value = "String value representing the type of message routing", example = "Success") + protected String relationType; + @ApiModelProperty(position = 8, value = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") + protected String dataSearch; + @ApiModelProperty(position = 9, value = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") + protected String metadataSearch; - public void setIsError(boolean isError) { - this.isError = isError; + @Override + public EventType getEventType() { + return EventType.DEBUG_RULE_NODE; } @Override - public boolean hasFilterForJsonBody() { - return !StringUtils.isEmpty(msgDirectionType) || !StringUtils.isEmpty(server) || !StringUtils.isEmpty(dataSearch) || !StringUtils.isEmpty(metadataSearch) - || !StringUtils.isEmpty(entityName) || !StringUtils.isEmpty(relationType) || !StringUtils.isEmpty(entityId) || !StringUtils.isEmpty(msgType) || !StringUtils.isEmpty(errorStr) || isError; + public boolean isNotEmpty() { + return super.isNotEmpty() || !StringUtils.isEmpty(msgDirectionType) || !StringUtils.isEmpty(entityId) + || !StringUtils.isEmpty(entityType) || !StringUtils.isEmpty(msgId) || !StringUtils.isEmpty(msgType) || + !StringUtils.isEmpty(relationType) || !StringUtils.isEmpty(dataSearch) || !StringUtils.isEmpty(metadataSearch); } - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java index b132ff02da..a48d03dcce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java @@ -37,7 +37,7 @@ public class StatisticsEventFilter implements EventFilter { } @Override - public boolean hasFilterForJsonBody() { + public boolean isNotEmpty() { return !StringUtils.isEmpty(server) || (messagesProcessed != null && messagesProcessed > 0) || (errorsOccurred != null && errorsOccurred > 0); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 311af9af44..85088667f1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -102,7 +102,7 @@ public class BaseEventService implements EventService { @Override public List findLatestEvents(TenantId tenantId, EntityId entityId, EventType eventType, int limit) { - return eventDao.findLatestEvents(tenantId.getId(), entityId.getId(), eventType, limit); + return convert(entityId.getEntityType(), eventDao.findLatestEvents(tenantId.getId(), entityId.getId(), eventType, limit)); } @Override @@ -142,4 +142,8 @@ public class BaseEventService implements EventService { pd.getData().stream().map(e -> e.toInfo(entityType)).collect(Collectors.toList()) , pd.getTotalPages(), pd.getTotalElements(), pd.hasNext()); } + + private List convert(EntityType entityType, List list) { + return list == null ? null : list.stream().map(e -> e.toInfo(entityType)).collect(Collectors.toList()); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java b/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java index 1878594fb4..718cb41d7c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java @@ -41,16 +41,6 @@ public interface EventDao { */ ListenableFuture saveAsync(Event event); - /** - * Find events by tenantId, entityId and pageLink. - * - * @param tenantId the tenantId - * @param entityId the entityId - * @param pageLink the pageLink - * @return the event list - */ - PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink); - /** * Find events by tenantId, entityId, eventType and pageLink. * @@ -73,7 +63,7 @@ public interface EventDao { * @param limit the limit * @return the event list */ - List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit); + List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit); /** * Executes stored procedure to cleanup old events. Uses separate ttl for debug and other events. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 37934ed306..171417402d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -388,6 +388,16 @@ public class ModelConstants { public static final String EVENT_ERROR_COLUMN_NAME = "e_error"; public static final String EVENT_SUCCESS_COLUMN_NAME = "e_success"; + public static final String EVENT_ENTITY_ID_COLUMN_NAME = "e_entity_id"; + public static final String EVENT_ENTITY_TYPE_COLUMN_NAME = "e_entity_type"; + public static final String EVENT_MSG_ID_COLUMN_NAME = "e_msg_id"; + public static final String EVENT_MSG_TYPE_COLUMN_NAME = "e_msg_type"; + public static final String EVENT_DATA_TYPE_COLUMN_NAME = "e_data_type"; + public static final String EVENT_RELATION_TYPE_COLUMN_NAME = "e_relation_type"; + public static final String EVENT_DATA_COLUMN_NAME = "e_data"; + public static final String EVENT_METADATA_COLUMN_NAME = "e_metadata"; + public static final String EVENT_MESSAGE_COLUMN_NAME = "e_message"; + public static final String DEBUG_MODE = "debug_mode"; /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java index 4da17d2c34..8e7474f96e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java @@ -31,7 +31,6 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; - import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.ADMIN_SETTINGS_COLUMN_FAMILY_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java index f2d1970238..893c9d549c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java @@ -30,7 +30,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.OtaPackageId; -import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java index 397824140f..2175c97c94 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java @@ -18,30 +18,21 @@ package org.thingsboard.server.dao.model.sql; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.event.ErrorEvent; -import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import java.util.UUID; - import static org.thingsboard.server.dao.model.ModelConstants.ERROR_EVENT_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_METHOD_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.STATS_EVENT_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ERROR_EVENT_TABLE_NAME) @NoArgsConstructor public class ErrorEventEntity extends EventEntity implements BaseEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java index b0a0135849..0e78d22600 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java @@ -17,11 +17,9 @@ package org.thingsboard.server.dao.model.sql; import lombok.Data; import lombok.NoArgsConstructor; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Id; @@ -34,7 +32,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TENANT_ID_PR import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN; @Data -@TypeDef(name = "json", typeClass = JsonStringType.class) @NoArgsConstructor @MappedSuperclass public abstract class EventEntity implements BaseEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java index 0a4380cb63..874cc4ea00 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java @@ -18,11 +18,9 @@ package org.thingsboard.server.dao.model.sql; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; @@ -36,7 +34,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.LC_EVENT_TABLE_NAM @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = LC_EVENT_TABLE_NAME) @NoArgsConstructor public class LifecycleEventEntity extends EventEntity implements BaseEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java new file mode 100644 index 0000000000..7968521f62 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java @@ -0,0 +1,63 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.sql; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.event.RuleChainDebugEvent; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.model.BaseEntity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MESSAGE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_DEBUG_EVENT_TABLE_NAME; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@Table(name = RULE_CHAIN_DEBUG_EVENT_TABLE_NAME) +@NoArgsConstructor +public class RuleChainDebugEventEntity extends EventEntity implements BaseEntity { + + @Column(name = EVENT_MESSAGE_COLUMN_NAME) + private String message; + @Column(name = EVENT_ERROR_COLUMN_NAME) + private String error; + + public RuleChainDebugEventEntity(RuleChainDebugEvent event) { + super(event); + this.message = event.getMessage(); + this.error = event.getError(); + } + + @Override + public RuleChainDebugEvent toData() { + return RuleChainDebugEvent.builder() + .tenantId(TenantId.fromUUID(tenantId)) + .entityId(entityId) + .serviceId(serviceId) + .id(id) + .ts(ts) + .message(message) + .error(error).build(); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java new file mode 100644 index 0000000000..6e75515b14 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java @@ -0,0 +1,109 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.sql; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.model.BaseEntity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_DATA_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_DATA_TYPE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_ID_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_TYPE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_METADATA_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MSG_ID_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MSG_TYPE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_RELATION_TYPE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.RULE_NODE_DEBUG_EVENT_TABLE_NAME; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@Table(name = RULE_NODE_DEBUG_EVENT_TABLE_NAME) +@NoArgsConstructor +public class RuleNodeDebugEventEntity extends EventEntity implements BaseEntity { + + @Column(name = EVENT_TYPE_COLUMN_NAME) + private String eventType; + @Column(name = EVENT_ENTITY_ID_COLUMN_NAME) + private UUID eventEntityId; + @Column(name = EVENT_ENTITY_TYPE_COLUMN_NAME) + private String eventEntityType; + @Column(name = EVENT_MSG_ID_COLUMN_NAME) + private UUID msgId; + @Column(name = EVENT_MSG_TYPE_COLUMN_NAME) + private String msgType; + @Column(name = EVENT_DATA_TYPE_COLUMN_NAME) + private String dataType; + @Column(name = EVENT_RELATION_TYPE_COLUMN_NAME) + private String relationType; + @Column(name = EVENT_DATA_COLUMN_NAME) + private String data; + @Column(name = EVENT_METADATA_COLUMN_NAME) + private String metadata; + @Column(name = EVENT_ERROR_COLUMN_NAME) + private String error; + + public RuleNodeDebugEventEntity(RuleNodeDebugEvent event) { + super(event); + this.eventType = event.getEventType(); + if (event.getEventEntity() != null) { + this.eventEntityId = event.getEventEntity().getId(); + this.eventEntityType = event.getEventEntity().getEntityType().name(); + } + this.msgId = event.getMsgId(); + this.msgType = event.getMsgType(); + this.dataType = event.getDataType(); + this.relationType = event.getRelationType(); + this.data = event.getData(); + this.metadata = event.getMetadata(); + this.error = event.getError(); + } + + @Override + public RuleNodeDebugEvent toData() { + var builder = RuleNodeDebugEvent.builder() + .tenantId(TenantId.fromUUID(tenantId)) + .entityId(entityId) + .serviceId(serviceId) + .id(id) + .ts(ts) + .eventType(eventType) + .msgId(msgId) + .msgType(msgType) + .dataType(dataType) + .relationType(relationType) + .data(data) + .metadata(metadata) + .error(error); + if (eventEntityId != null) { + builder.eventEntity(EntityIdFactory.getByTypeAndUuid(eventEntityType, eventEntityId)); + } + return builder.build(); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java index 240e6fdcf7..9e151a1c24 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java @@ -18,29 +18,21 @@ package org.thingsboard.server.dao.model.sql; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.hibernate.annotations.TypeDef; -import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERRORS_OCCURRED_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MESSAGES_PROCESSED_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME; -import static org.thingsboard.server.dao.model.ModelConstants.LC_EVENT_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.STATS_EVENT_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = STATS_EVENT_TABLE_NAME) @NoArgsConstructor public class StatisticsEventEntity extends EventEntity implements BaseEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java index 721ffe42fe..b4fcfcdcc7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java @@ -20,17 +20,23 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.dao.model.sql.ErrorEventEntity; import org.thingsboard.server.dao.model.sql.LifecycleEventEntity; import org.thingsboard.server.dao.model.sql.StatisticsEventEntity; +import java.util.List; import java.util.UUID; -/** - * Created by Valerii Sosliuk on 5/3/2017. - */ -public interface ErrorEventRepository extends JpaRepository { +public interface ErrorEventRepository extends EventRepository, JpaRepository { + + @Override + @Query("SELECT e FROM ErrorEventEntity e WHERE e.tenantId = :tenantId AND e.entityId = :entityId ORDER BY e.ts DESC") + List findLatestEvents(UUID tenantId, UUID entityId, int limit); + + @Override @Query("SELECT e FROM ErrorEventEntity e WHERE " + "e.tenantId = :tenantId " + "AND e.entityId = :entityId " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java index 79d7d250e7..85220ddf9f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.dao.sql.event; -import org.jetbrains.annotations.NotNull; -import org.postgresql.core.Oid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.BatchPreparedStatementSetter; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java index 8a967395ab..46e0ff6662 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java @@ -21,6 +21,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.dao.model.sql.EventEntity; import java.util.List; @@ -29,58 +31,12 @@ import java.util.UUID; /** * Created by Valerii Sosliuk on 5/3/2017. */ -public interface EventRepository extends JpaRepository { +public interface EventRepository, V extends Event> { + + List findLatestEvents(UUID tenantId, UUID entityId, int limit); + + Page findEvents(UUID tenantId, UUID entityId, Long startTime, Long endTime, Pageable pageable); -// EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId, -// EntityType entityType, -// UUID entityId, -// String eventType, -// String eventUid); -// -// EventEntity findByTenantIdAndEntityTypeAndEntityId(UUID tenantId, -// EntityType entityType, -// UUID entityId); -// -// @Query("SELECT e FROM EventEntity e WHERE e.tenantId = :tenantId AND e.entityType = :entityType " + -// "AND e.entityId = :entityId AND e.eventType = :eventType ORDER BY e.eventType DESC, e.id DESC") -// List findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType( -// @Param("tenantId") UUID tenantId, -// @Param("entityType") EntityType entityType, -// @Param("entityId") UUID entityId, -// @Param("eventType") String eventType, -// Pageable pageable); -// -// @Query("SELECT e FROM EventEntity e WHERE " + -// "e.tenantId = :tenantId " + -// "AND e.entityType = :entityType AND e.entityId = :entityId " + -// "AND (:startTime IS NULL OR e.createdTime >= :startTime) " + -// "AND (:endTime IS NULL OR e.createdTime <= :endTime) " + -// "AND LOWER(e.eventType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" -// ) -// Page findEventsByTenantIdAndEntityId(@Param("tenantId") UUID tenantId, -// @Param("entityType") EntityType entityType, -// @Param("entityId") UUID entityId, -// @Param("textSearch") String textSearch, -// @Param("startTime") Long startTime, -// @Param("endTime") Long endTime, -// Pageable pageable); -// -// -// -// @Query("SELECT e FROM EventEntity e WHERE " + -// "e.tenantId = :tenantId " + -// "AND e.entityType = :entityType AND e.entityId = :entityId " + -// "AND e.eventType = :eventType " + -// "AND (:startTime IS NULL OR e.createdTime >= :startTime) " + -// "AND (:endTime IS NULL OR e.createdTime <= :endTime)" -// ) -// Page findEventsByTenantIdAndEntityIdAndEventType(@Param("tenantId") UUID tenantId, -// @Param("entityType") EntityType entityType, -// @Param("entityId") UUID entityId, -// @Param("eventType") String eventType, -// @Param("startTime") Long startTime, -// @Param("endTime") Long endTime, -// Pageable pageable); // // @Query(nativeQuery = true, // value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index 0717fa6896..26117637d5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java @@ -23,25 +23,22 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.data.event.DebugEvent; -import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.RuleChainDebugEventFilter; +import org.thingsboard.server.common.data.event.RuleNodeDebugEventFilter; import org.thingsboard.server.common.data.event.ErrorEventFilter; import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.common.data.event.EventFilter; import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.event.LifeCycleEventFilter; -import org.thingsboard.server.common.data.event.LifecycleEvent; -import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.common.data.event.StatisticsEventFilter; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.event.EventDao; +import org.thingsboard.server.dao.model.sql.EventEntity; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; @@ -51,6 +48,7 @@ import org.thingsboard.server.dao.timeseries.SqlPartition; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -74,9 +72,6 @@ public class JpaBaseEventDao implements EventDao { @Autowired private SqlPartitioningRepository partitioningRepository; - @Autowired - private EventRepository eventRepository; - @Autowired private LifecycleEventRepository lcEventRepository; @@ -92,6 +87,12 @@ public class JpaBaseEventDao implements EventDao { @Autowired private EventCleanupRepository eventCleanupRepository; + @Autowired + private RuleNodeDebugEventRepository ruleNodeDebugEventRepository; + + @Autowired + private RuleChainDebugEventRepository ruleChainDebugEventRepository; + @Autowired ScheduledLogExecutorComponent logExecutor; @@ -115,6 +116,8 @@ public class JpaBaseEventDao implements EventDao { private TbSqlBlockingQueueWrapper queue; + private final Map> repositories = new ConcurrentHashMap<>(); + @PostConstruct private void init() { for (EventType eventType : EventType.values()) { @@ -131,6 +134,11 @@ public class JpaBaseEventDao implements EventDao { Function hashcodeFunction = entity -> Objects.hash(super.hashCode(), entity.getTenantId(), entity.getEntityId()); queue = new TbSqlBlockingQueueWrapper<>(params, hashcodeFunction, batchThreads, statsFactory); queue.init(logExecutor, v -> eventInsertRepository.save(v), Comparator.comparing(Event::getCreatedTime)); + repositories.put(EventType.LC_EVENT, lcEventRepository); + repositories.put(EventType.STATS, statsEventRepository); + repositories.put(EventType.ERROR, errorEventRepository); + repositories.put(EventType.DEBUG_RULE_NODE, ruleNodeDebugEventRepository); + repositories.put(EventType.DEBUG_RULE_CHAIN, ruleChainDebugEventRepository); } @PreDestroy @@ -190,58 +198,19 @@ public class JpaBaseEventDao implements EventDao { } } - @Override - public PageData findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) { - return null; -// return DaoUtil.toPageData( -// eventRepository -// .findEventsByTenantIdAndEntityId( -// tenantId, -// entityId.getEntityType(), -// entityId.getId(), -// Objects.toString(pageLink.getTextSearch(), ""), -// pageLink.getStartTime(), -// pageLink.getEndTime(), -// DaoUtil.toPageable(pageLink))); - } - @Override public PageData findEvents(UUID tenantId, UUID entityId, EventType eventType, TimePageLink pageLink) { - switch (eventType) { - case LC_EVENT: - return findLcEventsWithoutFilter(tenantId, entityId, pageLink); - case STATS: - return findStatsEventsWithoutFilter(tenantId, entityId, pageLink); - case ERROR: - return findErrorEventsWithoutFilter(tenantId, entityId, pageLink); - default: - throw new RuntimeException("Event type: " + eventType + " is not supported!"); - } + return DaoUtil.toPageData(getEventRepository(eventType).findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); } - private PageData findLcEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { - return DaoUtil.toPageData( - lcEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); - } - - private PageData findStatsEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { - return DaoUtil.toPageData( - statsEventRepository.findEventsWithoutFilter(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); - } - - private PageData findErrorEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { - return DaoUtil.toPageData( - errorEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); - } - - @Override public PageData findEventByFilter(UUID tenantId, UUID entityId, EventFilter eventFilter, TimePageLink pageLink) { - if (eventFilter.hasFilterForJsonBody()) { + if (eventFilter.isNotEmpty()) { switch (eventFilter.getEventType()) { case DEBUG_RULE_NODE: + return findEventByFilter(tenantId, entityId, (RuleNodeDebugEventFilter) eventFilter, pageLink); case DEBUG_RULE_CHAIN: - return findEventByFilter(tenantId, entityId, (DebugEvent) eventFilter, pageLink); + return findEventByFilter(tenantId, entityId, (RuleChainDebugEventFilter) eventFilter, pageLink); case LC_EVENT: return findEventByFilter(tenantId, entityId, (LifeCycleEventFilter) eventFilter, pageLink); case ERROR: @@ -256,27 +225,41 @@ public class JpaBaseEventDao implements EventDao { } } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, DebugEvent eventFilter, TimePageLink pageLink) { - return null; -// return DaoUtil.toPageData( -// eventRepository.findDebugRuleNodeEvents( -// tenantId, -// entityId.getId(), -// entityId.getEntityType().name(), -// eventFilter.getEventType().name(), -// notNull(pageLink.getStartTime()), -// notNull(pageLink.getEndTime()), -// eventFilter.getMsgDirectionType(), -// eventFilter.getServer(), -// eventFilter.getEntityName(), -// eventFilter.getRelationType(), -// eventFilter.getEntityId(), -// eventFilter.getMsgType(), -// eventFilter.isError(), -// eventFilter.getErrorStr(), -// eventFilter.getDataSearch(), -// eventFilter.getMetadataSearch(), -// DaoUtil.toPageable(pageLink))); + private PageData findEventByFilter(UUID tenantId, UUID entityId, RuleChainDebugEventFilter eventFilter, TimePageLink pageLink) { + return DaoUtil.toPageData( + ruleChainDebugEventRepository.findEvents( + tenantId, + entityId, + pageLink.getStartTime(), + pageLink.getEndTime(), + eventFilter.getServer(), + eventFilter.getMessage(), + eventFilter.isError(), + eventFilter.getErrorStr(), + DaoUtil.toPageable(pageLink))); + } + + private PageData findEventByFilter(UUID tenantId, UUID entityId, RuleNodeDebugEventFilter eventFilter, TimePageLink pageLink) { + parseUUID(eventFilter.getEntityId(), "Entity Id"); + parseUUID(eventFilter.getMsgId(), "Message Id"); + return DaoUtil.toPageData( + ruleNodeDebugEventRepository.findEvents( + tenantId, + entityId, + pageLink.getStartTime(), + pageLink.getEndTime(), + eventFilter.getServer(), + eventFilter.getMsgDirectionType(), + eventFilter.getEntityId(), + eventFilter.getEntityType(), + eventFilter.getMsgId(), + eventFilter.getMsgType(), + eventFilter.getRelationType(), + eventFilter.getDataSearch(), + eventFilter.getMetadataSearch(), + eventFilter.isError(), + eventFilter.getErrorStr(), + DaoUtil.toPageable(pageLink))); } private PageData findEventByFilter(UUID tenantId, UUID entityId, ErrorEventFilter eventFilter, TimePageLink pageLink) { @@ -311,32 +294,23 @@ public class JpaBaseEventDao implements EventDao { ); } - private PageData findEventByFilter(UUID tenantId, EntityId entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) { - return null; -// return DaoUtil.toPageData( -// eventRepository.findStatisticsEvents( -// tenantId, -// entityId.getId(), -// entityId.getEntityType().name(), -// notNull(pageLink.getStartTime()), -// notNull(pageLink.getEndTime()), -// eventFilter.getServer(), -// notNull(eventFilter.getMessagesProcessed()), -// notNull(eventFilter.getErrorsOccurred()), -// DaoUtil.toPageable(pageLink)) -// ); + private PageData findEventByFilter(UUID tenantId, UUID entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) { + return DaoUtil.toPageData( + statsEventRepository.findEvents( + tenantId, + entityId, + pageLink.getStartTime(), + pageLink.getEndTime(), + eventFilter.getServer(), + eventFilter.getMessagesProcessed(), + eventFilter.getErrorsOccurred(), + DaoUtil.toPageable(pageLink)) + ); } @Override - public List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit) { - return null; -// List latest = eventRepository.findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType( -// tenantId, -// entityId.getEntityType(), -// entityId.getId(), -// eventType, -// PageRequest.of(0, limit)); -// return DaoUtil.convertDataList(latest); + public List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit) { + return DaoUtil.convertDataList(getEventRepository(eventType).findLatestEvents(tenantId, entityId, limit)); } @Override @@ -345,12 +319,23 @@ public class JpaBaseEventDao implements EventDao { eventCleanupRepository.cleanupEvents(regularEventStartTs, regularEventEndTs, debugEventStartTs, debugEventEndTs); } - private long notNull(Long value) { - return value != null ? value : 0; + private void parseUUID(String src, String paramName) { + if (!StringUtils.isEmpty(src)) { + try { + UUID.fromString(src); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert " + paramName + " to UUID!"); + } + } } - private int notNull(Integer value) { - return value != null ? value : 0; + private EventRepository, ?> getEventRepository(EventType eventType) { + var repository = repositories.get(eventType); + if (repository == null) { + throw new RuntimeException("Event type: " + eventType + " is not supported!"); + } + return repository; } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java index f95959ad29..298e57a1b9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java @@ -20,14 +20,18 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.dao.model.sql.LifecycleEventEntity; +import java.util.List; import java.util.UUID; -/** - * Created by Valerii Sosliuk on 5/3/2017. - */ -public interface LifecycleEventRepository extends JpaRepository { +public interface LifecycleEventRepository extends EventRepository, JpaRepository { + + @Override + @Query("SELECT e FROM LifecycleEventEntity e WHERE e.tenantId = :tenantId AND e.entityId = :entityId ORDER BY e.ts DESC") + List findLatestEvents(UUID tenantId, UUID entityId, int limit); + @Query("SELECT e FROM LifecycleEventEntity e WHERE " + "e.tenantId = :tenantId " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleChainDebugEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleChainDebugEventRepository.java new file mode 100644 index 0000000000..32d27765a5 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleChainDebugEventRepository.java @@ -0,0 +1,82 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.event; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.event.RuleChainDebugEvent; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; +import org.thingsboard.server.dao.model.sql.RuleChainDebugEventEntity; +import org.thingsboard.server.dao.model.sql.RuleNodeDebugEventEntity; + +import java.util.List; +import java.util.UUID; + + +public interface RuleChainDebugEventRepository extends EventRepository, JpaRepository { + + @Override + @Query("SELECT e FROM RuleChainDebugEventEntity e WHERE e.tenantId = :tenantId AND e.entityId = :entityId ORDER BY e.ts DESC") + List findLatestEvents(UUID tenantId, UUID entityId, int limit); + + @Override + @Query("SELECT e FROM RuleChainDebugEventEntity e WHERE " + + "e.tenantId = :tenantId " + + "AND e.entityId = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime)" + ) + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + Pageable pageable); + + @Query(nativeQuery = true, + value = "SELECT * FROM rule_chain_debug_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:message IS NULL OR e.e_message ILIKE concat('%', :message, '%')) " + + "AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + + "AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" + , + countQuery = "SELECT count(*) FROM rule_chain_debug_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:message IS NULL OR e.e_message ILIKE concat('%', :message, '%')) " + + "AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + + "AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" + ) + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + @Param("serviceId") String server, + @Param("message") String message, + @Param("isError") boolean isError, + @Param("error") String error, + Pageable pageable); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleNodeDebugEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleNodeDebugEventRepository.java new file mode 100644 index 0000000000..6238acd5ac --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/RuleNodeDebugEventRepository.java @@ -0,0 +1,103 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.event; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.event.ErrorEvent; +import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; +import org.thingsboard.server.dao.model.sql.ErrorEventEntity; +import org.thingsboard.server.dao.model.sql.RuleNodeDebugEventEntity; + +import java.util.List; +import java.util.UUID; + + +public interface RuleNodeDebugEventRepository extends EventRepository, JpaRepository { + + @Override + @Query("SELECT e FROM RuleNodeDebugEventEntity e WHERE e.tenantId = :tenantId AND e.entityId = :entityId ORDER BY e.ts DESC") + List findLatestEvents(UUID tenantId, UUID entityId, int limit); + + @Override + @Query("SELECT e FROM RuleNodeDebugEventEntity e WHERE " + + "e.tenantId = :tenantId " + + "AND e.entityId = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime)" + ) + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + Pageable pageable); + + @Query(nativeQuery = true, + value = "SELECT * FROM rule_node_debug_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:eventType IS NULL OR e.e_type ILIKE concat('%', :eventType, '%')) " + + "AND (:eventEntityId IS NULL OR e.e_entity_id = uuid(:eventEntityId)) " + + "AND (:eventEntityType IS NULL OR e.e_entity_type ILIKE concat('%', :eventEntityType, '%')) " + + "AND (:msgId IS NULL OR e.e_msg_id = uuid(:msgId)) " + + "AND (:msgType IS NULL OR e.e_msg_type ILIKE concat('%', :msgType, '%')) " + + "AND (:relationType IS NULL OR e.e_relation_type ILIKE concat('%', :relationType, '%')) " + + "AND (:data IS NULL OR e.e_data ILIKE concat('%', :data, '%')) " + + "AND (:metadata IS NULL OR e.e_metadata ILIKE concat('%', :metadata, '%')) " + + "AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + + "AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" + , + countQuery = "SELECT count(*) FROM rule_node_debug_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:eventType IS NULL OR e.e_type ILIKE concat('%', :eventType, '%')) " + + "AND (:eventEntityId IS NULL OR e.e_entity_id = uuid(:eventEntityId)) " + + "AND (:eventEntityType IS NULL OR e.e_entity_type ILIKE concat('%', :eventEntityType, '%')) " + + "AND (:msgId IS NULL OR e.e_msg_id = uuid(:msgId)) " + + "AND (:msgType IS NULL OR e.e_msg_type ILIKE concat('%', :msgType, '%')) " + + "AND (:relationType IS NULL OR e.e_relation_type ILIKE concat('%', :relationType, '%')) " + + "AND (:data IS NULL OR e.e_data ILIKE concat('%', :data, '%')) " + + "AND (:metadata IS NULL OR e.e_metadata ILIKE concat('%', :metadata, '%')) " + + "AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + + "AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" + ) + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + @Param("serviceId") String server, + @Param("eventType") String type, + @Param("eventEntityId") String eventEntityId, + @Param("eventEntityType") String eventEntityType, + @Param("msgId") String eventMsgId, + @Param("msgType") String eventMsgType, + @Param("relationType") String relationType, + @Param("data") String data, + @Param("metadata") String metadata, + @Param("isError") boolean isError, + @Param("error") String error, + Pageable pageable); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java index 2d41501933..5eee96efbc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java @@ -21,15 +21,16 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.thingsboard.server.common.data.event.StatisticsEvent; -import org.thingsboard.server.dao.model.sql.LifecycleEventEntity; import org.thingsboard.server.dao.model.sql.StatisticsEventEntity; +import java.util.List; import java.util.UUID; -/** - * Created by Valerii Sosliuk on 5/3/2017. - */ -public interface StatisticsEventRepository extends JpaRepository { +public interface StatisticsEventRepository extends EventRepository, JpaRepository { + + @Override + @Query("SELECT e FROM LifecycleEventEntity e WHERE e.tenantId = :tenantId AND e.entityId = :entityId ORDER BY e.ts DESC") + List findLatestEvents(UUID tenantId, UUID entityId, int limit); @Query("SELECT e FROM StatisticsEventEntity e WHERE " + "e.tenantId = :tenantId " + @@ -37,10 +38,38 @@ public interface StatisticsEventRepository extends JpaRepository= :startTime) " + "AND (:endTime IS NULL OR e.ts <= :endTime)" ) - Page findEventsWithoutFilter(@Param("tenantId") UUID tenantId, - @Param("entityId") UUID entityId, - @Param("startTime") Long startTime, - @Param("endTime") Long endTime, - Pageable pageable); + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + Pageable pageable); + + @Query(nativeQuery = true, + value = "SELECT * FROM stats_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:messagesProcessed IS NULL OR e.e_messages_processed >= :messagesProcessed) " + + "AND (:errorsOccurred IS NULL OR e.e_errors_occurred >= :errorsOccurred)" + , + countQuery = "SELECT count(*) FROM stats_event e WHERE " + + "e.tenant_id = :tenantId " + + "AND e.entity_id = :entityId " + + "AND (:startTime IS NULL OR e.ts >= :startTime) " + + "AND (:endTime IS NULL OR e.ts <= :endTime) " + + "AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + + "AND (:messagesProcessed IS NULL OR e.e_messages_processed >= :messagesProcessed) " + + "AND (:errorsOccurred IS NULL OR e.e_errors_occurred >= :errorsOccurred)" + ) + Page findEvents(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + @Param("serviceId") String server, + @Param("messagesProcessed") Integer messagesProcessed, + @Param("errorsOccurred") Integer errorsOccurred, + Pageable pageable); } diff --git a/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql b/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql index b8fc60ecca..d78257ad8b 100644 --- a/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql +++ b/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql @@ -22,17 +22,17 @@ -- That why we need to define DESC index explicitly as (ts DESC NULLS LAST) CREATE INDEX IF NOT EXISTS idx_rule_node_debug_event_main - ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95); + ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); CREATE INDEX IF NOT EXISTS idx_rule_chain_debug_event_main - ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95); + ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); CREATE INDEX IF NOT EXISTS idx_stats_event_main - ON stats_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95); + ON stats_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); CREATE INDEX IF NOT EXISTS idx_lc_event_main - ON lc_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95); + ON lc_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); CREATE INDEX IF NOT EXISTS idx_error_event_main - ON error_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95); + ON error_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 1ab89c7885..22f36a2bfb 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -336,9 +336,9 @@ CREATE TABLE IF NOT EXISTS rule_node_debug_event ( e_msg_type varchar, e_data_type varchar, e_relation_type varchar, - e_data varchar NOT NULL, - e_metadata varchar NOT NULL, - e_error varchar NOT NULL + e_data varchar, + e_metadata varchar, + e_error varchar ) PARTITION BY RANGE (ts); CREATE TABLE IF NOT EXISTS rule_chain_debug_event ( diff --git a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts index 0aebf12bd5..4d6e43a34a 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/event/event-table-config.ts @@ -234,8 +234,8 @@ export class EventTableConfig extends EntityTableConfig { }), false, key => ({ padding: '0 12px 0 0' })), - new EntityTableColumn('entityName', 'event.entity-type', '100px', - (entity) => entity.body.entityName, entity => ({ + new EntityTableColumn('entityType', 'event.entity-type', '100px', + (entity) => entity.body.entityType, entity => ({ padding: '0 12px 0 0', }), false, key => ({ padding: '0 12px 0 0' diff --git a/ui-ngx/src/app/shared/models/event.models.ts b/ui-ngx/src/app/shared/models/event.models.ts index 220e7ce3b2..7ed4203dce 100644 --- a/ui-ngx/src/app/shared/models/event.models.ts +++ b/ui-ngx/src/app/shared/models/event.models.ts @@ -65,7 +65,7 @@ export interface StatsEventBody extends BaseEventBody { export interface DebugRuleNodeEventBody extends BaseEventBody { type: string; entityId: string; - entityName: string; + entityType: string; msgId: string; msgType: string; relationType: string; From 43b847b9d85ed89bd7a4b6e1a077e2548d79a6f3 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Tue, 26 Jul 2022 16:39:56 +0300 Subject: [PATCH 032/158] UI: Refactoring code --- .../rate-limits-list.component.html | 2 +- .../rate-limits/rate-limits-list.component.ts | 32 ++++++------------- .../rate-limits/rate-limits-text.component.ts | 3 +- .../rate-limits/rate-limits.component.html | 2 +- .../tenant/rate-limits/rate-limits.models.ts | 19 +++++------ 5 files changed, 22 insertions(+), 36 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html index ec25c80683..ba51cbc358 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.html @@ -61,6 +61,6 @@
tenant-profile.rate-limits.preview - +
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts index 0c135d0d9a..e6ad1c5b20 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-list.component.ts @@ -19,7 +19,6 @@ import { ControlValueAccessor, FormArray, FormBuilder, - FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, @@ -28,11 +27,7 @@ import { Validators } from '@angular/forms'; import { Subject, Subscription } from 'rxjs'; -import { - RateLimits, - rateLimitsArrayToString, - stringToRateLimitsArray -} from './rate-limits.models'; +import { RateLimits, rateLimitsArrayToString, stringToRateLimitsArray } from './rate-limits.models'; import { isDefinedAndNotNull } from '@core/utils'; import { takeUntil } from 'rxjs/operators'; @@ -59,11 +54,11 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, rateLimitsListFormGroup: FormGroup; - rateLimitsControl: FormControl; + rateLimitsArray: Array; - private propagateChange = (v: any) => { }; private valueChangeSubscription: Subscription = null; private destroy$ = new Subject(); + private propagateChange = (v: any) => { }; constructor(private fb: FormBuilder) {} @@ -71,7 +66,6 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, this.rateLimitsListFormGroup = this.fb.group({ rateLimits: this.fb.array([]) }); - this.rateLimitsControl = this.fb.control(null); this.valueChangeSubscription = this.rateLimitsListFormGroup.valueChanges .pipe(takeUntil(this.destroy$)) .subscribe((value) => { @@ -95,10 +89,6 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, return this.rateLimitsListFormGroup.get('rateLimits') as FormArray; } - get rateLimitsArray(): Array { - return this.rateLimitsControl.value; - } - registerOnChange(fn: any): void { this.propagateChange = fn; } @@ -110,23 +100,21 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, this.disabled = isDisabled; if (this.disabled) { this.rateLimitsListFormGroup.disable({emitEvent: false}); - this.rateLimitsControl.disable({emitEvent: false}); } else { this.rateLimitsListFormGroup.enable({emitEvent: false}); - this.rateLimitsControl.enable({emitEvent: false}); } } validate(): ValidationErrors | null { - return this.rateLimitsListFormGroup.valid && this.rateLimitsControl.valid ? null : { + return this.rateLimitsListFormGroup.valid ? null : { rateLimitsList: {valid: false} }; } - writeValue(value: string) { + writeValue(rateLimits: string) { const rateLimitsControls: Array = []; - if (value) { - let rateLimitsArray = value.split(','); + if (rateLimits) { + const rateLimitsArray = rateLimits.split(','); for (let i = 0; i < rateLimitsArray.length; i++) { const [value, time] = rateLimitsArray[i].split(':'); const rateLimitsControl = this.fb.group({ @@ -140,7 +128,7 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, } } this.rateLimitsListFormGroup.setControl('rateLimits', this.fb.array(rateLimitsControls), {emitEvent: false}); - this.rateLimitsControl.patchValue(stringToRateLimitsArray(value), {emitEvent: false}); + this.rateLimitsArray = stringToRateLimitsArray(rateLimits); } updateView(rateLimitsArray: Array) { @@ -150,10 +138,10 @@ export class RateLimitsListComponent implements ControlValueAccessor, Validator, ); const rateLimitsString = rateLimitsArrayToString(notNullRateLimits); this.propagateChange(rateLimitsString); - this.rateLimitsControl.patchValue(stringToRateLimitsArray(rateLimitsString), {emitEvent: false}); + this.rateLimitsArray = stringToRateLimitsArray(rateLimitsString); } else { this.propagateChange(null); - this.rateLimitsControl.patchValue(null, {emitEvent: false}); + this.rateLimitsArray = null; } } diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts index 0b65e97d5d..9081acc208 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits-text.component.ts @@ -33,7 +33,8 @@ export class RateLimitsTextComponent implements OnChanges { rateLimitsText: string; - constructor(private translate: TranslateService) {} + constructor(private translate: TranslateService) { + } ngOnChanges(changes: SimpleChanges): void { for (const propName of Object.keys(changes)) { diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html index ac341c8b69..0ab20fc533 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.component.html @@ -21,7 +21,7 @@
- +