From d54ddadd492824ae229e67fc0757de8d3838a8ea Mon Sep 17 00:00:00 2001 From: fe-dev Date: Wed, 13 Jul 2022 14:11:09 +0300 Subject: [PATCH 01/21] UI: improvement for VC popover --- .../vc/complex-version-create.component.html | 147 +++++++++--------- .../vc/complex-version-load.component.html | 111 +++++++------ ...entity-types-version-create.component.html | 8 +- .../entity-types-version-load.component.html | 5 +- .../vc/entity-version-create.component.html | 143 +++++++++-------- .../vc/entity-version-diff.component.html | 1 + .../vc/entity-version-diff.component.scss | 6 + .../vc/entity-version-restore.component.html | 121 +++++++------- .../vc/entity-versions-table.component.ts | 16 +- .../entity/entity-type-select.component.scss | 3 + 10 files changed, 288 insertions(+), 273 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html index e62c35e251..ef4226c393 100644 --- a/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html @@ -15,80 +15,79 @@ limitations under the License. --> -
-
- -

{{ 'version-control.create-entities-version' | translate }}

- -
- - -
-
-
- - - - version-control.version-name - - - {{ 'version-control.version-name-required' | translate }} - - - - version-control.default-sync-strategy - - - {{syncStrategyTranslations.get(strategy) | translate}} - - - - - - -
-
-
-
- - -
+ +
+ +

{{ 'version-control.create-entities-version' | translate }}

+ +
+ + +
+
+
+ + + + version-control.version-name + + + {{ 'version-control.version-name-required' | translate }} + + + + version-control.default-sync-strategy + + + {{syncStrategyTranslations.get(strategy) | translate}} + + + + + + +
+
+
+
+ + +
+
+
+
+
-
-
-
+
+ +
+ +
+
+ version-control.creating-version + +
-
- -
- -
-
- version-control.creating-version - -
-
-
-
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/complex-version-load.component.html b/ui-ngx/src/app/modules/home/components/vc/complex-version-load.component.html index 2df32ec5e2..4fd54b8b11 100644 --- a/ui-ngx/src/app/modules/home/components/vc/complex-version-load.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/complex-version-load.component.html @@ -15,60 +15,59 @@ limitations under the License. --> -
-
- -

{{ 'version-control.restore-entities-from-version' | translate: {versionName} }}

- -
- - -
-
-
- - -
-
-
-
- - -
-
-
-
- {{ 'version-control.no-entities-restored' | translate }} -
-
-
{{ entityTypeLoadResultMessage(entityTypeLoadResult) }}
-
- -
- -
-
- version-control.restoring-entities-from-version - -
-
-
-
+ +
+ +

{{ 'version-control.restore-entities-from-version' | translate: {versionName} }}

+ +
+ + +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ {{ 'version-control.no-entities-restored' | translate }} +
+
+
{{ entityTypeLoadResultMessage(entityTypeLoadResult) }}
+
+ +
+ +
+
+ version-control.restoring-entities-from-version + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html index 89b2a67c4d..9c9eb43f9b 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html @@ -43,7 +43,7 @@
-
+
-
+
version-control.sync-strategy @@ -76,8 +76,8 @@
-
+
{{ 'version-control.all-entities' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html index a171e4443f..f50098c9dd 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html @@ -43,15 +43,16 @@
-
+
-
+
-
-
- -

{{ 'version-control.create-entity-version' | translate }}

- -
- - -
-
-
- - - - version-control.version-name - - - {{ 'version-control.version-name-required' | translate }} - - - - {{ 'version-control.export-credentials' | translate }} - - - {{ 'version-control.export-attributes' | translate }} - - - {{ 'version-control.export-relations' | translate }} - -
-
-
-
- - -
-
-
-
-
-
{{ resultMessage }}
-
- -
-
+ +
+ +

{{ 'version-control.create-entity-version' | translate }}

+ +
+ + +
+
+
+ + + + version-control.version-name + + + {{ 'version-control.version-name-required' | translate }} + + + + {{ 'version-control.export-credentials' | translate }} + + + {{ 'version-control.export-attributes' | translate }} + + + {{ 'version-control.export-relations' | translate }} + +
+
+
+
+ + +
+
+
+
+
+
{{ resultMessage }}
+
+ +
- -
-
- version-control.creating-version - -
-
-
+ +
+
+ version-control.creating-version + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-diff.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-version-diff.component.html index 22bebd716f..aa0c9284a9 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-diff.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-diff.component.html @@ -41,6 +41,7 @@ - -
-
-
-
-
-
-
- -
-
+ +
+ +

{{ 'version-control.restore-entity-from-version' | translate: {versionName} }}

+ +
+ + + +
+
+
+ + {{ 'version-control.load-credentials' | translate }} + + + {{ 'version-control.load-attributes' | translate }} + + + {{ 'version-control.load-relations' | translate }} + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
- -
-
- version-control.restoring-entity-version - -
-
-
+ +
+
+ version-control.restoring-entity-version + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts index 0c4a7ca477..1073c26acc 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts @@ -217,7 +217,9 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } } - }, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false); + }, + {maxHeight: '100vh', height: '100%', padding: '10px'}, + {width: '400px', minWidth: '100%', maxWidth: '100%'}, {}, false); createVersionPopover.tbComponentRef.instance.popoverComponent = createVersionPopover; } } @@ -244,7 +246,9 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } } - }, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false); + }, + {maxHeight: '90vh', height: '100%', padding: '10px'}, + {width: '600px', minWidth: '100%', maxWidth: '100%'}, {}, false); complexCreateVersionPopover.tbComponentRef.instance.popoverComponent = complexCreateVersionPopover; } } @@ -292,7 +296,9 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni this.versionRestored.emit(); } } - }, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false); + }, + {maxHeight: '100vh', height: '100%', padding: '10px'}, + {width: '400px', minWidth: '100%', maxWidth: '100%'}, {}, false); restoreVersionPopover.tbComponentRef.instance.popoverComponent = restoreVersionPopover; } } @@ -313,7 +319,9 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni onClose: (result: VersionLoadResult | null) => { restoreEntitiesVersionPopover.hide(); } - }, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false); + }, + {maxHeight: '80vh', height: '100%', padding: '10px'}, + {width: '600px', minWidth: '100%', maxWidth: '100%'}, {}, false); restoreEntitiesVersionPopover.tbComponentRef.instance.popoverComponent = restoreEntitiesVersionPopover; } } diff --git a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.scss b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.scss index 4cf23ca6d5..f9f2391ed2 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.scss +++ b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.scss @@ -14,6 +14,9 @@ * limitations under the License. */ :host { + .mat-form-field { + width: 100%; + } } :host ::ng-deep { From 3eba68b1643cd4cc85ef940b96ba7e9e1660618c Mon Sep 17 00:00:00 2001 From: fe-dev Date: Wed, 13 Jul 2022 16:01:51 +0300 Subject: [PATCH 02/21] UI: refactoring --- .../vc/entity-types-version-create.component.html | 2 +- .../components/vc/entity-version-restore.component.html | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html index 9c9eb43f9b..656664784d 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html @@ -77,7 +77,7 @@
+ formGroupName="config" ngStyle.gt-xs="min-height: 76px;"> {{ 'version-control.all-entities' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html index b75f34af06..f218e3c8b9 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-restore.component.html @@ -27,14 +27,14 @@
-
- +
+ {{ 'version-control.load-credentials' | translate }} - + {{ 'version-control.load-attributes' | translate }} - + {{ 'version-control.load-relations' | translate }}
From fcb15bf99c687f3d2fe8033114758a26ea9e8f39 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Thu, 14 Jul 2022 18:13:47 +0300 Subject: [PATCH 03/21] UI: Fixed first loading and validation --- ui-ngx/src/app/shared/components/phone-input.component.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index 45f8151d5f..1be1e20d29 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -92,6 +92,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida this.isLoading = value; if (this.phoneFormGroup) { this.defineCountryFromNumber(this.phoneFormGroup.get('phoneNumber').value); + this.getFlagAndPhoneNumberData(this.phoneFormGroup.get('country').value); } } } @@ -183,7 +184,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida validatePhoneNumber(): ValidatorFn { return (c: FormControl) => { const phoneNumber = c.value; - if (phoneNumber && this.countryCallingCode !== phoneNumber && this.parsePhoneNumberFromString) { + if (phoneNumber && this.parsePhoneNumberFromString) { const parsedPhoneNumber = this.parsePhoneNumberFromString(phoneNumber); if (!parsedPhoneNumber?.isValid() || !parsedPhoneNumber?.isPossible()) { return { @@ -213,7 +214,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida validate(): ValidationErrors | null { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); - return phoneNumber.valid || phoneNumber.untouched || this.countryCallingCode === phoneNumber.value ? null : { + return phoneNumber.valid ? null : { phoneFormGroup: false }; } From 3881c809fec08ccc87525a87a517ab309a812e6b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 15 Jul 2022 12:39:22 +0300 Subject: [PATCH 04/21] Clean up cassandra partitions cache on remove --- .../CassandraBaseTimeseriesDao.java | 7 ++++++ .../CassandraTsPartitionsCache.java | 4 +++ .../timeseries/BaseTimeseriesServiceTest.java | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index bb3930b99c..f1d64c0019 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -254,6 +254,13 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD } QueryCursor cursor = new QueryCursor(entityId.getEntityType().name(), entityId.getId(), query, partitionsToDelete); deletePartitionAsync(tenantId, cursor, resultFuture); + + for (Long partition : partitionsToDelete) { + CassandraPartitionCacheKey key = new CassandraPartitionCacheKey(entityId, query.getKey(), partition); + if (cassandraTsPartitionsCache.has(key)) { + cassandraTsPartitionsCache.invalidate(key); + } + } } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraTsPartitionsCache.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraTsPartitionsCache.java index 90943b427a..2ec9e0a596 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraTsPartitionsCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraTsPartitionsCache.java @@ -39,4 +39,8 @@ public class CassandraTsPartitionsCache { public void put(CassandraPartitionCacheKey key) { partitionsCache.put(key, CompletableFuture.completedFuture(true)); } + + public void invalidate(CassandraPartitionCacheKey key) { + partitionsCache.synchronous().invalidate(key); + } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java index b38afe77f6..5339863044 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java @@ -606,6 +606,31 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { assertEquals(java.util.Optional.of(2L), list.get(2).getLongValue()); } + @Test + public void testSaveTs_RemoveTs_AndSaveTsAgain() throws Exception { + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + + save(deviceId, 2000000L, 95); + save(deviceId, 4000000L, 100); + save(deviceId, 6000000L, 105); + List list = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery(LONG_KEY, 0L, + 8000000L, 200000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(3, list.size()); + + tsService.remove(tenantId, deviceId, Collections.singletonList( + new BaseDeleteTsKvQuery(LONG_KEY, 0L, 8000000L, false))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + list = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery(LONG_KEY, 0L, + 8000000L, 200000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(0, list.size()); + + save(deviceId, 2000000L, 99); + save(deviceId, 4000000L, 104); + save(deviceId, 6000000L, 109); + list = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery(LONG_KEY, 0L, + 8000000L, 200000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(3, list.size()); + } + private TsKvEntry save(DeviceId deviceId, long ts, long value) throws Exception { TsKvEntry entry = new BasicTsKvEntry(ts, new LongDataEntry(LONG_KEY, value)); tsService.save(tenantId, deviceId, entry).get(MAX_TIMEOUT, TimeUnit.SECONDS); From 4c78121cc57f7044f22e270f8a931cc92ee879ce Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 15 Jul 2022 13:17:18 +0300 Subject: [PATCH 05/21] Core review updates --- .../server/dao/timeseries/CassandraBaseTimeseriesDao.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index f1d64c0019..d688d145f4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -257,9 +257,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD for (Long partition : partitionsToDelete) { CassandraPartitionCacheKey key = new CassandraPartitionCacheKey(entityId, query.getKey(), partition); - if (cassandraTsPartitionsCache.has(key)) { - cassandraTsPartitionsCache.invalidate(key); - } + cassandraTsPartitionsCache.invalidate(key); } } From 2653732cf85921931aa02474e7f882b6c3ad227a Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 15 Jul 2022 15:05:27 +0200 Subject: [PATCH 06/21] hide externalIds and minor swagger improvements --- .../server/controller/AlarmController.java | 4 ++- .../server/controller/CustomerController.java | 4 ++- .../controller/DashboardController.java | 1 + .../server/controller/DeviceController.java | 6 ++-- .../controller/DeviceProfileController.java | 1 + .../server/controller/EdgeController.java | 5 ++-- .../controller/EntityViewController.java | 4 ++- .../server/controller/QueueController.java | 1 + .../controller/RuleChainController.java | 4 ++- .../controller/TbResourceController.java | 4 ++- .../server/controller/TenantController.java | 1 + .../controller/TenantProfileController.java | 1 + .../server/controller/UserController.java | 4 ++- .../controller/WidgetTypeController.java | 5 ++-- .../controller/WidgetsBundleController.java | 5 ++-- ...ThingsboardCredentialsExpiredResponse.java | 2 +- .../exception/ThingsboardErrorResponse.java | 8 +++--- .../service/telemetry/AttributeData.java | 6 ++-- .../server/service/telemetry/TsData.java | 4 +-- .../server/common/data/AdminSettings.java | 4 +-- .../server/common/data/Customer.java | 4 +-- .../server/common/data/Device.java | 6 ++-- .../server/common/data/DeviceInfo.java | 6 ++-- .../server/common/data/EntityView.java | 6 ++-- .../server/common/data/EntityViewInfo.java | 4 +-- .../thingsboard/server/common/data/Event.java | 6 ++-- .../server/common/data/ExportableEntity.java | 4 +++ .../server/common/data/OtaPackage.java | 2 +- .../server/common/data/OtaPackageInfo.java | 28 +++++++++---------- .../data/SaveOtaPackageInfoRequest.java | 2 +- .../server/common/data/TbResource.java | 4 +-- .../server/common/data/TbResourceInfo.java | 10 +++---- .../server/common/data/Tenant.java | 4 +-- .../server/common/data/asset/Asset.java | 5 ++-- .../server/common/data/page/PageData.java | 8 +++--- .../data/plugin/ComponentDescriptor.java | 14 +++++----- .../data/relation/EntityRelationInfo.java | 4 +-- .../server/common/data/rpc/Rpc.java | 16 +++++------ .../server/common/data/rule/RuleChain.java | 4 +-- .../common/data/rule/RuleChainData.java | 4 +-- .../server/common/data/rule/RuleNode.java | 4 +-- .../data/security/DeviceCredentials.java | 2 +- .../common/data/widget/BaseWidgetType.java | 10 +++---- .../server/common/data/widget/WidgetType.java | 2 +- .../common/data/widget/WidgetTypeDetails.java | 4 +-- .../common/data/widget/WidgetTypeInfo.java | 6 ++-- .../common/data/widget/WidgetsBundle.java | 12 ++++---- 47 files changed, 140 insertions(+), 115 deletions(-) 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..d2e11086c7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -126,7 +126,9 @@ public class AlarmController extends BaseController { "\n\nPlatform also deduplicate the alarms based on the entity id of originator and alarm 'type'. " + "For example, if the user or system component create the alarm with the type 'HighTemperature' for device 'Device A' the new active alarm is created. " + "If the user tries to create 'HighTemperature' alarm for the same device again, the previous alarm will be updated (the 'end_ts' will be set to current timestamp). " + - "If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH + "If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. " + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Alarm entity. " + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH , produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm", method = RequestMethod.POST) diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 2510974991..591eaa1318 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -138,7 +138,9 @@ public class CustomerController extends BaseController { notes = "Creates or Updates the Customer. When creating customer, platform generates Customer Id as " + UUID_WIKI_LINK + "The newly created Customer Id will be present in the response. " + "Specify existing Customer Id to update the Customer. " + - "Referencing non-existing Customer Id will cause 'Not Found' error." + TENANT_AUTHORITY_PARAGRAPH) + "Referencing non-existing Customer Id will cause 'Not Found' error." + + "Remove 'id', 'tenantId' from the request body example (below) to create new Customer entity. " + + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer", method = RequestMethod.POST) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index c6ff15c3ac..9ceeb0d14c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -172,6 +172,7 @@ public class DashboardController extends BaseController { "The newly created Dashboard id will be present in the response. " + "Specify existing Dashboard id to update the dashboard. " + "Referencing non-existing dashboard Id will cause 'Not Found' error. " + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Dashboard entity. " + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 895e711073..ae1558381f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -158,8 +158,9 @@ public class DeviceController extends BaseController { "The newly created device id will be present in the response. " + "Specify existing Device id to update the device. " + "Referencing non-existing device Id will cause 'Not Found' error." + - "\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes." - + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + "\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes." + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. " + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device", method = RequestMethod.POST) @ResponseBody @@ -181,6 +182,7 @@ public class DeviceController extends BaseController { "Requires to provide the Device Credentials object as well. Useful to create device and credentials in one request. " + "You may find the example of LwM2M device and RPK credentials below: \n\n" + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device-with-credentials", method = RequestMethod.POST) 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..e45a195a2d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -191,6 +191,7 @@ public class DeviceProfileController extends BaseController { "Specify existing device profile id to update the device profile. " + "Referencing non-existing device profile Id will cause 'Not Found' error. " + NEW_LINE + "Device profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant." + DEVICE_PROFILE_DATA + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device Profile entity. " + TENANT_AUTHORITY_PARAGRAPH, produces = "application/json", consumes = "application/json") diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 5b2c6a6a9d..59c9eb39c1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -141,8 +141,9 @@ public class EdgeController extends BaseController { "The newly created edge id will be present in the response. " + "Specify existing Edge id to update the edge. " + "Referencing non-existing Edge Id will cause 'Not Found' error." + - "\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes." - + TENANT_AUTHORITY_PARAGRAPH, + "\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes." + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Edge entity. " + + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge", method = RequestMethod.POST) diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index 7d5de91890..0f299fefae 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -132,7 +132,9 @@ public class EntityViewController extends BaseController { } @ApiOperation(value = "Save or update entity view (saveEntityView)", - notes = ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION, + notes = ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Entity View entity." + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView", method = RequestMethod.POST) diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueController.java b/application/src/main/java/org/thingsboard/server/controller/QueueController.java index 0f29ced288..f87be5d5f2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java +++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java @@ -86,6 +86,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST) @ResponseBody + public Queue saveQueue(@RequestBody Queue queue, @RequestParam String serviceType) throws ThingsboardException { checkParameter("serviceType", serviceType); 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 38e7f5bb7d..faa1711fd9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -227,7 +227,9 @@ public class RuleChainController extends BaseController { "The newly created Rule Chain Id will be present in the response. " + "Specify existing Rule Chain id to update the rule chain. " + "Referencing non-existing rule chain Id will cause 'Not Found' error." + - "\n\n" + RULE_CHAIN_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH) + "\n\n" + RULE_CHAIN_DESCRIPTION + + "Remove 'id', 'tenantId' from the request body example (below) to create new Rule Chain entity." + + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain", method = RequestMethod.POST) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 4342a647c5..ec0b530117 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -139,7 +139,9 @@ public class TbResourceController extends BaseController { "The newly created Resource id will be present in the response. " + "Specify existing Resource id to update the Resource. " + "Referencing non-existing Resource Id will cause 'Not Found' error. " + - "\n\nResource combination of the title with the key is unique in the scope of tenant. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, + "\n\nResource combination of the title with the key is unique in the scope of tenant. " + + "Remove 'id', 'tenantId' from the request body example (below) to create new Resource entity." + + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, produces = "application/json", consumes = "application/json") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index ef3c141131..b44c5327cd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -115,6 +115,7 @@ public class TenantController extends BaseController { "The newly created Tenant Id will be present in the response. " + "Specify existing Tenant Id id to update the Tenant. " + "Referencing non-existing Tenant Id will cause 'Not Found' error." + + "Remove 'id', 'tenantId' from the request body example (below) to create new Tenant entity." + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant", method = RequestMethod.POST) diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java index 9bbfcce351..e5a33da948 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java @@ -164,6 +164,7 @@ public class TenantProfileController extends BaseController { " \"default\": true\n" + "}" + MARKDOWN_CODE_BLOCK_END + + "Remove 'id', from the request body example (below) to create new Tenant Profile entity." + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenantProfile", method = RequestMethod.POST) diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index e9375665bb..e96a73b65c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -176,7 +176,9 @@ public class UserController extends BaseController { "The newly created User Id will be present in the response. " + "Specify existing User Id to update the device. " + "Referencing non-existing User Id will cause 'Not Found' error." + - "\n\nDevice email is unique for entire platform setup.") + "\n\nDevice email is unique for entire platform setup." + + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new User entity." + + "\n\nAvailable for users with 'SYS_ADMIN', 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user", method = RequestMethod.POST) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index 71ea889c03..725d8ca2b4 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -85,8 +85,9 @@ public class WidgetTypeController extends AutoCommitController { "Specify existing Widget Type id to update the Widget Type. " + "Referencing non-existing Widget Type Id will cause 'Not Found' error." + "\n\nWidget Type alias is unique in the scope of Widget Bundle. " + - "Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create request is sent by user with 'SYS_ADMIN' authority." - + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + "Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create request is sent by user with 'SYS_ADMIN' authority." + + "Remove 'id', 'tenantId' rom the request body example (below) to create new Widget Type entity." + + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/widgetType", method = RequestMethod.POST) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 2d51c3dee8..23ec498d0e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -89,8 +89,9 @@ public class WidgetsBundleController extends BaseController { "Specify existing Widget Bundle id to update the Widget Bundle. " + "Referencing non-existing Widget Bundle Id will cause 'Not Found' error." + "\n\nWidget Bundle alias is unique in the scope of tenant. " + - "Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create bundle request is sent by user with 'SYS_ADMIN' authority." - + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + "Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create bundle request is sent by user with 'SYS_ADMIN' authority." + + "Remove 'id', 'tenantId' from the request body example (below) to create new Widgets Bundle entity." + + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/widgetsBundle", method = RequestMethod.POST) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java index b02f85f84a..208fdead93 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java @@ -34,7 +34,7 @@ public class ThingsboardCredentialsExpiredResponse extends ThingsboardErrorRespo return new ThingsboardCredentialsExpiredResponse(message, resetToken); } - @ApiModelProperty(position = 5, value = "Password reset token", readOnly = true) + @ApiModelProperty(position = 5, value = "Password reset token", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public String getResetToken() { return resetToken; } diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java index 09fce98985..7cf2ca87f1 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java @@ -46,12 +46,12 @@ public class ThingsboardErrorResponse { return new ThingsboardErrorResponse(message, errorCode, status); } - @ApiModelProperty(position = 1, value = "HTTP Response Status Code", example = "401", readOnly = true) + @ApiModelProperty(position = 1, value = "HTTP Response Status Code", example = "401", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Integer getStatus() { return status.value(); } - @ApiModelProperty(position = 2, value = "Error message", example = "Authentication failed", readOnly = true) + @ApiModelProperty(position = 2, value = "Error message", example = "Authentication failed", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public String getMessage() { return message; } @@ -69,12 +69,12 @@ public class ThingsboardErrorResponse { "\n\n* `34` - Too many updates (Too many updates over Websocket session)" + "\n\n* `40` - Subscription violation (HTTP: 403 - Forbidden)", example = "10", dataType = "integer", - readOnly = true) + accessMode = ApiModelProperty.AccessMode.READ_ONLY) public ThingsboardErrorCode getErrorCode() { return errorCode; } - @ApiModelProperty(position = 4, value = "Timestamp", readOnly = true) + @ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Date getTimestamp() { return timestamp; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java index 9b67628aa3..5eb258c2a6 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java @@ -32,17 +32,17 @@ public class AttributeData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 1, value = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public long getLastUpdateTs() { return lastUpdateTs; } - @ApiModelProperty(position = 2, value = "String representing attribute key", example = "active", readOnly = true) + @ApiModelProperty(position = 2, value = "String representing attribute key", example = "active", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public String getKey() { return key; } - @ApiModelProperty(position = 3, value = "Object representing value of attribute key", example = "false", readOnly = true) + @ApiModelProperty(position = 3, value = "Object representing value of attribute key", example = "false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java index e48561a965..56d1785d45 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java @@ -30,12 +30,12 @@ public class TsData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 1, value = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public long getTs() { return ts; } - @ApiModelProperty(position = 2, value = "Object representing value of timeseries key", example = "20", readOnly = true) + @ApiModelProperty(position = 2, value = "Object representing value of timeseries key", example = "20", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java index d88fabc052..ab92f267f6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java @@ -58,13 +58,13 @@ public class AdminSettings extends BaseData implements HasTenan return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java index 9ce638e667..bdd06606a6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java @@ -83,7 +83,7 @@ public class Customer extends ContactBased implements HasTenantId, E return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -159,7 +159,7 @@ public class Customer extends ContactBased implements HasTenantId, E @Override @JsonProperty(access = Access.READ_ONLY) - @ApiModelProperty(position = 4, value = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", readOnly = true) + @ApiModelProperty(position = 4, value = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public String getName() { return title; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java index 678c68c115..4a6589d72c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java @@ -112,13 +112,13 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the device creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the device creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -127,7 +127,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java index a2e569d602..ccb9c29b6b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java @@ -24,11 +24,11 @@ import org.thingsboard.server.common.data.id.DeviceId; @Data public class DeviceInfo extends Device { - @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", readOnly = true) + @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 14, value = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", readOnly = true) + @ApiModelProperty(position = 14, value = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private boolean customerIsPublic; - @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", readOnly = true) + @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String deviceProfileName; public DeviceInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java index a7e21b8a25..51129801e3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java @@ -87,7 +87,7 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo return getName() /*What the ...*/; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return customerId; @@ -98,7 +98,7 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo return name; } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return tenantId; @@ -113,7 +113,7 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java index 4b8ac3f066..b9acde7af0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.id.EntityViewId; @Data public class EntityViewInfo extends EntityView { - @ApiModelProperty(position = 12, value = "Title of the Customer that owns the entity view.", readOnly = true) + @ApiModelProperty(position = 12, value = "Title of the Customer that owns the entity view.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 13, value = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", readOnly = true) + @ApiModelProperty(position = 13, value = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private boolean customerIsPublic; public EntityViewInfo() { 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/Event.java index 6ff574917d..29ab33d075 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/Event.java @@ -30,13 +30,13 @@ import org.thingsboard.server.common.data.id.TenantId; @ApiModel public class Event extends BaseData { - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @ApiModelProperty(position = 2, value = "Event type", example = "STATS") private String type; @ApiModelProperty(position = 3, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") private String uid; - @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private EntityId entityId; @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode") private transient JsonNode body; @@ -53,7 +53,7 @@ public class Event extends BaseData { super(event); } - @ApiModelProperty(position = 6, value = "Timestamp of the event creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 6, value = "Timestamp of the event creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java index 64834c8b15..57541d02e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -23,10 +24,13 @@ public interface ExportableEntity extends HasId, HasName void setId(I id); + @ApiModelProperty(position = 100, value = "JSON object with External Id from the VCS", accessMode = ApiModelProperty.AccessMode.READ_ONLY, hidden = true) I getExternalId(); + void setExternalId(I externalId); long getCreatedTime(); + void setCreatedTime(long createdTime); void setTenantId(TenantId tenantId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java index 3a17aefab8..b708979006 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java @@ -30,7 +30,7 @@ public class OtaPackage extends OtaPackageInfo { private static final long serialVersionUID = 3091601761339422546L; - @ApiModelProperty(position = 16, value = "OTA Package data.", readOnly = true) + @ApiModelProperty(position = 16, value = "OTA Package data.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private transient ByteBuffer data; public OtaPackage() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java index c860d06a4c..b31d0a6bc0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java @@ -40,44 +40,44 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo implements Has private static final long serialVersionUID = 7282664529021651736L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "title") @ApiModelProperty(position = 4, value = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0") private String title; - @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", readOnly = true) + @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private ResourceType resourceType; @NoXss @Length(fieldName = "resourceKey") - @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", readOnly = true) + @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String resourceKey; - @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", readOnly = true) + @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String searchText; public TbResourceInfo() { @@ -75,7 +75,7 @@ public class TbResourceInfo extends SearchTextBased implements Has return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java index 5a55669646..8d5a9fe3fc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java @@ -74,7 +74,7 @@ public class Tenant extends ContactBased implements HasTenantId { } @Override - @ApiModelProperty(position = 4, value = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", readOnly = true) + @ApiModelProperty(position = 4, value = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { return title; @@ -110,7 +110,7 @@ public class Tenant extends ContactBased implements HasTenantId { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java index bef1bd99b8..f4ad335a43 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java @@ -52,7 +52,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo implements @Length(fieldName = "label") private String label; - @ApiModelProperty(position = 100, value = "JSON object with External Id from the VCS", accessMode = ApiModelProperty.AccessMode.READ_ONLY, hidden = true) @Getter @Setter private AssetId externalId; @@ -93,7 +92,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo implements return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -108,7 +107,7 @@ public class Asset extends SearchTextBasedWithAdditionalInfo implements this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java index 02f6683989..511e9fe170 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java @@ -48,22 +48,22 @@ public class PageData { this.hasNext = hasNext; } - @ApiModelProperty(position = 1, value = "Array of the entities", readOnly = true) + @ApiModelProperty(position = 1, value = "Array of the entities", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public List getData() { return data; } - @ApiModelProperty(position = 2, value = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", readOnly = true) + @ApiModelProperty(position = 2, value = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public int getTotalPages() { return totalPages; } - @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", readOnly = true) + @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public long getTotalElements() { return totalElements; } - @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", readOnly = true) + @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @JsonProperty("hasNext") public boolean hasNext() { return hasNext; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index cdc5d55154..81708ae101 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -32,19 +32,19 @@ public class ComponentDescriptor extends SearchTextBased private static final long serialVersionUID = 1L; - @ApiModelProperty(position = 3, value = "Type of the Rule Node", readOnly = true) + @ApiModelProperty(position = 3, value = "Type of the Rule Node", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private ComponentType type; - @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", readOnly = true, allowableValues = "TENANT", example = "TENANT") + @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") @Getter @Setter private ComponentScope scope; @Length(fieldName = "name") - @ApiModelProperty(position = 5, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", readOnly = true, example = "Custom Rule Node") + @ApiModelProperty(position = 5, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "Custom Rule Node") @Getter @Setter private String name; - @ApiModelProperty(position = 6, value = "Full name of the Java class that implements the Rule Engine Node interface.", readOnly = true, example = "com.mycompany.CustomRuleNode") + @ApiModelProperty(position = 6, value = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") @Getter @Setter private String clazz; - @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", readOnly = true) + @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private transient JsonNode configurationDescriptor; @Length(fieldName = "actions") - @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", readOnly = true) + @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; public ComponentDescriptor() { @@ -74,7 +74,7 @@ public class ComponentDescriptor extends SearchTextBased return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java index 42f57b57a2..95714351e1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java @@ -32,7 +32,7 @@ public class EntityRelationInfo extends EntityRelation { super(entityRelation); } - @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", readOnly = true, example = "A4B72CCDFF33") + @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF33") public String getFromName() { return fromName; } @@ -41,7 +41,7 @@ public class EntityRelationInfo extends EntityRelation { this.fromName = fromName; } - @ApiModelProperty(position = 7, value = "Name of the entity for [to] direction.", readOnly = true, example = "A4B72CCDFF35") + @ApiModelProperty(position = 7, value = "Name of the entity for [to] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF35") public String getToName() { return toName; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java index ee2ea6d830..7703c1aec2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java @@ -31,19 +31,19 @@ import org.thingsboard.server.common.data.id.TenantId; @EqualsAndHashCode(callSuper = true) public class Rpc extends BaseData implements HasTenantId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Device Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Device Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private DeviceId deviceId; - @ApiModelProperty(position = 5, value = "Expiration time of the request.", readOnly = true) + @ApiModelProperty(position = 5, value = "Expiration time of the request.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private long expirationTime; - @ApiModelProperty(position = 6, value = "The request body that will be used to send message to device.", readOnly = true) + @ApiModelProperty(position = 6, value = "The request body that will be used to send message to device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private JsonNode request; - @ApiModelProperty(position = 7, value = "The response from the device.", readOnly = true) + @ApiModelProperty(position = 7, value = "The response from the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private JsonNode response; - @ApiModelProperty(position = 8, value = "The current status of the RPC call.", readOnly = true) + @ApiModelProperty(position = 8, value = "The current status of the RPC call.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private RpcStatus status; - @ApiModelProperty(position = 9, value = "Additional info used in the rule engine to process the updates to the RPC state.", readOnly = true) + @ApiModelProperty(position = 9, value = "Additional info used in the rule engine to process the updates to the RPC state.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private JsonNode additionalInfo; public Rpc() { @@ -71,7 +71,7 @@ public class Rpc extends BaseData implements HasTenantId { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java index eca9e331cd..a8ba432ceb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java @@ -40,7 +40,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo im private static final long serialVersionUID = -5656679015121935465L; - @ApiModelProperty(position = 3, required = true, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, required = true, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") @@ -100,7 +100,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo im return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java index 93fd690d6d..885226caba 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java @@ -25,8 +25,8 @@ import java.util.List; @Data public class RuleChainData { - @ApiModelProperty(position = 1, required = true, value = "List of the Rule Chain objects.", readOnly = true) + @ApiModelProperty(position = 1, required = true, value = "List of the Rule Chain objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) List ruleChains; - @ApiModelProperty(position = 2, required = true, value = "List of the Rule Chain metadata objects.", readOnly = true) + @ApiModelProperty(position = 2, required = true, value = "List of the Rule Chain metadata objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) List metadata; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index d9dce57f46..c9bf8b462c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -37,7 +37,7 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo impl private static final long serialVersionUID = -5656679015121235465L; - @ApiModelProperty(position = 3, value = "JSON object with the Rule Chain Id. ", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with the Rule Chain Id. ", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private RuleChainId ruleChainId; @Length(fieldName = "type") @ApiModelProperty(position = 4, value = "Full Java Class Name of the rule node implementation. ", example = "com.mycompany.iot.rule.engine.ProcessingNode") @@ -100,7 +100,7 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo impl return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java index ed797eec70..e5af27776c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java @@ -48,7 +48,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsValue = deviceCredentials.getCredentialsValue(); } - @ApiModelProperty(position = 1, required = true, readOnly = true, value = "The Id is automatically generated during device creation. " + + @ApiModelProperty(position = 1, required = true, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "The Id is automatically generated during device creation. " + "Use 'getDeviceCredentialsByDeviceId' to obtain the id based on device id. " + "Use 'updateDeviceCredentials' to update device credentials. ", example = "784f394c-42b6-435a-983c-b7beff2784f9") @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java index 0e88a6535d..be5014a4cd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java @@ -29,19 +29,19 @@ public class BaseWidgetType extends BaseData implements HasTenantI private static final long serialVersionUID = 8388684344603660756L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "bundleAlias") - @ApiModelProperty(position = 4, value = "Reference to widget bundle", readOnly = true) + @ApiModelProperty(position = 4, value = "Reference to widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String bundleAlias; @NoXss @Length(fieldName = "alias") - @ApiModelProperty(position = 5, value = "Unique alias that is used in dashboards as a reference widget type", readOnly = true) + @ApiModelProperty(position = 5, value = "Unique alias that is used in dashboards as a reference widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 6, value = "Widget name used in search and UI", readOnly = true) + @ApiModelProperty(position = 6, value = "Widget name used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String name; public BaseWidgetType() { @@ -69,7 +69,7 @@ public class BaseWidgetType extends BaseData implements HasTenantI return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java index 96c5512dad..6b836c53e8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.id.WidgetTypeId; @Data public class WidgetType extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Complex JSON object that describes the widget type", readOnly = true) + @ApiModelProperty(position = 7, value = "Complex JSON object that describes the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private transient JsonNode descriptor; public WidgetType() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java index 2a46091671..1447400721 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java @@ -27,11 +27,11 @@ import org.thingsboard.server.common.data.validation.NoXss; public class WidgetTypeDetails extends WidgetType { @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 8, value = "Base64 encoded thumbnail", readOnly = true) + @ApiModelProperty(position = 8, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") - @ApiModelProperty(position = 9, value = "Description of the widget", readOnly = true) + @ApiModelProperty(position = 9, value = "Description of the widget", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String description; public WidgetTypeDetails() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index e6d7f591d2..bb7b19fce6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -23,13 +23,13 @@ import org.thingsboard.server.common.data.validation.NoXss; @Data public class WidgetTypeInfo extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Base64 encoded widget thumbnail", readOnly = true) + @ApiModelProperty(position = 7, value = "Base64 encoded widget thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String image; @NoXss - @ApiModelProperty(position = 7, value = "Description of the widget type", readOnly = true) + @ApiModelProperty(position = 7, value = "Description of the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String description; @NoXss - @ApiModelProperty(position = 8, value = "Type of the widget (timeseries, latest, control, alarm or static)", readOnly = true) + @ApiModelProperty(position = 8, value = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String widgetType; public WidgetTypeInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java index 4f3de71512..389771e46f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java @@ -37,34 +37,34 @@ public class WidgetsBundle extends SearchTextBased implements H @Getter @Setter - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "alias") @Getter @Setter - @ApiModelProperty(position = 4, value = "Unique alias that is used in widget types as a reference widget bundle", readOnly = true) + @ApiModelProperty(position = 4, value = "Unique alias that is used in widget types as a reference widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "title") @Getter @Setter - @ApiModelProperty(position = 5, value = "Title used in search and UI", readOnly = true) + @ApiModelProperty(position = 5, value = "Title used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String title; @Length(fieldName = "image", max = 1000000) @Getter @Setter - @ApiModelProperty(position = 6, value = "Base64 encoded thumbnail", readOnly = true) + @ApiModelProperty(position = 6, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") @Getter @Setter - @ApiModelProperty(position = 7, value = "Description", readOnly = true) + @ApiModelProperty(position = 7, value = "Description", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String description; @Getter @@ -98,7 +98,7 @@ public class WidgetsBundle extends SearchTextBased implements H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); From 5fafa3fe72f8e7faca1ff999feec02430a5765be Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 15 Jul 2022 15:45:44 +0200 Subject: [PATCH 07/21] added queue swagger doc --- .../controller/ControllerConstants.java | 4 ++ .../server/controller/QueueController.java | 54 +++++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index a425b0968a..bdf74c9055 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -112,6 +112,10 @@ public class ControllerConstants { protected static final String DEVICE_PROFILE_INFO_DESCRIPTION = "Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. "; protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)"; protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR"; + protected static final String QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the queue name."; + protected static final String QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, topic"; + protected static final String QUEUE_ID_PARAM_DESCRIPTION = "A string value representing the queue id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; + protected static final String QUEUE_NAME_PARAM_DESCRIPTION = "A string value representing the queue id. For example, 'Main'"; protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. "; protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. "; protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128"; diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueController.java b/application/src/main/java/org/thingsboard/server/controller/QueueController.java index f87be5d5f2..3b37e6727f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java +++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.controller; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -37,6 +39,22 @@ import org.thingsboard.server.service.security.permission.Resource; import java.util.UUID; +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_ID_PARAM_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_NAME_PARAM_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES; +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; +import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; + @RestController @TbCoreComponent @RequestMapping("/api") @@ -45,14 +63,23 @@ public class QueueController extends BaseController { private final TbQueueService tbQueueService; + @ApiOperation(value = "Get Queues (getTenantQueuesByServiceType)", + notes = "Returns a page of queues registered in the platform. " + + PAGE_DATA_PARAMETERS + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET) @ResponseBody - public PageData getTenantQueuesByServiceType(@RequestParam String serviceType, + public PageData getTenantQueuesByServiceType(@ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) + @RequestParam String serviceType, + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, + @ApiParam(value = QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES) @RequestParam(required = false) String sortProperty, + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("serviceType", serviceType); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -65,29 +92,44 @@ public class QueueController extends BaseController { } } + @ApiOperation(value = "Get Queue (getQueueById)", + notes = "Fetch the Queue object based on the provided Queue Id. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueById(@PathVariable("queueId") String queueIdStr) throws ThingsboardException { + public Queue getQueueById(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(UUID.fromString(queueIdStr)); checkQueueId(queueId, Operation.READ); return checkNotNull(queueService.findQueueById(getTenantId(), queueId)); } + @ApiOperation(value = "Get Queue (getQueueByName)", + notes = "Fetch the Queue object based on the provided Queue name. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/name/{queueName}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueByName(@PathVariable("queueName") String queueName) throws ThingsboardException { + public Queue getQueueByName(@ApiParam(value = QUEUE_NAME_PARAM_DESCRIPTION) + @PathVariable("queueName") String queueName) throws ThingsboardException { checkParameter("queueName", queueName); return checkNotNull(queueService.findQueueByTenantIdAndName(getTenantId(), queueName)); } + @ApiOperation(value = "Create Or Update Queue (saveQueue)", + notes = "Create or update the Queue. When creating queue, platform generates Queue Id as " + UUID_WIKI_LINK + + "Specify existing Queue id to update the queue. " + + "Referencing non-existing Queue Id will cause 'Not Found' error." + + "\n\nQueue name is unique in the scope of sysadmin. " + + "Remove 'id', 'tenantId' from the request body example (below) to create new Queue entity. " + + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST) @ResponseBody - public Queue saveQueue(@RequestBody Queue queue, + public Queue saveQueue(@ApiParam(value = "A JSON value representing the queue.") + @RequestBody Queue queue, + @ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) @RequestParam String serviceType) throws ThingsboardException { checkParameter("serviceType", serviceType); queue.setTenantId(getCurrentUser().getTenantId()); @@ -106,10 +148,12 @@ public class QueueController extends BaseController { } } + @ApiOperation(value = "Delete Queue (deleteQueue)", notes = "Deletes the Queue. " + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteQueue(@PathVariable("queueId") String queueIdStr) throws ThingsboardException { + public void deleteQueue(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(toUUID(queueIdStr)); checkQueueId(queueId, Operation.DELETE); From e3383597ba8160e68933112cf19176be67308785 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 15 Jul 2022 16:24:57 +0200 Subject: [PATCH 08/21] replace deprecated param readOnly --- .../server/common/data/DashboardInfo.java | 14 +++++------ .../server/common/data/DeviceProfile.java | 4 ++-- .../server/common/data/TenantProfile.java | 2 +- .../thingsboard/server/common/data/User.java | 8 +++---- .../server/common/data/alarm/Alarm.java | 6 ++--- .../server/common/data/asset/AssetInfo.java | 4 ++-- .../server/common/data/audit/AuditLog.java | 22 ++++++++--------- .../bootstrap/LwM2MServerSecurityConfig.java | 24 +++++++++---------- .../LwM2MServerSecurityConfigDefault.java | 4 ++-- .../server/common/data/edge/Edge.java | 8 +++---- .../common/data/relation/EntityRelation.java | 4 ++-- .../common/data/rule/RuleChainMetaData.java | 2 +- 12 files changed, 51 insertions(+), 51 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java index 0a6d2260d2..1895b41639 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java @@ -71,13 +71,13 @@ public class DashboardInfo extends SearchTextBased implements HasNa return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -95,7 +95,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa this.title = title; } - @ApiModelProperty(position = 8, value = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", readOnly = true) + @ApiModelProperty(position = 8, value = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public String getImage() { return image; } @@ -104,7 +104,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa this.image = image; } - @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", readOnly = true) + @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Set getAssignedCustomers() { return assignedCustomers; } @@ -113,7 +113,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa this.assignedCustomers = assignedCustomers; } - @ApiModelProperty(position = 6, value = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", readOnly = true) + @ApiModelProperty(position = 6, value = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public boolean isMobileHide() { return mobileHide; } @@ -122,7 +122,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa this.mobileHide = mobileHide; } - @ApiModelProperty(position = 7, value = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", readOnly = true) + @ApiModelProperty(position = 7, value = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public Integer getMobileOrder() { return mobileOrder; } @@ -180,7 +180,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa } } - @ApiModelProperty(position = 4, value = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", readOnly = true) + @ApiModelProperty(position = 4, value = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 316780550c..da8edc695e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -49,7 +49,7 @@ public class DeviceProfile extends SearchTextBased implements H private static final long serialVersionUID = 6998485460273302018L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") @@ -129,7 +129,7 @@ public class DeviceProfile extends SearchTextBased implements H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java index 09a27fe0ec..89bd02344a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java @@ -87,7 +87,7 @@ public class TenantProfile extends SearchTextBased implements H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/User.java b/common/data/src/main/java/org/thingsboard/server/common/data/User.java index c207135f6d..60d8d7eca9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/User.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/User.java @@ -74,13 +74,13 @@ public class User extends SearchTextBasedWithAdditionalInfo implements H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the user creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the user creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with the Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -89,7 +89,7 @@ public class User extends SearchTextBasedWithAdditionalInfo implements H this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -107,7 +107,7 @@ public class User extends SearchTextBasedWithAdditionalInfo implements H this.email = email; } - @ApiModelProperty(position = 6, readOnly = true, value = "Duplicates the email of the user, readonly", example = "user@example.com") + @ApiModelProperty(position = 6, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "Duplicates the email of the user, readonly", example = "user@example.com") @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java index 7587d687dd..f13c84bc82 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java @@ -43,10 +43,10 @@ import java.util.List; @AllArgsConstructor public class Alarm extends BaseData implements HasName, HasTenantId, HasCustomerId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private CustomerId customerId; @ApiModelProperty(position = 6, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") @@ -124,7 +124,7 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha } - @ApiModelProperty(position = 2, value = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java index 4b962aa811..a6a532cbe6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.AssetId; @Data public class AssetInfo extends Asset { - @ApiModelProperty(position = 9, value = "Title of the Customer that owns the asset.", readOnly = true) + @ApiModelProperty(position = 9, value = "Title of the Customer that owns the asset.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 10, value = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", readOnly = true) + @ApiModelProperty(position = 10, value = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private boolean customerIsPublic; public AssetInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java index 01f2336197..e87a1a6380 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java @@ -28,25 +28,25 @@ import org.thingsboard.server.common.data.id.*; @Data public class AuditLog extends BaseData { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private CustomerId customerId; - @ApiModelProperty(position = 5, value = "JSON object with Entity id", readOnly = true) + @ApiModelProperty(position = 5, value = "JSON object with Entity id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private EntityId entityId; - @ApiModelProperty(position = 6, value = "Name of the logged entity", example = "Thermometer", readOnly = true) + @ApiModelProperty(position = 6, value = "Name of the logged entity", example = "Thermometer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String entityName; - @ApiModelProperty(position = 7, value = "JSON object with User id.", readOnly = true) + @ApiModelProperty(position = 7, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 8, value = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", readOnly = true) + @ApiModelProperty(position = 8, value = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String userName; - @ApiModelProperty(position = 9, value = "String represented Action type", example = "ADDED", readOnly = true) + @ApiModelProperty(position = 9, value = "String represented Action type", example = "ADDED", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private ActionType actionType; - @ApiModelProperty(position = 10, value = "JsonNode represented action data", readOnly = true) + @ApiModelProperty(position = 10, value = "JsonNode represented action data", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private JsonNode actionData; - @ApiModelProperty(position = 11, value = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", readOnly = true) + @ApiModelProperty(position = 11, value = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private ActionStatus actionStatus; - @ApiModelProperty(position = 12, value = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", readOnly = true) + @ApiModelProperty(position = 12, value = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String actionFailureDetails; public AuditLog() { @@ -71,7 +71,7 @@ public class AuditLog extends BaseData { this.actionFailureDetails = auditLog.getActionFailureDetails(); } - @ApiModelProperty(position = 2, value = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java index 8232f6670f..2fc2b84586 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java @@ -25,44 +25,44 @@ public class LwM2MServerSecurityConfig { @ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + "This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. " + - "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", readOnly = true) + "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected Integer shortServerId = 123; /** Security -> ObjectId = 0 'LWM2M Security' */ @ApiModelProperty(position = 2, value = "Is Bootstrap Server or Lwm2m Server. " + "The LwM2M Client MAY be configured to use one or more LwM2M Server Account(s). " + "The LwM2M Client MUST have at most one LwM2M Bootstrap-Server Account. " + - "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", readOnly = true) + "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected boolean bootstrapServerIs = false; - @ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", readOnly = true) + @ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected String host; - @ApiModelProperty(position = 4, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", readOnly = true) + @ApiModelProperty(position = 4, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected Integer port; - @ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", readOnly = true) + @ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected Integer clientHoldOffTime = 1; @ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + - "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", readOnly = true) + "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected String serverPublicKey; @ApiModelProperty(position = 9, value = "Server Public Key for 'Security' mode (DTLS): X509. Format: base64 encoded", example = "MMIICODCCAd6gAwIBAgIUI88U1zowOdrxDK/dOV+36gJxI2MwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMCVUs\n" + "xEjAQBgNVBAgTCUt5aXYgY2l0eTENMAsGA1UEBxMES3lpdjEUMBIGA1UEChMLVGhpbmdzYm9hcmQxFzAVBgNVBAsMDkRFVkVMT1BFUl9URVNUMRkwFwYDVQQDDBBpbnRlcm1lZGlhdGVfY2EwMB4XDTIyMDEwOTEzMDMwMFoXDTI3MDEwODEzMDMwMFowFDESMBAGA1UEAxM\n" + "JbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUO3vBo/JTv0eooY7XHiKAIVDoWKFqtrU7C6q8AIKqpLcqhCdW+haFeBOH3PjY6EwaWkY04Bir4oanU0s7tz2uKOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/\n" + "BAIwADAdBgNVHQ4EFgQUEjc3Q4a0TxzP/3x3EV4fHxYUg0YwHwYDVR0jBBgwFoAUuSquGycMU6Q0SYNcbtSkSD3TfH0wLwYDVR0RBCgwJoIVbG9jYWxob3N0LmxvY2FsZG9tYWlugglsb2NhbGhvc3SCAiAtMAoGCCqGSM49BAMCA0gAMEUCIQD7dbZObyUaoDiNbX+9fUNp\n" + - "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", readOnly = true) + "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected String serverCertificate; - @ApiModelProperty(position = 10, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", readOnly = true) + @ApiModelProperty(position = 10, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) Integer bootstrapServerAccountTimeout = 0; /** Config -> ObjectId = 1 'LwM2M Server' */ - @ApiModelProperty(position = 11, value = "Specify the lifetime of the registration in seconds.", example = "300", readOnly = true) + @ApiModelProperty(position = 11, value = "Specify the lifetime of the registration in seconds.", example = "300", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private Integer lifetime = 300; @ApiModelProperty(position = 12, value = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " + - "If this Resource doesn’t exist, the default value is 0.", example = "1", readOnly = true) + "If this Resource doesn’t exist, the default value is 0.", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private Integer defaultMinPeriod = 1; /** ResourceID=6 'Notification Storing When Disabled or Offline' */ @ApiModelProperty(position = 13, value = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " + "If false, the LwM2M Client discards all the “Notify” operations or temporarily disables the Observe function while the LwM2M Server is disabled or the LwM2M Client is offline. " + - "The default value is true.", example = "true", readOnly = true) + "The default value is true.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private boolean notifIfDisabled = true; @ApiModelProperty(position = 14, value = "This Resource defines the transport binding configured for the LwM2M Client. " + - "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", readOnly = true) + "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String binding = "U"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index ce2686f086..948a492e42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -22,8 +22,8 @@ import lombok.Data; @ApiModel @Data public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { - @ApiModelProperty(position = 5, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", readOnly = true) + @ApiModelProperty(position = 5, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected String securityHost; - @ApiModelProperty(position = 6, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", readOnly = true) + @ApiModelProperty(position = 6, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", accessMode = ApiModelProperty.AccessMode.READ_ONLY) protected Integer securityPort; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java index 4a4cd1afc4..58c23d0877 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java @@ -98,25 +98,25 @@ public class Edge extends SearchTextBasedWithAdditionalInfo implements H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", readOnly = true) + @ApiModelProperty(position = 2, value = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", readOnly = true) + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return this.tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", readOnly = true) + @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return this.customerId; } - @ApiModelProperty(position = 5, value = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", readOnly = true) + @ApiModelProperty(position = 5, value = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public RuleChainId getRootRuleChainId() { return this.rootRuleChainId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java index d57b1aa9d7..8c7f2291cc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java @@ -73,7 +73,7 @@ public class EntityRelation implements Serializable { this.additionalInfo = entityRelation.getAdditionalInfo(); } - @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", readOnly = true) + @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public EntityId getFrom() { return from; } @@ -82,7 +82,7 @@ public class EntityRelation implements Serializable { this.from = from; } - @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", readOnly = true) + @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) public EntityId getTo() { return to; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java index 7bd19e2441..fcb88924da 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java @@ -33,7 +33,7 @@ import java.util.Map; @Data public class RuleChainMetaData { - @ApiModelProperty(position = 1, required = true, value = "JSON object with Rule Chain Id.", readOnly = true) + @ApiModelProperty(position = 1, required = true, value = "JSON object with Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private RuleChainId ruleChainId; @ApiModelProperty(position = 2, required = true, value = "Index of the first rule node in the 'nodes' list") From e6fe7e68337842c2a2ed0cb280369dd9373c0a2e Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 15 Jul 2022 18:00:33 +0300 Subject: [PATCH 09/21] Unique constraint for external id --- .../main/data/upgrade/3.3.4/schema_update.sql | 83 +++++++++++++++++-- .../server/dao/asset/BaseAssetService.java | 11 ++- .../dao/customer/CustomerServiceImpl.java | 12 ++- .../dao/dashboard/DashboardServiceImpl.java | 7 +- .../dao/device/DeviceProfileServiceImpl.java | 15 ++-- .../server/dao/device/DeviceServiceImpl.java | 10 +-- .../dao/entity/AbstractEntityService.java | 29 ++++++- .../dao/entityview/EntityViewServiceImpl.java | 12 ++- .../server/dao/ota/BaseOtaPackageService.java | 10 --- .../server/dao/rule/BaseRuleChainService.java | 7 +- .../CassandraBaseTimeseriesDao.java | 3 +- .../dao/widget/WidgetsBundleServiceImpl.java | 8 +- .../main/resources/sql/schema-entities.sql | 22 +++-- 13 files changed, 170 insertions(+), 59 deletions(-) diff --git a/application/src/main/data/upgrade/3.3.4/schema_update.sql b/application/src/main/data/upgrade/3.3.4/schema_update.sql index 9ab6a65b86..c86a4fe1f4 100644 --- a/application/src/main/data/upgrade/3.3.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.3.4/schema_update.sql @@ -33,16 +33,7 @@ ALTER TABLE widgets_bundle ALTER TABLE entity_view ADD COLUMN IF NOT EXISTS external_id UUID; -CREATE INDEX IF NOT EXISTS idx_device_external_id ON device(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_device_profile_external_id ON device_profile(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_asset_external_id ON asset(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_rule_chain_external_id ON rule_chain(tenant_id, external_id); CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, external_id); -CREATE INDEX IF NOT EXISTS idx_dashboard_external_id ON dashboard(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_customer_external_id ON customer(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_widgets_bundle_external_id ON widgets_bundle(tenant_id, external_id); -CREATE INDEX IF NOT EXISTS idx_entity_view_external_id ON entity_view(tenant_id, external_id); - CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); ALTER TABLE admin_settings @@ -73,3 +64,77 @@ CREATE TABLE IF NOT EXISTS user_auth_settings ( CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); ALTER TABLE tenant_profile DROP COLUMN IF EXISTS isolated_tb_core; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'device_external_id_unq_key') THEN + ALTER TABLE device ADD CONSTRAINT device_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'device_profile_external_id_unq_key') THEN + ALTER TABLE device_profile ADD CONSTRAINT device_profile_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'asset_external_id_unq_key') THEN + ALTER TABLE asset ADD CONSTRAINT asset_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'rule_chain_external_id_unq_key') THEN + ALTER TABLE rule_chain ADD CONSTRAINT rule_chain_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'dashboard_external_id_unq_key') THEN + ALTER TABLE dashboard ADD CONSTRAINT dashboard_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'customer_external_id_unq_key') THEN + ALTER TABLE customer ADD CONSTRAINT customer_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'widgets_bundle_external_id_unq_key') THEN + ALTER TABLE widgets_bundle ADD CONSTRAINT widgets_bundle_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'entity_view_external_id_unq_key') THEN + ALTER TABLE entity_view ADD CONSTRAINT entity_view_external_id_unq_key UNIQUE (tenant_id, external_id); + END IF; + END; +$$; + diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index eb85f70687..31c40e0d96 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -22,6 +22,7 @@ import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntitySubtype; @@ -126,12 +127,10 @@ public class BaseAssetService extends AbstractCachedEntityService extractConstraintViolationException(Exception t) { + protected static Optional extractConstraintViolationException(Exception t) { if (t instanceof ConstraintViolationException) { return Optional.of((ConstraintViolationException) t); } else if (t.getCause() instanceof ConstraintViolationException) { @@ -83,6 +87,29 @@ public abstract class AbstractEntityService { } } + public static final void checkConstraintViolation(Exception t, String constraintName, String constraintMessage) { + checkConstraintViolation(t, Collections.singletonMap(constraintName, constraintMessage)); + } + + public static final void checkConstraintViolation(Exception t, String constraintName1, String constraintMessage1, String constraintName2, String constraintMessage2) { + checkConstraintViolation(t, Map.of(constraintName1, constraintMessage1, constraintName2, constraintMessage2)); + } + + public static final void checkConstraintViolation(Exception t, Map constraints) { + var exOpt = extractConstraintViolationException(t); + if (exOpt.isPresent()) { + var ex = exOpt.get(); + if (StringUtils.isNotEmpty(ex.getConstraintName())) { + var constraintName = ex.getConstraintName(); + for (var constraintMessage : constraints.entrySet()) { + if (constraintName.equals(constraintMessage.getKey())) { + throw new DataValidationException(constraintMessage.getValue()); + } + } + } + } + } + protected void checkAssignedEntityViewsToEdge(TenantId tenantId, EntityId entityId, EdgeId edgeId) { List entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(tenantId, entityId); if (entityViews != null && !entityViews.isEmpty()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index 6b1d6775d6..f71f2cc7a9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -98,9 +98,15 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService extractConstraintViolationException(Exception t) { - if (t instanceof ConstraintViolationException) { - return Optional.of((ConstraintViolationException) t); - } else if (t.getCause() instanceof ConstraintViolationException) { - return Optional.of((ConstraintViolationException) (t.getCause())); - } else { - return Optional.empty(); - } - } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 746bd5e4e4..b511ab3da2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -98,7 +98,12 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Transactional public RuleChain saveRuleChain(RuleChain ruleChain) { ruleChainValidator.validate(ruleChain, RuleChain::getTenantId); - return ruleChainDao.save(ruleChain.getTenantId(), ruleChain); + try { + return ruleChainDao.save(ruleChain.getTenantId(), ruleChain); + } catch (Exception e) { + checkConstraintViolation(e, "rule_chain_external_id_unq_key", "Rule Chain with such external id already exists!"); + throw e; + } } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index d688d145f4..3b5e45f206 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -256,8 +256,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD deletePartitionAsync(tenantId, cursor, resultFuture); for (Long partition : partitionsToDelete) { - CassandraPartitionCacheKey key = new CassandraPartitionCacheKey(entityId, query.getKey(), partition); - cassandraTsPartitionsCache.invalidate(key); + cassandraTsPartitionsCache.invalidate(new CassandraPartitionCacheKey(entityId, query.getKey(), partition)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index df5e4a29f1..737043ccba 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.entity.AbstractCachedEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -59,7 +60,12 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { public WidgetsBundle saveWidgetsBundle(WidgetsBundle widgetsBundle) { log.trace("Executing saveWidgetsBundle [{}]", widgetsBundle); widgetsBundleValidator.validate(widgetsBundle, WidgetsBundle::getTenantId); - return widgetsBundleDao.save(widgetsBundle.getTenantId(), widgetsBundle); + try { + return widgetsBundleDao.save(widgetsBundle.getTenantId(), widgetsBundle); + } catch (Exception e) { + AbstractCachedEntityService.checkConstraintViolation(e, "widgets_bundle_external_id_unq_key", "Widget Bundle with such external id already exists!"); + throw e; + } } @Override diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index a1a9820909..a9b25a66f7 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -84,7 +84,8 @@ CREATE TABLE IF NOT EXISTS asset ( tenant_id uuid, type varchar(255), external_id uuid, - CONSTRAINT asset_name_unq_key UNIQUE (tenant_id, name) + CONSTRAINT asset_name_unq_key UNIQUE (tenant_id, name), + CONSTRAINT asset_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS audit_log ( @@ -144,7 +145,8 @@ CREATE TABLE IF NOT EXISTS customer ( tenant_id uuid, title varchar(255), zip varchar(255), - external_id uuid + external_id uuid, + CONSTRAINT customer_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS dashboard ( @@ -158,7 +160,8 @@ CREATE TABLE IF NOT EXISTS dashboard ( mobile_hide boolean DEFAULT false, mobile_order int, image varchar(1000000), - external_id uuid + external_id uuid, + CONSTRAINT dashboard_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS rule_chain ( @@ -173,7 +176,8 @@ CREATE TABLE IF NOT EXISTS rule_chain ( debug_mode boolean, search_text varchar(255), tenant_id uuid, - external_id uuid + external_id uuid, + CONSTRAINT rule_chain_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS rule_node ( @@ -221,7 +225,7 @@ CREATE TABLE IF NOT EXISTS ota_package ( CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); -CREATE TABLE IF NOT EXISTS queue( +CREATE TABLE IF NOT EXISTS queue ( id uuid NOT NULL CONSTRAINT queue_pkey PRIMARY KEY, created_time bigint NOT NULL, tenant_id uuid, @@ -258,6 +262,7 @@ CREATE TABLE IF NOT EXISTS device_profile ( external_id uuid, CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), + CONSTRAINT device_profile_external_id_unq_key UNIQUE (tenant_id, external_id), CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id), CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id), @@ -301,6 +306,7 @@ CREATE TABLE IF NOT EXISTS device ( software_id uuid, external_id uuid, CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), + CONSTRAINT device_external_id_unq_key UNIQUE (tenant_id, external_id), CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES ota_package(id), CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES ota_package(id) @@ -424,7 +430,8 @@ CREATE TABLE IF NOT EXISTS widgets_bundle ( title varchar(255), image varchar(1000000), description varchar(255), - external_id uuid + external_id uuid, + CONSTRAINT widgets_bundle_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS entity_view ( @@ -441,7 +448,8 @@ CREATE TABLE IF NOT EXISTS entity_view ( end_ts bigint, search_text varchar(255), additional_info varchar, - external_id uuid + external_id uuid, + CONSTRAINT entity_view_external_id_unq_key UNIQUE (tenant_id, external_id) ); CREATE TABLE IF NOT EXISTS ts_kv_latest From 581cf8b7c867c1d0c2c9e39a0115c9e241864f9e Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 15 Jul 2022 20:16:51 +0300 Subject: [PATCH 10/21] Add TbCoreComponent annotation to DefaultEdgeRequestsService to avoid invalid dependencies in rule engine --- .../service/edge/rpc/sync/DefaultEdgeRequestsService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index 21f3171d3d..e66d7d5595 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -72,6 +72,7 @@ import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.entityview.TbEntityViewService; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.state.DefaultDeviceStateService; @@ -83,6 +84,7 @@ import java.util.Map; import java.util.UUID; @Service +@TbCoreComponent @Slf4j public class DefaultEdgeRequestsService implements EdgeRequestsService { From d5d75b1b5ea56616680cd46bdf4e1c8aeab8966d Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 18 Jul 2022 11:40:49 +0300 Subject: [PATCH 11/21] UI: Refactoring --- .../shared/components/contact.component.html | 2 +- .../components/phone-input.component.ts | 39 +++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ui-ngx/src/app/shared/components/contact.component.html b/ui-ngx/src/app/shared/components/contact.component.html index 2776c88863..d3e6c474d0 100644 --- a/ui-ngx/src/app/shared/components/contact.component.html +++ b/ui-ngx/src/app/shared/components/contact.component.html @@ -57,7 +57,7 @@ diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index 1be1e20d29..2f055bbb59 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -92,7 +92,6 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida this.isLoading = value; if (this.phoneFormGroup) { this.defineCountryFromNumber(this.phoneFormGroup.get('phoneNumber').value); - this.getFlagAndPhoneNumberData(this.phoneFormGroup.get('country').value); } } } @@ -103,6 +102,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida private countryCallingCode = '+'; private modelValue: string; private changeSubscriptions: Subscription[] = []; + private validators: ValidatorFn[] = [(c: FormControl) => Validators.pattern(this.getPhoneNumberPattern())(c), this.validatePhoneNumber()]; private propagateChange = (v: any) => { }; @@ -116,15 +116,16 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } ngOnInit(): void { - const validators: ValidatorFn[] = [(c: FormControl) => Validators.pattern(this.getPhoneNumberPattern())(c), this.validatePhoneNumber()]; if (this.required) { - validators.push(Validators.required); + this.validators.push(Validators.required); } this.phoneFormGroup = this.fb.group({ country: [this.defaultCountry, []], - phoneNumber: [null, validators] + phoneNumber: [null, this.validators] }); + this.flagIcon = this.getFlagIcon(this.phoneFormGroup.get('country').value); + this.changeSubscriptions.push(this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => { this.updateModel(); this.defineCountryFromNumber(value); @@ -154,11 +155,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida focus() { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); if (!phoneNumber.value) { - phoneNumber.patchValue(this.countryCallingCode, {emitEvent: false}); - } - if (phoneNumber.untouched && this.countryCallingCode !== phoneNumber.value) { - phoneNumber.markAsTouched(); - phoneNumber.updateValueAndValidity(); + phoneNumber.patchValue(this.countryCallingCode, {emitEvent: true}); } } @@ -214,7 +211,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida validate(): ValidationErrors | null { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); - return phoneNumber.valid ? null : { + return phoneNumber.valid || this.countryCallingCode === phoneNumber.value ? null : { phoneFormGroup: false }; } @@ -239,6 +236,24 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida this.modelValue = phoneNumber; let country = this.defaultCountry; if (this.parsePhoneNumberFromString) { + this.phoneFormGroup.get('phoneNumber').clearValidators(); + this.phoneFormGroup.get('phoneNumber').setValidators(this.validators); + if (phoneNumber) { + const parsedPhoneNumber = this.parsePhoneNumberFromString(phoneNumber); + if (parsedPhoneNumber?.isValid() && parsedPhoneNumber?.isPossible()) { + this.enableFlagsSelect = true; + } else { + const validators = [Validators.maxLength(255)]; + if (this.required) { + validators.push(Validators.required); + } + this.phoneFormGroup.get('phoneNumber').setValidators(validators); + this.enableFlagsSelect = false; + } + } else { + this.enableFlagsSelect = true; + } + this.phoneFormGroup.updateValueAndValidity({emitEvent: false}); country = phoneNumber ? this.parsePhoneNumberFromString(phoneNumber)?.country || this.defaultCountry : this.defaultCountry; this.getFlagAndPhoneNumberData(country); } @@ -247,7 +262,9 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida private updateModel() { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); - if (phoneNumber.valid) { + if (phoneNumber.value === '+' || phoneNumber.value === this.countryCallingCode) { + this.propagateChange(null); + } else if (phoneNumber.valid) { this.modelValue = phoneNumber.value; this.propagateChange(this.modelValue); } else { From 54b301d7bad1a09f1add83454844493a4d1e870e Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Mon, 18 Jul 2022 11:46:39 +0300 Subject: [PATCH 12/21] Restore @EnableScheduling on MQTT and HTTP transports --- .../server/http/ThingsboardHttpTransportApplication.java | 2 ++ .../server/mqtt/ThingsboardMqttTransportApplication.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java b/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java index 4d51a5a65a..52ae8db97b 100644 --- a/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java +++ b/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java @@ -20,11 +20,13 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; import java.util.Arrays; @SpringBootApplication @EnableAsync +@EnableScheduling @EnableAutoConfiguration @ComponentScan({"org.thingsboard.server.http", "org.thingsboard.server.common", "org.thingsboard.server.transport.http", "org.thingsboard.server.queue", "org.thingsboard.server.cache"}) public class ThingsboardHttpTransportApplication { diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java b/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java index f97ca22255..6db7772a74 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java @@ -20,11 +20,13 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; import java.util.Arrays; @SpringBootConfiguration @EnableAsync +@EnableScheduling @EnableAutoConfiguration @ComponentScan({"org.thingsboard.server.mqtt", "org.thingsboard.server.common", "org.thingsboard.server.transport.mqtt", "org.thingsboard.server.queue", "org.thingsboard.server.cache"}) public class ThingsboardMqttTransportApplication { From 760dbe063b673c33d6f060645c30b361d3f36598 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 18 Jul 2022 12:06:05 +0300 Subject: [PATCH 13/21] UI: Fix enableFlagsSelect input --- .../app/shared/components/phone-input.component.html | 2 +- .../app/shared/components/phone-input.component.ts | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/shared/components/phone-input.component.html b/ui-ngx/src/app/shared/components/phone-input.component.html index 87ce1f6c1b..4a7b36b50e 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.html +++ b/ui-ngx/src/app/shared/components/phone-input.component.html @@ -18,7 +18,7 @@
-
+
{{ flagIcon }} diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index 2f055bbb59..238f3c7134 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -77,6 +77,10 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida @Input() label = 'phone-input.phone-input-label'; + get showFlagSelect(): boolean { + return this.enableFlagsSelect && !this.isLegacy; + } + allCountries: Array = this.countryCodeData.allCountries; phonePlaceholder = '+12015550123'; flagIcon: string; @@ -96,6 +100,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } } + private isLegacy = false; private getExampleNumber; private parsePhoneNumberFromString; private baseCode = 127397; @@ -241,17 +246,17 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida if (phoneNumber) { const parsedPhoneNumber = this.parsePhoneNumberFromString(phoneNumber); if (parsedPhoneNumber?.isValid() && parsedPhoneNumber?.isPossible()) { - this.enableFlagsSelect = true; + this.isLegacy = false; } else { const validators = [Validators.maxLength(255)]; if (this.required) { validators.push(Validators.required); } this.phoneFormGroup.get('phoneNumber').setValidators(validators); - this.enableFlagsSelect = false; + this.isLegacy = true; } } else { - this.enableFlagsSelect = true; + this.isLegacy = false; } this.phoneFormGroup.updateValueAndValidity({emitEvent: false}); country = phoneNumber ? this.parsePhoneNumberFromString(phoneNumber)?.country || this.defaultCountry : this.defaultCountry; From bd0332ea2ecc7d06ab8187d4f4832392f6cc3357 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 18 Jul 2022 12:11:24 +0300 Subject: [PATCH 14/21] Fix the annotation duplication --- .../server/http/ThingsboardHttpTransportApplication.java | 1 - .../server/mqtt/ThingsboardMqttTransportApplication.java | 1 - 2 files changed, 2 deletions(-) diff --git a/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java b/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java index 52ae8db97b..41ee0bddaf 100644 --- a/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java +++ b/transport/http/src/main/java/org/thingsboard/server/http/ThingsboardHttpTransportApplication.java @@ -27,7 +27,6 @@ import java.util.Arrays; @SpringBootApplication @EnableAsync @EnableScheduling -@EnableAutoConfiguration @ComponentScan({"org.thingsboard.server.http", "org.thingsboard.server.common", "org.thingsboard.server.transport.http", "org.thingsboard.server.queue", "org.thingsboard.server.cache"}) public class ThingsboardHttpTransportApplication { diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java b/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java index a45f586b7c..6db7772a74 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/mqtt/ThingsboardMqttTransportApplication.java @@ -28,7 +28,6 @@ import java.util.Arrays; @EnableAsync @EnableScheduling @EnableAutoConfiguration -@EnableScheduling @ComponentScan({"org.thingsboard.server.mqtt", "org.thingsboard.server.common", "org.thingsboard.server.transport.mqtt", "org.thingsboard.server.queue", "org.thingsboard.server.cache"}) public class ThingsboardMqttTransportApplication { From 6e776417cb5782b40e9b6ab880bb6ba6bb3db7dd Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 18 Jul 2022 14:34:55 +0300 Subject: [PATCH 15/21] Fix references to tenant --- .../sync/ie/importing/impl/BaseEntityImportService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java index dae246ec49..4fdd6cf6ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java @@ -308,6 +308,10 @@ public abstract class BaseEntityImportService ID getInternalId(ID externalId, boolean throwExceptionIfNotFound) { if (externalId == null || externalId.isNullUid()) return null; + if (EntityType.TENANT.equals(externalId.getEntityType())) { + return (ID) ctx.getTenantId(); + } + EntityId localId = ctx.getInternalId(externalId); if (localId != null) { return (ID) localId; From 58e418578c897b80306d6b2fe2057ec5579d8c2d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 18 Jul 2022 15:53:02 +0300 Subject: [PATCH 16/21] Fix reordering of chunked entities from git --- .../DefaultGitVersionControlQueueService.java | 23 +++++++++++-------- common/cluster-api/src/main/proto/queue.proto | 8 +++---- .../DefaultClusterVersionControlService.java | 10 ++++---- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java index 0c098d8281..413980d119 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java @@ -76,11 +76,13 @@ import org.thingsboard.server.service.sync.vc.data.VoidGitRequest; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -102,7 +104,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu private final SchedulerComponent scheduler; private final Map> pendingRequestMap = new HashMap<>(); - private final Map> chunkedMsgs = new ConcurrentHashMap<>(); + private final Map> chunkedMsgs = new ConcurrentHashMap<>(); @Value("${queue.vc.request-timeout:60000}") private int requestTimeout; @@ -286,7 +288,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu @SuppressWarnings("rawtypes") public ListenableFuture getEntity(TenantId tenantId, String versionId, EntityId entityId) { EntityContentGitRequest request = new EntityContentGitRequest(tenantId, versionId, entityId); - chunkedMsgs.put(request.getRequestId(), new LinkedHashMap<>()); + chunkedMsgs.put(request.getRequestId(), new HashMap<>()); registerAndSend(request, builder -> builder.setEntityContentRequest(EntityContentRequestMsg.newBuilder() .setVersionId(versionId) .setEntityType(entityId.getEntityType().name()) @@ -328,7 +330,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu @SuppressWarnings("rawtypes") public ListenableFuture> getEntities(TenantId tenantId, String versionId, EntityType entityType, int offset, int limit) { EntitiesContentGitRequest request = new EntitiesContentGitRequest(tenantId, versionId, entityType); - chunkedMsgs.put(request.getRequestId(), new LinkedHashMap<>()); + chunkedMsgs.put(request.getRequestId(), new HashMap<>()); registerAndSend(request, builder -> builder.setEntitiesContentRequest(EntitiesContentRequestMsg.newBuilder() .setVersionId(versionId) .setEntityType(entityType.name()) @@ -412,10 +414,10 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu ((ListVersionsGitRequest) request).getFuture().set(toPageData(listVersionsResponse)); } else if (vcResponseMsg.hasEntityContentResponse()) { TransportProtos.EntityContentResponseMsg responseMsg = vcResponseMsg.getEntityContentResponse(); - log.trace("[{}] received chunk {} for 'getEntity'", responseMsg.getChunkedMsgId(), responseMsg.getChunkIndex()); - var joined = joinChunks(requestId, responseMsg, 1); + log.trace("Received chunk {} for 'getEntity'", responseMsg.getChunkIndex()); + var joined = joinChunks(requestId, responseMsg, 0, 1); if (joined.isPresent()) { - log.trace("[{}] collected all chunks for 'getEntity'", responseMsg.getChunkedMsgId()); + log.trace("Collected all chunks for 'getEntity'"); ((EntityContentGitRequest) request).getFuture().set(joined.get().get(0)); } else { completed = false; @@ -424,7 +426,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu TransportProtos.EntitiesContentResponseMsg responseMsg = vcResponseMsg.getEntitiesContentResponse(); TransportProtos.EntityContentResponseMsg item = responseMsg.getItem(); if (responseMsg.getItemsCount() > 0) { - var joined = joinChunks(requestId, item, responseMsg.getItemsCount()); + var joined = joinChunks(requestId, item, responseMsg.getItemIdx(), responseMsg.getItemsCount()); if (joined.isPresent()) { ((EntitiesContentGitRequest) request).getFuture().set(joined.get()); } else { @@ -459,16 +461,17 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu } @SuppressWarnings("rawtypes") - private Optional> joinChunks(UUID requestId, TransportProtos.EntityContentResponseMsg responseMsg, int expectedMsgCount) { + private Optional> joinChunks(UUID requestId, TransportProtos.EntityContentResponseMsg responseMsg, int itemIdx, int expectedMsgCount) { var chunksMap = chunkedMsgs.get(requestId); if (chunksMap == null) { return Optional.empty(); } - String[] msgChunks = chunksMap.computeIfAbsent(responseMsg.getChunkedMsgId(), id -> new String[responseMsg.getChunksCount()]); + String[] msgChunks = chunksMap.computeIfAbsent(itemIdx, id -> new String[responseMsg.getChunksCount()]); msgChunks[responseMsg.getChunkIndex()] = responseMsg.getData(); if (chunksMap.size() == expectedMsgCount && chunksMap.values().stream() .allMatch(chunks -> CollectionsUtil.countNonNull(chunks) == chunks.length)) { - return Optional.of(chunksMap.values().stream() + return Optional.of(chunksMap.entrySet().stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)).map(Map.Entry::getValue) .map(chunks -> String.join("", chunks)) .map(this::toData) .collect(Collectors.toList())); diff --git a/common/cluster-api/src/main/proto/queue.proto b/common/cluster-api/src/main/proto/queue.proto index 3995040080..1714e109a3 100644 --- a/common/cluster-api/src/main/proto/queue.proto +++ b/common/cluster-api/src/main/proto/queue.proto @@ -803,9 +803,8 @@ message EntityContentRequestMsg { message EntityContentResponseMsg { string data = 1; - string chunkedMsgId = 2; - int32 chunkIndex = 3; - int32 chunksCount = 4; + int32 chunkIndex = 2; + int32 chunksCount = 3; } message EntitiesContentRequestMsg { @@ -817,7 +816,8 @@ message EntitiesContentRequestMsg { message EntitiesContentResponseMsg { EntityContentResponseMsg item = 1; - int32 itemsCount = 2; + int32 itemIdx = 2; + int32 itemsCount = 3; } message VersionsDiffRequestMsg { diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java index 4d642be521..eb7a3d20e4 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java @@ -274,20 +274,20 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe var ids = vcService.listEntitiesAtVersion(ctx.getTenantId(), request.getVersionId(), path) .stream().skip(request.getOffset()).limit(request.getLimit()).collect(Collectors.toList()); if (!ids.isEmpty()) { - for (VersionedEntityInfo info : ids) { + for (int i = 0; i < ids.size(); i++){ + VersionedEntityInfo info = ids.get(i); var data = vcService.getFileContentAtCommit(ctx.getTenantId(), getRelativePath(info.getExternalId().getEntityType(), info.getExternalId().getId().toString()), request.getVersionId()); - Iterable dataChunks = StringUtils.split(data, msgChunkSize); - String chunkedMsgId = UUID.randomUUID().toString(); int chunksCount = Iterables.size(dataChunks); AtomicInteger chunkIndex = new AtomicInteger(); + int itemIdx = i; dataChunks.forEach(chunk -> { EntitiesContentResponseMsg.Builder response = EntitiesContentResponseMsg.newBuilder() .setItemsCount(ids.size()) + .setItemIdx(itemIdx) .setItem(EntityContentResponseMsg.newBuilder() .setData(chunk) - .setChunkedMsgId(chunkedMsgId) .setChunksCount(chunksCount) .setChunkIndex(chunkIndex.getAndIncrement()) .build()); @@ -313,7 +313,7 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe dataChunks.forEach(chunk -> { log.trace("[{}] sending chunk {} for 'getEntity'", chunkedMsgId, chunkIndex.get()); reply(ctx, Optional.empty(), builder -> builder.setEntityContentResponse(EntityContentResponseMsg.newBuilder() - .setData(chunk).setChunkedMsgId(chunkedMsgId).setChunksCount(chunksCount) + .setData(chunk).setChunksCount(chunksCount) .setChunkIndex(chunkIndex.getAndIncrement()))); }); } From a60ecd13722199b6f8ff73d4f915a48951b13c44 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 18 Jul 2022 16:56:03 +0300 Subject: [PATCH 17/21] UI: Fixed responsive create/restore complex version --- ...entity-types-version-create.component.html | 97 +++++++++---------- ...entity-types-version-create.component.scss | 4 + .../entity-types-version-create.component.ts | 2 + .../entity-types-version-load.component.html | 71 +++++++------- .../entity-types-version-load.component.scss | 4 + .../vc/entity-types-version-load.component.ts | 2 + .../vc/entity-versions-table.component.ts | 4 +- 7 files changed, 97 insertions(+), 87 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html index 656664784d..bc2131c5a1 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.html @@ -22,7 +22,8 @@
- +
@@ -40,57 +41,55 @@
- -
- -
- - -
- - version-control.sync-strategy - - - {{ 'version-control.default' | translate }} - - - {{syncStrategyTranslations.get(strategy) | translate}} - - - -
- - {{ 'version-control.export-credentials' | translate }} - - - {{ 'version-control.export-attributes' | translate }} - - - {{ 'version-control.export-relations' | translate }} - -
+
+ +
+ + +
+ + version-control.sync-strategy + + + {{ 'version-control.default' | translate }} + + + {{syncStrategyTranslations.get(strategy) | translate}} + + + +
+ + {{ 'version-control.export-credentials' | translate }} + + + {{ 'version-control.export-attributes' | translate }} + + + {{ 'version-control.export-relations' | translate }} +
-
- - {{ 'version-control.all-entities' | translate }} - - - -
- +
+ + {{ 'version-control.all-entities' | translate }} + + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss index 62b29bed53..47b5de00b8 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss @@ -55,5 +55,9 @@ .mat-expansion-panel-body { padding: 0; } + &.load .mat-expansion-panel-content { + height: 0; + visibility: hidden; + } } } diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts index 6434329447..f7e8541d07 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts @@ -74,6 +74,8 @@ export class EntityTypesVersionCreateComponent extends PageComponent implements entityTypes = EntityType; + loading = true; + constructor(protected store: Store, private translate: TranslateService, private fb: FormBuilder) { diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html index f50098c9dd..824759bec0 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html @@ -22,7 +22,8 @@
- +
@@ -40,44 +41,42 @@
- -
- -
- - -
-
- - {{ 'version-control.remove-other-entities' | translate }} - - - {{ 'version-control.find-existing-entity-by-name' | translate }} - -
-
- - {{ 'version-control.load-credentials' | translate }} - - - {{ 'version-control.load-attributes' | translate }} - - - {{ 'version-control.load-relations' | translate }} - -
+
+ +
+ + +
+
+ + {{ 'version-control.remove-other-entities' | translate }} + + + {{ 'version-control.find-existing-entity-by-name' | translate }} + +
+
+ + {{ 'version-control.load-credentials' | translate }} + + + {{ 'version-control.load-attributes' | translate }} + + + {{ 'version-control.load-relations' | translate }} +
- +
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss index a02e782b76..6f1f26c640 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss @@ -55,5 +55,9 @@ .mat-expansion-panel-body { padding: 0; } + &.load .mat-expansion-panel-content { + height: 0; + visibility: hidden; + } } } diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts index ef43899c5b..0a02c95cff 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts @@ -68,6 +68,8 @@ export class EntityTypesVersionLoadComponent extends PageComponent implements On entityTypes = EntityType; + loading = true; + constructor(protected store: Store, private translate: TranslateService, private popoverService: TbPopoverService, diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts index 1073c26acc..fc7984e878 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts @@ -248,7 +248,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } }, {maxHeight: '90vh', height: '100%', padding: '10px'}, - {width: '600px', minWidth: '100%', maxWidth: '100%'}, {}, false); + {}, {}, false); complexCreateVersionPopover.tbComponentRef.instance.popoverComponent = complexCreateVersionPopover; } } @@ -321,7 +321,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } }, {maxHeight: '80vh', height: '100%', padding: '10px'}, - {width: '600px', minWidth: '100%', maxWidth: '100%'}, {}, false); + {}, {}, false); restoreEntitiesVersionPopover.tbComponentRef.instance.popoverComponent = restoreEntitiesVersionPopover; } } From 53381636e35c95e374776a91b2ffffdec15cc49c Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 18 Jul 2022 17:31:44 +0300 Subject: [PATCH 18/21] Fix ota package cyclic dependency --- .../dao/service/validator/AbstractHasOtaPackageValidator.java | 2 ++ .../dao/service/validator/BaseOtaPackageDataValidator.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AbstractHasOtaPackageValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AbstractHasOtaPackageValidator.java index d53d2f09c4..069e1fcfc8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/AbstractHasOtaPackageValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/AbstractHasOtaPackageValidator.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.service.validator; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasOtaPackage; import org.thingsboard.server.common.data.OtaPackage; @@ -29,6 +30,7 @@ import org.thingsboard.server.dao.service.DataValidator; public abstract class AbstractHasOtaPackageValidator> extends DataValidator { @Autowired + @Lazy private OtaPackageService otaPackageService; protected void validateOtaPackage(TenantId tenantId, T entity, DeviceProfileId deviceProfileId) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/BaseOtaPackageDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/BaseOtaPackageDataValidator.java index c7ffe8c61e..f0c7c3e15d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/BaseOtaPackageDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/BaseOtaPackageDataValidator.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.service.validator; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.OtaPackageInfo; @@ -30,6 +31,7 @@ import java.util.Objects; public abstract class BaseOtaPackageDataValidator> extends DataValidator { @Autowired + @Lazy private TenantService tenantService; @Autowired From 742e27f3e20aeccabca11524de1973577064cbd8 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 18 Jul 2022 18:29:57 +0300 Subject: [PATCH 19/21] fix_bug_tests lwm2m Security --- .../security/AbstractSecurityLwM2MIntegrationTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index 328a1fa0da..6547405337 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -196,7 +196,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M device.getId().getId().toString(); lwM2MTestClient.start(isStartLw); await(awaitAlias) - .atMost(5000, TimeUnit.MILLISECONDS) + .atMost(20, TimeUnit.SECONDS) .until(() -> finishState.equals(lwM2MTestClient.getClientState())); Assert.assertEquals(expectedStatuses, lwM2MTestClient.getClientStates()); } @@ -234,7 +234,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M String deviceId = device.getId().getId().toString(); lwM2MTestClient.start(true); await(awaitAlias) - .atMost(5000, TimeUnit.MILLISECONDS) + .atMost(20, TimeUnit.SECONDS) .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState())); Assert.assertEquals(expectedStatusesLwm2m, lwM2MTestClient.getClientStates()); @@ -246,7 +246,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M expectedStatusesBs.add(ON_DEREGISTRATION_STARTED); expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS); await(awaitAlias) - .atMost(5000, TimeUnit.MILLISECONDS) + .atMost(20, TimeUnit.SECONDS) .until(() -> ON_REGISTRATION_SUCCESS.equals(lwM2MTestClient.getClientState())); Assert.assertEquals(expectedStatusesBs, lwM2MTestClient.getClientStates()); } From 156fa3f0d22e1518e27303e3c71c795288b2e827 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 19 Jul 2022 11:04:49 +0300 Subject: [PATCH 20/21] UI: Improve complex version control popups layout. --- .../vc/complex-version-create.component.html | 62 +++--- .../vc/complex-version-load.component.html | 16 +- ...entity-types-version-create.component.html | 188 +++++++++--------- .../entity-types-version-create.component.ts | 2 +- .../entity-types-version-load.component.html | 162 ++++++++------- .../entity-types-version-load.component.scss | 63 ------ .../vc/entity-types-version-load.component.ts | 2 +- ...ss => entity-types-version.component.scss} | 60 +++--- 8 files changed, 244 insertions(+), 311 deletions(-) delete mode 100644 ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss rename ui-ngx/src/app/modules/home/components/vc/{entity-types-version-create.component.scss => entity-types-version.component.scss} (55%) diff --git a/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html index ef4226c393..317d6e9cb6 100644 --- a/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/complex-version-create.component.html @@ -16,7 +16,7 @@ --> -
+

{{ 'version-control.create-entities-version' | translate }}

@@ -24,38 +24,36 @@ - -
-
- - - - version-control.version-name - - - {{ 'version-control.version-name-required' | translate }} - - - - version-control.default-sync-strategy - - - {{syncStrategyTranslations.get(strategy) | translate}} - - - - - - -
-
+ +
+ + + + version-control.version-name + + + {{ 'version-control.version-name-required' | translate }} + + +
+ + version-control.default-sync-strategy + + + {{syncStrategyTranslations.get(strategy) | translate}} + + + + + + -
+
-
- -
- -
- - -
- - version-control.sync-strategy - - - {{ 'version-control.default' | translate }} - - - {{syncStrategyTranslations.get(strategy) | translate}} - - - -
- - {{ 'version-control.export-credentials' | translate }} - - - {{ 'version-control.export-attributes' | translate }} - - - {{ 'version-control.export-relations' | translate }} - -
+
+ version-control.entities-to-export +
+
+ + +
+ +
+
{{ entityTypeText(entityTypeFormGroup) }}
+
+
+ + +
+
+
+ +
+ + +
+ + version-control.sync-strategy + + + {{ 'version-control.default' | translate }} + + + {{syncStrategyTranslations.get(strategy) | translate}} + + + +
+ + {{ 'version-control.export-credentials' | translate }} + + + {{ 'version-control.export-attributes' | translate }} + + + {{ 'version-control.export-relations' | translate }} +
-
- - {{ 'version-control.all-entities' | translate }} - - - -
- -
-
- version-control.no-entities-to-export-prompt -
-
- - - -
+
+ + {{ 'version-control.all-entities' | translate }} + + + +
+
+ +
+
+ version-control.no-entities-to-export-prompt
-
-
+
+
+ + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts index f7e8541d07..789ac72922 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.ts @@ -43,7 +43,7 @@ import { isDefinedAndNotNull } from '@core/utils'; @Component({ selector: 'tb-entity-types-version-create', templateUrl: './entity-types-version-create.component.html', - styleUrls: ['./entity-types-version-create.component.scss'], + styleUrls: ['./entity-types-version.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html index 824759bec0..6910fa56af 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.html @@ -15,89 +15,87 @@ limitations under the License. --> -
-
- version-control.entities-to-restore -
-
- - -
- -
-
{{ entityTypeText(entityTypeFormGroup) }}
-
-
- - -
-
-
- -
- - -
-
- - {{ 'version-control.remove-other-entities' | translate }} - - - {{ 'version-control.find-existing-entity-by-name' | translate }} - -
-
- - {{ 'version-control.load-credentials' | translate }} - - - {{ 'version-control.load-attributes' | translate }} - - - {{ 'version-control.load-relations' | translate }} - -
+
+ version-control.entities-to-restore +
+
+ + +
+ +
+
{{ entityTypeText(entityTypeFormGroup) }}
+
+
+ + +
+
+
+ +
+ + +
+
+ + {{ 'version-control.remove-other-entities' | translate }} + + + {{ 'version-control.find-existing-entity-by-name' | translate }} + +
+
+ + {{ 'version-control.load-credentials' | translate }} + + + {{ 'version-control.load-attributes' | translate }} + + + {{ 'version-control.load-relations' | translate }} +
- -
-
- version-control.no-entities-to-restore-prompt -
-
- - - -
+
+ +
+
+ version-control.no-entities-to-restore-prompt
-
-
+
+
+ + + +
+ diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss deleted file mode 100644 index 6f1f26c640..0000000000 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.scss +++ /dev/null @@ -1,63 +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. - */ -:host { - .entity-types-version-load { - .fields-group { - padding: 0 16px 8px; - margin-bottom: 10px; - border: 1px groove rgba(0, 0, 0, .25); - border-radius: 4px; - - legend { - color: rgba(0, 0, 0, .7); - width: fit-content; - } - - legend + * { - display: block; - margin-top: 16px; - } - } - - .tb-prompt { - margin: 30px 0; - } - - mat-expansion-panel.entity-type-config { - box-shadow: none; - border: 1px groove rgba(0, 0, 0, .25); - .mat-expansion-panel-header { - padding: 0 24px 0 8px; - height: 48px; - } - .entity-type-config-content { - padding: 0 8px 8px; - } - } - } -} - -:host ::ng-deep { - .mat-expansion-panel.entity-type-config { - .mat-expansion-panel-body { - padding: 0; - } - &.load .mat-expansion-panel-content { - height: 0; - visibility: hidden; - } - } -} diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts index 0a02c95cff..6d1e542fa3 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version-load.component.ts @@ -41,7 +41,7 @@ import { RemoveOtherEntitiesConfirmComponent } from '@home/components/vc/remove- @Component({ selector: 'tb-entity-types-version-load', templateUrl: './entity-types-version-load.component.html', - styleUrls: ['./entity-types-version-load.component.scss'], + styleUrls: ['./entity-types-version.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss b/ui-ngx/src/app/modules/home/components/vc/entity-types-version.component.scss similarity index 55% rename from ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss rename to ui-ngx/src/app/modules/home/components/vc/entity-types-version.component.scss index 47b5de00b8..4a7e1eca65 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-types-version-create.component.scss +++ b/ui-ngx/src/app/modules/home/components/vc/entity-types-version.component.scss @@ -13,39 +13,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -:host { - .entity-types-version-create { - .fields-group { - padding: 0 16px 8px; - margin-bottom: 10px; - border: 1px groove rgba(0, 0, 0, .25); - border-radius: 4px; - legend { - color: rgba(0, 0, 0, .7); - width: fit-content; - } +@import '../../../../../scss/constants'; + +:host { + min-height: 200px; + min-width: 300px; + @media #{$mat-gt-xs} { + min-width: 550px; + } + .fields-group { + height: 100%; + padding: 0 16px 8px; + border: 1px groove rgba(0, 0, 0, .25); + border-radius: 4px; - legend + * { - display: block; - margin-top: 16px; - } + legend { + color: rgba(0, 0, 0, .7); + width: fit-content; } - .tb-prompt { - margin: 30px 0; + legend + * { + display: block; + margin-top: 16px; } + } + + .tb-prompt { + margin: 30px 0; + } - mat-expansion-panel.entity-type-config { - box-shadow: none; - border: 1px groove rgba(0, 0, 0, .25); - .mat-expansion-panel-header { - padding: 0 24px 0 8px; - height: 48px; - } - .entity-type-config-content { - padding: 0 8px 8px; - } + mat-expansion-panel.entity-type-config { + box-shadow: none; + border: 1px groove rgba(0, 0, 0, .25); + .mat-expansion-panel-header { + padding: 0 24px 0 8px; + height: 48px; + } + .entity-type-config-content { + padding: 0 8px 8px; } } } From 578075e9b8ed2bb29144cb75d76448faa8bc867b Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 19 Jul 2022 12:49:37 +0300 Subject: [PATCH 21/21] Update UI help links --- .../home/pages/admin/two-factor-auth-settings.component.html | 2 +- ui-ngx/src/app/shared/models/constants.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/admin/two-factor-auth-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/two-factor-auth-settings.component.html index 1c6124bdc7..e8d64ae68b 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/two-factor-auth-settings.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/two-factor-auth-settings.component.html @@ -21,7 +21,7 @@
admin.2fa.2fa - +
diff --git a/ui-ngx/src/app/shared/models/constants.ts b/ui-ngx/src/app/shared/models/constants.ts index 28c08f09a0..d793d8082b 100644 --- a/ui-ngx/src/app/shared/models/constants.ts +++ b/ui-ngx/src/app/shared/models/constants.ts @@ -151,8 +151,9 @@ export const HelpLinks = { ruleNodePushToCloud: helpBaseUrl + '/docs/user-guide/rule-engine-2-0/action-nodes/#push-to-cloud', ruleNodePushToEdge: helpBaseUrl + '/docs/user-guide/rule-engine-2-0/action-nodes/#push-to-edge', queue: helpBaseUrl + '/docs/user-guide/queue', - repositorySettings: helpBaseUrl + '/docs/user-guide/ui/repository-settings', - autoCommitSettings: helpBaseUrl + '/docs/user-guide/ui/auto-commit-settings', + repositorySettings: helpBaseUrl + '/docs/user-guide/version-control/#git-settings-configuration', + autoCommitSettings: helpBaseUrl + '/docs/user-guide/version-control/#auto-commit', + twoFactorAuthentication: helpBaseUrl + '/docs/user-guide/two-factor-authentication' } };