From 8ba34a953ab20408f77674614018e279d1f43be4 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 3 Dec 2024 14:06:06 +0200 Subject: [PATCH 01/11] Dashboard/widget resources export - process whole config --- .../controller/DashboardControllerTest.java | 20 +++- .../dao/resource/BaseResourceService.java | 108 ++++++++++++------ 2 files changed, 89 insertions(+), 39 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java index 88dd8f241c..ffbf95d990 100644 --- a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -602,13 +603,14 @@ public class DashboardControllerTest extends AbstractControllerTest { dashboard.setTitle("My dashboard"); dashboard.setConfiguration(JacksonUtil.newObjectNode() .put("someImage", "tb-image;/api/images/tenant/" + imageInfo.getResourceKey()) - .set("widgets", JacksonUtil.toJsonNode(""" + .set("widgets", JacksonUtil.toJsonNode(""" {"xxx": {"config":{"actions":{"elementClick":[ {"customResources":[{"url":{"entityType":"TB_RESOURCE","id": "tb-resource;/api/resource/js_module/tenant/gateway-management-extension.js"},"isModule":true}, {"url":"tb-resource;/api/resource/js_module/tenant/gateway-management-extension.js","isModule":true}]}]}}}} - """))); + """)) + .put("someResource", "tb-resource;/api/resource/js_module/tenant/gateway-management-extension.js")); dashboard = doPost("/api/dashboard", dashboard, Dashboard.class); Dashboard exportedDashboard = doGet("/api/dashboard/" + dashboard.getUuidId() + "?includeResources=true", Dashboard.class); @@ -637,12 +639,18 @@ public class DashboardControllerTest extends AbstractControllerTest { doPost("/api/resource", resource, TbResourceInfo.class); Dashboard importedDashboard = doPost("/api/dashboard", exportedDashboard, Dashboard.class); + String newResourceKey = "gateway-management-extension_(1).js"; + imageRef = importedDashboard.getConfiguration().get("someImage").asText(); assertThat(imageRef).isEqualTo("tb-image;/api/images/tenant/" + imageInfo.getResourceKey()); - resourceRef = importedDashboard.getConfiguration().get("widgets").get("xxx").get("config") - .get("actions").get("elementClick").get(0).get("customResources").get(0).get("url").asText(); - String newResourceKey = "gateway-management-extension_(1).js"; - assertThat(resourceRef).isEqualTo("tb-resource;/api/resource/js_module/tenant/" + newResourceKey); + + List resourcesRefs = new ArrayList<>(); + resourcesRefs.add(importedDashboard.getConfiguration().get("widgets").get("xxx").get("config") + .get("actions").get("elementClick").get(0).get("customResources").get(0).get("url").asText()); + resourcesRefs.add(importedDashboard.getConfiguration().get("someResource").asText()); + assertThat(resourcesRefs).allSatisfy(ref -> { + assertThat(ref).isEqualTo("tb-resource;/api/resource/js_module/tenant/" + newResourceKey); + }); TbResourceInfo importedImageInfo = doGet("/api/images/tenant/" + imageInfo.getResourceKey() + "/info", TbResourceInfo.class); assertThat(importedImageInfo.getEtag()).isEqualTo(imageInfo.getEtag()); diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 22aa2ae748..7101922f6b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -57,6 +57,7 @@ import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.service.validator.ResourceDataValidator; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Base64; import java.util.Collection; import java.util.Collections; @@ -403,16 +404,26 @@ public class BaseResourceService extends AbstractCachedEntityService links = getResourcesLinks(dashboard.getResources()); - return updateResourcesUsage(dashboard.getTenantId(), dashboard.getConfiguration(), DASHBOARD_RESOURCES_MAPPING, links); + return updateResourcesUsage(dashboard.getTenantId(), List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING), links); } @Override public boolean updateResourcesUsage(WidgetTypeDetails widgetTypeDetails) { Map links = getResourcesLinks(widgetTypeDetails.getResources()); - boolean updated = updateResourcesUsage(widgetTypeDetails.getTenantId(), widgetTypeDetails.getDescriptor(), WIDGET_RESOURCES_MAPPING, links); + List jsonNodes = new ArrayList<>(2); + List> mappings = new ArrayList<>(2); + + jsonNodes.add(widgetTypeDetails.getDescriptor()); + mappings.add(WIDGET_RESOURCES_MAPPING); + JsonNode defaultConfig = widgetTypeDetails.getDefaultConfig(); if (defaultConfig != null) { - updated |= updateResourcesUsage(widgetTypeDetails.getTenantId(), defaultConfig, WIDGET_DEFAULT_CONFIG_RESOURCES_MAPPING, links); + jsonNodes.add(defaultConfig); + mappings.add(WIDGET_DEFAULT_CONFIG_RESOURCES_MAPPING); + } + + boolean updated = updateResourcesUsage(widgetTypeDetails.getTenantId(), jsonNodes, mappings, links); + if (defaultConfig != null) { widgetTypeDetails.setDefaultConfig(defaultConfig); } return updated; @@ -433,8 +444,9 @@ public class BaseResourceService extends AbstractCachedEntityService mapping, Map links) { - return processResources(jsonNode, mapping, value -> { + private boolean updateResourcesUsage(TenantId tenantId, List jsonNodes, List> mappings, Map links) { + log.trace("[{}] updateResourcesUsage (new links: {}) for {}", tenantId, links, jsonNodes); + return processResources(jsonNodes, mappings, value -> { String link = getResourceLink(value); if (link != null) { String newLink = links.get(link); @@ -463,22 +475,30 @@ public class BaseResourceService extends AbstractCachedEntityService getUsedResources(Dashboard dashboard) { - return getUsedResources(dashboard.getTenantId(), dashboard.getConfiguration(), DASHBOARD_RESOURCES_MAPPING).values(); + return getUsedResources(dashboard.getTenantId(), List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING)).values(); } @Override public Collection getUsedResources(WidgetTypeDetails widgetTypeDetails) { - Map resources = getUsedResources(widgetTypeDetails.getTenantId(), widgetTypeDetails.getDescriptor(), WIDGET_RESOURCES_MAPPING); + List jsonNodes = new ArrayList<>(2); + List> mappings = new ArrayList<>(2); + + jsonNodes.add(widgetTypeDetails.getDescriptor()); + mappings.add(WIDGET_RESOURCES_MAPPING); + JsonNode defaultConfig = widgetTypeDetails.getDefaultConfig(); if (defaultConfig != null) { - resources.putAll(getUsedResources(widgetTypeDetails.getTenantId(), defaultConfig, WIDGET_DEFAULT_CONFIG_RESOURCES_MAPPING)); + jsonNodes.add(defaultConfig); + mappings.add(WIDGET_DEFAULT_CONFIG_RESOURCES_MAPPING); } - return resources.values(); + + return getUsedResources(widgetTypeDetails.getTenantId(), jsonNodes, mappings).values(); } - private Map getUsedResources(TenantId tenantId, JsonNode jsonNode, Map mapping) { + private Map getUsedResources(TenantId tenantId, List jsonNodes, List> mappings) { Map resources = new HashMap<>(); - processResources(jsonNode, mapping, value -> { + log.trace("[{}] getUsedResources for {}", tenantId, jsonNodes); + processResources(jsonNodes, mappings, value -> { String link = getResourceLink(value); if (link == null) { return value; @@ -517,32 +537,54 @@ public class BaseResourceService extends AbstractCachedEntityService mapping, UnaryOperator processor) { + private boolean processResources(List jsonNodes, List> mappings, UnaryOperator processor) { AtomicBoolean updated = new AtomicBoolean(false); - JacksonUtil.replaceByMapping(jsonNode, mapping, Collections.emptyMap(), (name, urlNode) -> { - String value = null; - if (urlNode.isTextual()) { // link is in the right place - value = urlNode.asText(); - } else { - JsonNode id = urlNode.get("id"); // old structure is used - if (id != null && id.isTextual()) { - value = id.asText(); + + for (int i = 0; i < jsonNodes.size(); i++) { + JsonNode jsonNode = jsonNodes.get(i); + // processing by mappings first + JacksonUtil.replaceByMapping(jsonNode, mappings.get(i), Collections.emptyMap(), (name, urlNode) -> { + String value = null; + if (urlNode.isTextual()) { // link is in the right place + value = urlNode.asText(); + } else { + JsonNode id = urlNode.get("id"); // old structure is used + if (id != null && id.isTextual()) { + value = id.asText(); + } } - } - if (StringUtils.isNotBlank(value)) { - value = processor.apply(value); - } else { - value = ""; - } + if (StringUtils.isNotBlank(value)) { + value = processor.apply(value); + } else { + value = ""; + } + + JsonNode newValue = new TextNode(value); + if (!newValue.toString().equals(urlNode.toString())) { + updated.set(true); + log.trace("Replaced by mapping '{}' ({}) with '{}'", value, name, newValue); + } + return newValue; + }); + + // processing all + JacksonUtil.replaceAll(jsonNode, "", (name, value) -> { + if (!StringUtils.startsWith(value, DataConstants.TB_RESOURCE_PREFIX + "/api/resource/")) { + return value; + } + + String newValue = processor.apply(value); + if (StringUtils.equals(value, newValue)) { + return value; + } else { + updated.set(true); + log.trace("Replaced '{}' ({}) with '{}'", value, name, newValue); + return newValue; + } + }); + } - JsonNode newValue = new TextNode(value); - if (!newValue.toString().equals(urlNode.toString())) { - updated.set(true); - log.trace("Replaced '{}' with '{}'", urlNode, newValue); - } - return newValue; - }); return updated.get(); } From f50789ebf3c2be362e788071f384302d2a1a84a4 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 3 Dec 2024 17:17:49 +0200 Subject: [PATCH 02/11] Minor refactoring for ResourceService --- .../install/update/ResourcesUpdater.java | 4 +- .../resource/DefaultTbResourceService.java | 15 +++-- .../server/dao/resource/ResourceService.java | 8 +-- .../dao/dashboard/DashboardServiceImpl.java | 11 ++-- .../dao/resource/BaseResourceService.java | 63 ++++++++++--------- .../dao/widget/WidgetTypeServiceImpl.java | 9 +-- 6 files changed, 57 insertions(+), 53 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/ResourcesUpdater.java b/application/src/main/java/org/thingsboard/server/service/install/update/ResourcesUpdater.java index 00797da449..da2b7276dd 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/ResourcesUpdater.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/ResourcesUpdater.java @@ -101,7 +101,7 @@ public class ResourcesUpdater { for (DashboardId dashboardId : dashboards) { executor.submit(() -> { Dashboard dashboard = dashboardService.findDashboardById(TenantId.SYS_TENANT_ID, dashboardId); - boolean updated = resourceService.updateResourcesUsage(dashboard); // will convert resources ids to new structure + boolean updated = resourceService.updateResourcesUsage(dashboard.getTenantId(), dashboard); // will convert resources ids to new structure if (updated) { dashboardService.saveDashboard(dashboard); updatedCount.incrementAndGet(); @@ -130,7 +130,7 @@ public class ResourcesUpdater { for (WidgetTypeId widgetTypeId : widgets) { executor.submit(() -> { WidgetTypeDetails widgetTypeDetails = widgetTypeService.findWidgetTypeDetailsById(TenantId.SYS_TENANT_ID, widgetTypeId); - boolean updated = resourceService.updateResourcesUsage(widgetTypeDetails); + boolean updated = resourceService.updateResourcesUsage(widgetTypeDetails.getTenantId(), widgetTypeDetails); if (updated) { widgetTypeService.saveWidgetType(widgetTypeDetails); updatedCount.incrementAndGet(); diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index 90ad3e38dd..e3a79a8ba5 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -46,7 +46,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; -import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -132,12 +132,12 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements @Override public List exportResources(Dashboard dashboard, SecurityUser user) throws ThingsboardException { - return exportResources(dashboard, imageService::getUsedImages, resourceService::getUsedResources, user); + return exportResources(() -> imageService.getUsedImages(dashboard), () -> resourceService.getUsedResources(user.getTenantId(), dashboard), user); } @Override public List exportResources(WidgetTypeDetails widgetTypeDetails, SecurityUser user) throws ThingsboardException { - return exportResources(widgetTypeDetails, imageService::getUsedImages, resourceService::getUsedResources, user); + return exportResources(() -> imageService.getUsedImages(widgetTypeDetails), () -> resourceService.getUsedResources(user.getTenantId(), widgetTypeDetails), user); } @Override @@ -153,13 +153,12 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements } } - private List exportResources(T entity, - Function> imagesProcessor, - Function> resourcesProcessor, + private List exportResources(Supplier> imagesProcessor, + Supplier> resourcesProcessor, SecurityUser user) throws ThingsboardException { List resources = new ArrayList<>(); - resources.addAll(imagesProcessor.apply(entity)); - resources.addAll(resourcesProcessor.apply(entity)); + resources.addAll(imagesProcessor.get()); + resources.addAll(resourcesProcessor.get()); for (TbResourceInfo resourceInfo : resources) { accessControlService.checkPermission(user, Resource.TB_RESOURCE, Operation.READ, resourceInfo.getId(), resourceInfo); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 0e2acb2e4e..f7f4b1ce4b 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -80,13 +80,13 @@ public interface ResourceService extends EntityDaoService { TbResourceInfo findSystemOrTenantResourceByEtag(TenantId tenantId, ResourceType resourceType, String etag); - boolean updateResourcesUsage(Dashboard dashboard); + boolean updateResourcesUsage(TenantId tenantId, Dashboard dashboard); - boolean updateResourcesUsage(WidgetTypeDetails widgetTypeDetails); + boolean updateResourcesUsage(TenantId tenantId, WidgetTypeDetails widgetTypeDetails); - Collection getUsedResources(Dashboard dashboard); + Collection getUsedResources(TenantId tenantId, Dashboard dashboard); - Collection getUsedResources(WidgetTypeDetails widgetTypeDetails); + Collection getUsedResources(TenantId tenantId, WidgetTypeDetails widgetTypeDetails); TbResource createOrUpdateSystemResource(ResourceType resourceType, String resourceKey, byte[] data); diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index b547de1eca..2e9e37577c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -162,18 +162,19 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb dashboardValidator.validate(dashboard, DashboardInfo::getTenantId); } try { + TenantId tenantId = dashboard.getTenantId(); if (CollectionUtils.isNotEmpty(dashboard.getResources())) { - resourceService.importResources(dashboard.getTenantId(), dashboard.getResources()); + resourceService.importResources(tenantId, dashboard.getResources()); } imageService.updateImagesUsage(dashboard); - resourceService.updateResourcesUsage(dashboard); + resourceService.updateResourcesUsage(tenantId, dashboard); - var saved = dashboardDao.save(dashboard.getTenantId(), dashboard); + var saved = dashboardDao.save(tenantId, dashboard); publishEvictEvent(new DashboardTitleEvictEvent(saved.getId())); - eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId()) + eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId) .entityId(saved.getId()).created(dashboard.getId() == null).build()); if (dashboard.getId() == null) { - countService.publishCountEntityEvictEvent(saved.getTenantId(), EntityType.DASHBOARD); + countService.publishCountEntityEvictEvent(tenantId, EntityType.DASHBOARD); } return saved; } catch (Exception e) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 7101922f6b..361d2b3894 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -402,13 +402,13 @@ public class BaseResourceService extends AbstractCachedEntityService links = getResourcesLinks(dashboard.getResources()); - return updateResourcesUsage(dashboard.getTenantId(), List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING), links); + return updateResourcesUsage(tenantId, List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING), links); } @Override - public boolean updateResourcesUsage(WidgetTypeDetails widgetTypeDetails) { + public boolean updateResourcesUsage(TenantId tenantId, WidgetTypeDetails widgetTypeDetails) { Map links = getResourcesLinks(widgetTypeDetails.getResources()); List jsonNodes = new ArrayList<>(2); List> mappings = new ArrayList<>(2); @@ -422,7 +422,7 @@ public class BaseResourceService extends AbstractCachedEntityService getUsedResources(Dashboard dashboard) { - return getUsedResources(dashboard.getTenantId(), List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING)).values(); + public Collection getUsedResources(TenantId tenantId, Dashboard dashboard) { + return getUsedResources(tenantId, List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING)).values(); } @Override - public Collection getUsedResources(WidgetTypeDetails widgetTypeDetails) { + public Collection getUsedResources(TenantId tenantId, WidgetTypeDetails widgetTypeDetails) { List jsonNodes = new ArrayList<>(2); List> mappings = new ArrayList<>(2); @@ -492,7 +492,7 @@ public class BaseResourceService extends AbstractCachedEntityService getUsedResources(TenantId tenantId, List jsonNodes, List> mappings) { @@ -543,30 +543,33 @@ public class BaseResourceService extends AbstractCachedEntityService { - String value = null; - if (urlNode.isTextual()) { // link is in the right place - value = urlNode.asText(); - } else { - JsonNode id = urlNode.get("id"); // old structure is used - if (id != null && id.isTextual()) { - value = id.asText(); + if (i <= mappings.size() - 1) { + JacksonUtil.replaceByMapping(jsonNode, mappings.get(i), Collections.emptyMap(), (name, urlNode) -> { + String value = null; + if (urlNode.isTextual()) { // link is in the right place + value = urlNode.asText(); + } else { + JsonNode id = urlNode.get("id"); // old structure is used + if (id != null && id.isTextual()) { + value = id.asText(); + } } - } - if (StringUtils.isNotBlank(value)) { - value = processor.apply(value); - } else { - value = ""; - } + if (StringUtils.isNotBlank(value)) { + value = processor.apply(value); + } else { + value = ""; + } + + JsonNode newValue = new TextNode(value); + if (!newValue.toString().equals(urlNode.toString())) { + updated.set(true); + log.trace("Replaced by mapping '{}' ({}) with '{}'", value, name, newValue); + } + return newValue; + }); + } - JsonNode newValue = new TextNode(value); - if (!newValue.toString().equals(urlNode.toString())) { - updated.set(true); - log.trace("Replaced by mapping '{}' ({}) with '{}'", value, name, newValue); - } - return newValue; - }); // processing all JacksonUtil.replaceAll(jsonNode, "", (name, value) -> { @@ -597,7 +600,7 @@ public class BaseResourceService extends AbstractCachedEntityService Date: Wed, 4 Dec 2024 10:08:41 +0200 Subject: [PATCH 03/11] UI: Fixed disable event on edit mode --- .../widget/lib/button/two-segment-button-widget.component.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/two-segment-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/button/two-segment-button-widget.component.html index 10cf016e11..1aac07bd4a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/button/two-segment-button-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/two-segment-button-widget.component.html @@ -15,7 +15,7 @@ limitations under the License. --> -
+
From 18eab054a437462bc55d51daca2a679c0e934048 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 4 Dec 2024 11:35:35 +0200 Subject: [PATCH 04/11] tbel: ver 1.2.5 add bitwise operation for boolean to MathProcessor --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a1d5f26ecf..05f16ca5b1 100755 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.9.2 3.25.3 1.63.0 - 1.2.4 + 1.2.5 1.18.32 1.2.5 1.2.5 From fde6756bcad4dd0a302491b2ca3a05a926eca2cb Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 4 Dec 2024 13:13:45 +0200 Subject: [PATCH 05/11] UI: Added to JavaScript library details audit logs and version control --- .../vc/entity-version-create.component.html | 4 +-- .../vc/entity-version-create.component.ts | 9 +++-- .../modules/home/pages/admin/admin.module.ts | 2 ++ .../js-library-table-config.resolver.ts | 2 ++ .../resource/resource-tabs.component.html | 27 ++++++++++++++ .../admin/resource/resource-tabs.component.ts | 36 +++++++++++++++++++ ui-ngx/src/app/shared/models/vc.models.ts | 12 +++---- 7 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.html create mode 100644 ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.ts diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html index 67ef5908e5..ab127e45cd 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.html @@ -41,10 +41,10 @@ {{ 'version-control.export-credentials' | translate }} - + {{ 'version-control.export-attributes' | translate }} - + {{ 'version-control.export-relations' | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts index 26d45de2c0..7d3e89eda8 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-create.component.ts @@ -18,6 +18,7 @@ import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular import { PageComponent } from '@shared/components/page.component'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { + entityTypesWithoutRelatedData, SingleEntityVersionCreateRequest, VersionCreateRequestType, VersionCreationResult @@ -62,6 +63,8 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni entityTypes = EntityType; + entityTypesWithoutRelatedData = entityTypesWithoutRelatedData; + resultMessage: string; versionCreateResult$: Observable; @@ -108,8 +111,10 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni branch: this.createVersionFormGroup.get('branch').value, versionName: this.createVersionFormGroup.get('versionName').value, config: { - saveRelations: this.createVersionFormGroup.get('saveRelations').value, - saveAttributes: this.createVersionFormGroup.get('saveAttributes').value, + saveRelations: !entityTypesWithoutRelatedData.has(this.entityId.entityType) + ? this.createVersionFormGroup.get('saveRelations').value : false, + saveAttributes: !entityTypesWithoutRelatedData.has(this.entityId.entityType) + ? this.createVersionFormGroup.get('saveAttributes').value : false, saveCredentials: this.entityId.entityType === EntityType.DEVICE ? this.createVersionFormGroup.get('saveCredentials').value : false }, type: VersionCreateRequestType.SINGLE_ENTITY diff --git a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts index 704f909809..784aade083 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts @@ -27,6 +27,7 @@ import { SmsProviderComponent } from '@home/pages/admin/sms-provider.component'; import { SendTestSmsDialogComponent } from '@home/pages/admin/send-test-sms-dialog.component'; import { HomeSettingsComponent } from '@home/pages/admin/home-settings.component'; import { ResourcesLibraryComponent } from '@home/pages/admin/resource/resources-library.component'; +import { ResourceTabsComponent } from '@home/pages/admin/resource/resource-tabs.component'; import { ResourcesTableHeaderComponent } from '@home/pages/admin/resource/resources-table-header.component'; import { QueueComponent } from '@home/pages/admin/queue/queue.component'; import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component'; @@ -47,6 +48,7 @@ import { NgxFlowModule } from '@flowjs/ngx-flow'; SecuritySettingsComponent, HomeSettingsComponent, ResourcesLibraryComponent, + ResourceTabsComponent, ResourcesTableHeaderComponent, JsResourceComponent, JsLibraryTableHeaderComponent, diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/js-library-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/js-library-table-config.resolver.ts index b0fadd53d9..862adf48d5 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/resource/js-library-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/js-library-table-config.resolver.ts @@ -43,6 +43,7 @@ import { EntityAction } from '@home/models/entity/entity-component.models'; import { JsLibraryTableHeaderComponent } from '@home/pages/admin/resource/js-library-table-header.component'; import { JsResourceComponent } from '@home/pages/admin/resource/js-resource.component'; import { switchMap } from 'rxjs/operators'; +import { ResourceTabsComponent } from '@home/pages/admin/resource/resource-tabs.component'; @Injectable() export class JsLibraryTableConfigResolver { @@ -57,6 +58,7 @@ export class JsLibraryTableConfigResolver { this.config.entityType = EntityType.TB_RESOURCE; this.config.entityComponent = JsResourceComponent; + this.config.entityTabsComponent = ResourceTabsComponent; this.config.entityTranslations = { details: 'javascript.javascript-resource-details', add: 'javascript.add', diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.html b/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.html new file mode 100644 index 0000000000..fb608683d8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.html @@ -0,0 +1,27 @@ + + + + + + + diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.ts new file mode 100644 index 0000000000..2cd2f43d62 --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resource-tabs.component.ts @@ -0,0 +1,36 @@ +/// +/// Copyright © 2016-2024 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { EntityTabsComponent } from '@home/components/entity/entity-tabs.component'; +import { Resource } from '@shared/models/resource.models'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { NULL_UUID } from '@shared/models/id/has-uuid'; + +@Component({ + selector: 'tb-resource-tabs', + templateUrl: './resource-tabs.component.html', + styleUrls: [] +}) +export class ResourceTabsComponent extends EntityTabsComponent { + + readonly NULL_UUID = NULL_UUID; + + constructor(protected store: Store) { + super(store); + } +} diff --git a/ui-ngx/src/app/shared/models/vc.models.ts b/ui-ngx/src/app/shared/models/vc.models.ts index ba54a297a7..15d41656df 100644 --- a/ui-ngx/src/app/shared/models/vc.models.ts +++ b/ui-ngx/src/app/shared/models/vc.models.ts @@ -15,7 +15,7 @@ /// import { EntityId } from '@shared/models/id/entity-id'; -import { EntityType } from '@shared/models/entity-type.models'; +import { AliasEntityType, EntityType } from '@shared/models/entity-type.models'; import { ExportableEntity } from '@shared/models/base-data'; import { EntityRelation } from '@shared/models/relation.models'; import { Device, DeviceCredentials } from '@shared/models/device.models'; @@ -38,7 +38,7 @@ export const exportableEntityTypes: Array = [ EntityType.NOTIFICATION_RULE ]; -export const entityTypesWithoutRelatedData: Set = new Set([ +export const entityTypesWithoutRelatedData: Set = new Set([ EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_RULE, @@ -104,8 +104,8 @@ export function createDefaultEntityTypesVersionCreate(): {[entityType: string]: for (const entityType of exportableEntityTypes) { res[entityType] = { syncStrategy: null, - saveAttributes: true, - saveRelations: true, + saveAttributes: !entityTypesWithoutRelatedData.has(entityType), + saveRelations: !entityTypesWithoutRelatedData.has(entityType), saveCredentials: true, allEntities: true, entityIds: [] @@ -151,8 +151,8 @@ export function createDefaultEntityTypesVersionLoad(): {[entityType: string]: En const res: {[entityType: string]: EntityTypeVersionLoadConfig} = {}; for (const entityType of exportableEntityTypes) { res[entityType] = { - loadAttributes: true, - loadRelations: true, + loadAttributes: !entityTypesWithoutRelatedData.has(entityType), + loadRelations: !entityTypesWithoutRelatedData.has(entityType), loadCredentials: true, removeOtherEntities: false, findExistingEntityByName: true From 749df3f212e3da715a82feb81728a548c92dcd0e Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 4 Dec 2024 15:19:42 +0200 Subject: [PATCH 06/11] Add gzip compression for load dashboard and download svg images methods. --- .../server/controller/BaseController.java | 21 ++++++++++ .../controller/DashboardController.java | 36 +++++++++++------ .../server/controller/ImageController.java | 39 +++++++++++++------ 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 8470566af3..2d868a1135 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; import jakarta.mail.MessagingException; +import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.ConstraintViolation; import lombok.Getter; @@ -28,6 +29,7 @@ import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -182,7 +184,9 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; +import java.io.IOException; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -194,6 +198,7 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.zip.GZIPOutputStream; import static org.thingsboard.server.common.data.StringUtils.isNotEmpty; import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; @@ -1008,6 +1013,22 @@ public abstract class BaseController { } } + protected void compressResponseWithGzipIFAccepted(String acceptEncodingHeader, HttpServletResponse response, byte[] content) throws IOException { + if (StringUtils.isNotEmpty(acceptEncodingHeader) && acceptEncodingHeader.contains("gzip")) { + response.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip"); + response.setCharacterEncoding(StandardCharsets.UTF_8.displayName()); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(response.getOutputStream())) { + gzipOutputStream.write(content); + gzipOutputStream.finish(); + } + } else { + try (ServletOutputStream outputStream = response.getOutputStream()) { + outputStream.write(content); + outputStream.flush(); + } + } + } + protected ResponseEntity response(HttpStatus status) { return ResponseEntity.status(status).build(); } 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 e3e793014d..e50484bed3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -22,8 +22,10 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; @@ -31,6 +33,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -67,6 +70,7 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION; @@ -149,17 +153,20 @@ public class DashboardController extends BaseController { ) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @GetMapping(value = "/dashboard/{dashboardId}") - public Dashboard getDashboardById(@Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) + public void getDashboardById(@Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, @Parameter(description = INCLUDE_RESOURCES_DESCRIPTION) - @RequestParam(value = INCLUDE_RESOURCES, required = false) boolean includeResources) throws ThingsboardException { + @RequestParam(value = INCLUDE_RESOURCES, required = false) boolean includeResources, + @RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader, + HttpServletResponse response) throws Exception { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ); if (includeResources) { dashboard.setResources(tbResourceService.exportResources(dashboard, getCurrentUser())); } - return dashboard; + response.setContentType(APPLICATION_JSON_VALUE); + compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(dashboard)); } @ApiOperation(value = "Create Or Update Dashboard (saveDashboard)", @@ -171,11 +178,15 @@ public class DashboardController extends BaseController { TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @PostMapping(value = "/dashboard") - public Dashboard saveDashboard(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A JSON value representing the dashboard.") - @RequestBody Dashboard dashboard) throws Exception { + public void saveDashboard(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A JSON value representing the dashboard.") + @RequestBody Dashboard dashboard, + @RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader, + HttpServletResponse response) throws Exception { dashboard.setTenantId(getTenantId()); checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); - return tbDashboardService.save(dashboard, getCurrentUser()); + var savedDashboard = tbDashboardService.save(dashboard, getCurrentUser()); + response.setContentType(APPLICATION_JSON_VALUE); + compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(savedDashboard)); } @ApiOperation(value = "Delete the Dashboard (deleteDashboard)", @@ -408,12 +419,13 @@ public class DashboardController extends BaseController { "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " + DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET) - @ResponseBody - public HomeDashboard getHomeDashboard() throws ThingsboardException { + @GetMapping(value = "/dashboard/home") + public void getHomeDashboard(@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader, + HttpServletResponse response) throws Exception { SecurityUser securityUser = getCurrentUser(); + response.setContentType(APPLICATION_JSON_VALUE); if (securityUser.isSystemAdmin()) { - return null; + return; } User user = userService.findUserById(securityUser.getTenantId(), securityUser.getId()); JsonNode additionalInfo = user.getAdditionalInfo(); @@ -431,7 +443,9 @@ public class DashboardController extends BaseController { homeDashboard = extractHomeDashboardFromAdditionalInfo(additionalInfo); } } - return homeDashboard; + if (homeDashboard != null) { + compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(homeDashboard)); + } } @ApiOperation(value = "Get Home Dashboard Info (getHomeDashboardInfo)", diff --git a/application/src/main/java/org/thingsboard/server/controller/ImageController.java b/application/src/main/java/org/thingsboard/server/controller/ImageController.java index cd1116a420..5a7bd19d8e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ImageController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ImageController.java @@ -61,7 +61,9 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; +import java.io.ByteArrayOutputStream; import java.util.concurrent.TimeUnit; +import java.util.zip.GZIPOutputStream; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; @@ -70,6 +72,7 @@ import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INC import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION; 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.dao.util.ImageUtils.mediaTypeToFileExtension; @Slf4j @RestController @@ -179,15 +182,17 @@ public class ImageController extends BaseController { @PathVariable String type, @Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true) @PathVariable String key, - @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception { - return downloadIfChanged(type, key, etag, false); + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag, + @RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception { + return downloadIfChanged(type, key, etag, acceptEncodingHeader, false); } @GetMapping(value = "/api/images/public/{publicResourceKey}", produces = "image/*") public ResponseEntity downloadPublicImage(@PathVariable String publicResourceKey, - @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception { + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag, + @RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception { ImageCacheKey cacheKey = ImageCacheKey.forPublicImage(publicResourceKey); - return downloadIfChanged(cacheKey, etag, () -> imageService.getPublicImageInfoByKey(publicResourceKey)); + return downloadIfChanged(cacheKey, etag, acceptEncodingHeader, () -> imageService.getPublicImageInfoByKey(publicResourceKey)); } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @@ -213,8 +218,9 @@ public class ImageController extends BaseController { @PathVariable String type, @Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true) @PathVariable String key, - @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception { - return downloadIfChanged(type, key, etag, true); + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag, + @RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception { + return downloadIfChanged(type, key, etag, acceptEncodingHeader, true); } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @@ -268,12 +274,12 @@ public class ImageController extends BaseController { return (result.isSuccess() ? ResponseEntity.ok() : ResponseEntity.badRequest()).body(result); } - private ResponseEntity downloadIfChanged(String type, String key, String etag, boolean preview) throws Exception { + private ResponseEntity downloadIfChanged(String type, String key, String etag, String acceptEncodingHeader, boolean preview) throws Exception { ImageCacheKey cacheKey = ImageCacheKey.forImage(getTenantId(type), key, preview); - return downloadIfChanged(cacheKey, etag, () -> checkImageInfo(type, key, Operation.READ)); + return downloadIfChanged(cacheKey, etag, acceptEncodingHeader, () -> checkImageInfo(type, key, Operation.READ)); } - private ResponseEntity downloadIfChanged(ImageCacheKey cacheKey, String etag, ThrowingSupplier imageInfoSupplier) throws Exception { + private ResponseEntity downloadIfChanged(ImageCacheKey cacheKey, String etag, String acceptEncodingHeader, ThrowingSupplier imageInfoSupplier) throws Exception { if (StringUtils.isNotEmpty(etag)) { etag = StringUtils.remove(etag, '\"'); // etag is wrapped in double quotes due to HTTP specification if (etag.equals(tbImageService.getETag(cacheKey))) { @@ -294,7 +300,6 @@ public class ImageController extends BaseController { tbImageService.putETag(cacheKey, descriptor.getEtag()); var result = ResponseEntity.ok() .header("Content-Type", descriptor.getMediaType()) - .contentLength(data.length) .eTag(descriptor.getEtag()); if (!cacheKey.isPublic()) { result @@ -308,7 +313,19 @@ public class ImageController extends BaseController { } else { result.cacheControl(CacheControl.noCache()); } - return result.body(new ByteArrayResource(data)); + var responseData = data; + if (mediaTypeToFileExtension(descriptor.getMediaType()).equals("svg") && + StringUtils.isNotEmpty(acceptEncodingHeader) && acceptEncodingHeader.contains("gzip")) { + result.header(HttpHeaders.CONTENT_ENCODING, "gzip"); + var outputStream = new ByteArrayOutputStream(); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream)) { + gzipOutputStream.write(data); + gzipOutputStream.finish(); + } + responseData = outputStream.toByteArray(); + } + result.contentLength(responseData.length); + return result.body(new ByteArrayResource(responseData)); } private TbResourceInfo checkImageInfo(String imageType, String key, Operation operation) throws ThingsboardException { From cca4ac362950cb34a9360dc112076fe2ee3be0d0 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 4 Dec 2024 16:44:31 +0200 Subject: [PATCH 07/11] Version set to 3.9.0-RC --- application/pom.xml | 2 +- common/actor/pom.xml | 2 +- common/cache/pom.xml | 2 +- common/cluster-api/pom.xml | 2 +- common/coap-server/pom.xml | 2 +- common/dao-api/pom.xml | 2 +- common/data/pom.xml | 2 +- common/edge-api/pom.xml | 2 +- common/message/pom.xml | 2 +- common/pom.xml | 2 +- common/proto/pom.xml | 2 +- common/queue/pom.xml | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- common/script/script-api/pom.xml | 2 +- common/stats/pom.xml | 2 +- common/transport/coap/pom.xml | 2 +- common/transport/http/pom.xml | 2 +- common/transport/lwm2m/pom.xml | 2 +- common/transport/mqtt/pom.xml | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- common/transport/transport-api/pom.xml | 2 +- common/util/pom.xml | 2 +- common/version-control/pom.xml | 2 +- dao/pom.xml | 2 +- monitoring/pom.xml | 2 +- msa/black-box-tests/pom.xml | 2 +- msa/js-executor/pom.xml | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/web-ui/pom.xml | 2 +- netty-mqtt/pom.xml | 4 ++-- pom.xml | 2 +- rest-client/pom.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- tools/pom.xml | 2 +- transport/coap/pom.xml | 2 +- transport/http/pom.xml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/mqtt/pom.xml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 56 files changed, 57 insertions(+), 57 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index 17b179c767..ef57037448 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard application diff --git a/common/actor/pom.xml b/common/actor/pom.xml index cc19cc949f..cbbce12336 100644 --- a/common/actor/pom.xml +++ b/common/actor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index 1ecb95c6c5..a4f7dd4f7b 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index bd7dc214cf..4bbe65d99f 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index 401d1e94fd..32da47ca08 100644 --- a/common/coap-server/pom.xml +++ b/common/coap-server/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 62c1e420c2..7d48a63903 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index b206f0b173..e6eca1aa93 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index 31d90de948..68e647642d 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index ac56095e7e..0614c94bc4 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index c905e0eee9..8bd1904d72 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard common diff --git a/common/proto/pom.xml b/common/proto/pom.xml index 4409d6b97f..fded7298e4 100644 --- a/common/proto/pom.xml +++ b/common/proto/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index 7485294f6e..fab4ff3989 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/script/pom.xml b/common/script/pom.xml index 88e35e8429..1aad1dd39e 100644 --- a/common/script/pom.xml +++ b/common/script/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/script/remote-js-client/pom.xml b/common/script/remote-js-client/pom.xml index 7309e6af51..38a14cd8f3 100644 --- a/common/script/remote-js-client/pom.xml +++ b/common/script/remote-js-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC script org.thingsboard.common.script diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 08ef60713e..4210f1f528 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC script org.thingsboard.common.script diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 31fbc72dcc..231811144a 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index d4528944e0..0bd4c0d6e3 100644 --- a/common/transport/coap/pom.xml +++ b/common/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.common.transport diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml index 054fc3cbbe..5a0dd9e4ff 100644 --- a/common/transport/http/pom.xml +++ b/common/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.common.transport diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index 54232ac104..ddb9d7a399 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.common.transport diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index e672f7a5dd..45d228f225 100644 --- a/common/transport/mqtt/pom.xml +++ b/common/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.common.transport diff --git a/common/transport/pom.xml b/common/transport/pom.xml index c87fa8c2bf..6c4310151d 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 78665bfde2..a2b9dd7c84 100644 --- a/common/transport/snmp/pom.xml +++ b/common/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index 7d221c48bf..8f01cab08b 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.common.transport diff --git a/common/util/pom.xml b/common/util/pom.xml index ad3bbaba58..194724b70f 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index f37139b3c5..8e3fceff99 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index 1dac54c142..c1f5a1f62b 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard dao diff --git a/monitoring/pom.xml b/monitoring/pom.xml index 013a0b5c47..e19acb0fe6 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index 4d34a13f38..5563fcc8d8 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index f747db1438..daea52bfa5 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index 3a4834236c..20f8d90695 100644 --- a/msa/monitoring/pom.xml +++ b/msa/monitoring/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa diff --git a/msa/pom.xml b/msa/pom.xml index d77384cc74..057f37a575 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index 11295dc4b9..3ca22bcf55 100644 --- a/msa/tb-node/pom.xml +++ b/msa/tb-node/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index 79a2a66385..3789fe14a1 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 9ec8589d9a..089581f1cb 100644 --- a/msa/transport/coap/pom.xml +++ b/msa/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.msa.transport diff --git a/msa/transport/http/pom.xml b/msa/transport/http/pom.xml index d562f89cd5..4d9e17df5f 100644 --- a/msa/transport/http/pom.xml +++ b/msa/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.msa.transport diff --git a/msa/transport/lwm2m/pom.xml b/msa/transport/lwm2m/pom.xml index 992187316a..94b86d035f 100644 --- a/msa/transport/lwm2m/pom.xml +++ b/msa/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.msa.transport diff --git a/msa/transport/mqtt/pom.xml b/msa/transport/mqtt/pom.xml index 32aa6a4f23..2b637ddd19 100644 --- a/msa/transport/mqtt/pom.xml +++ b/msa/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index 34be0bd338..4f7e0ad030 100644 --- a/msa/transport/pom.xml +++ b/msa/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index 95919ad175..94bc03f29d 100644 --- a/msa/transport/snmp/pom.xml +++ b/msa/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.msa transport - 3.9.0-SNAPSHOT + 3.9.0-RC org.thingsboard.msa.transport diff --git a/msa/vc-executor-docker/pom.xml b/msa/vc-executor-docker/pom.xml index 8aeeed2b1e..f6dc43ea13 100644 --- a/msa/vc-executor-docker/pom.xml +++ b/msa/vc-executor-docker/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 0932bf7c06..725c3e40ad 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index 195ae123f4..c5a900e004 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC msa org.thingsboard.msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 7de766b2da..d4cd55629d 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,11 +19,11 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard netty-mqtt - 3.9.0-SNAPSHOT + 3.9.0-RC jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 8dc3e1c40a..094c48fd5d 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC pom Thingsboard diff --git a/rest-client/pom.xml b/rest-client/pom.xml index 069f7b84f0..f868acabf5 100644 --- a/rest-client/pom.xml +++ b/rest-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index e6abae70ef..fbefcd1de9 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index 57bc5771d2..3ee6496452 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 99853b0950..33bb15af00 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC rule-engine org.thingsboard.rule-engine diff --git a/tools/pom.xml b/tools/pom.xml index 2d196cec7d..dce8e1606d 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard tools diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 76655178ae..eef23eae9b 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 7e569ea1f1..d841c56da7 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.transport diff --git a/transport/lwm2m/pom.xml b/transport/lwm2m/pom.xml index b5b7867146..cec30fcbc5 100644 --- a/transport/lwm2m/pom.xml +++ b/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 88009474aa..edf3727320 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index 8e7f77be9b..d744f7eb2f 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index 02fe36f657..dcd08c10af 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC transport diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index f16e352d71..1384b1c3e6 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.9.0-SNAPSHOT + 3.9.0-RC thingsboard org.thingsboard From 9fc597a5a4d933da7728a21a8d49cf893c93bc37 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 4 Dec 2024 18:22:00 +0200 Subject: [PATCH 08/11] fixed oauth2 client fetch by for mobile apps --- .../dao/oauth2/OAuth2ClientServiceImpl.java | 2 +- .../dao/sql/oauth2/JpaOAuth2ClientDao.java | 14 ++++++++++++-- .../dao/sql/oauth2/OAuth2ClientRepository.java | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java index 683c323ab5..452bd7ccf7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientServiceImpl.java @@ -64,7 +64,7 @@ public class OAuth2ClientServiceImpl extends AbstractEntityService implements OA @Override public List findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType(String pkgName, PlatformType platformType) { - log.trace("Executing findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType pkgName=[{}] platformType=[{}]",pkgName, platformType); + log.trace("Executing findOAuth2ClientLoginInfosByMobilePkgNameAndPlatformType pkgName=[{}] platformType=[{}]", pkgName, platformType); return oauth2ClientDao.findEnabledByPkgNameAndPlatformType(pkgName, platformType) .stream() .map(OAuth2Utils::toClientLoginInfo) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/JpaOAuth2ClientDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/JpaOAuth2ClientDao.java index 4310e0b705..31464cbe9a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/JpaOAuth2ClientDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/JpaOAuth2ClientDao.java @@ -31,6 +31,7 @@ import org.thingsboard.server.dao.oauth2.OAuth2ClientDao; import org.thingsboard.server.dao.sql.JpaAbstractDao; import org.thingsboard.server.dao.util.SqlDao; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -65,8 +66,17 @@ public class JpaOAuth2ClientDao extends JpaAbstractDao findEnabledByPkgNameAndPlatformType(String pkgName, PlatformType platformType) { - return DaoUtil.convertDataList(repository.findEnabledByPkgNameAndPlatformType(pkgName, - platformType != null ? platformType.name() : null)); + List clientEntities; + if (platformType != null) { + clientEntities = switch (platformType) { + case ANDROID -> repository.findEnabledByAndroidPkgNameAndPlatformType(pkgName, platformType.name()); + case IOS -> repository.findEnabledByIosPkgNameAndPlatformType(pkgName, platformType.name()); + default -> Collections.emptyList(); + }; + } else { + clientEntities = Collections.emptyList(); + } + return DaoUtil.convertDataList(clientEntities); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/OAuth2ClientRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/OAuth2ClientRepository.java index f7fe5bce3a..2a5526c146 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/OAuth2ClientRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/oauth2/OAuth2ClientRepository.java @@ -49,11 +49,21 @@ public interface OAuth2ClientRepository extends JpaRepository findEnabledByPkgNameAndPlatformType(@Param("pkgName") String pkgName, - @Param("platformFilter") String platformFilter); + List findEnabledByAndroidPkgNameAndPlatformType(@Param("pkgName") String pkgName, + @Param("platformFilter") String platformFilter); + + @Query("SELECT c " + + "FROM OAuth2ClientEntity c " + + "LEFT JOIN MobileAppBundleOauth2ClientEntity ac ON c.id = ac.oauth2ClientId " + + "LEFT JOIN MobileAppBundleEntity b ON ac.mobileAppBundleId = b.id " + + "LEFT JOIN MobileAppEntity iosApp ON b.iosAppID = iosApp.id " + + "WHERE iosApp.pkgName = :pkgName AND b.oauth2Enabled = true " + + "AND (:platformFilter IS NULL OR c.platforms IS NULL OR c.platforms = '' OR ilike(c.platforms, CONCAT('%', :platformFilter, '%')) = true)") + List findEnabledByIosPkgNameAndPlatformType(@Param("pkgName") String pkgName, + @Param("platformFilter") String platformFilter); @Query("SELECT c " + "FROM OAuth2ClientEntity c " + From b2c934a4a44f450573a4f83b1a4d5e64a60a239a Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 5 Dec 2024 10:57:29 +0200 Subject: [PATCH 09/11] Fixed ordering for available notification delivery methods --- .../thingsboard/server/controller/NotificationController.java | 2 +- .../service/notification/DefaultNotificationCenter.java | 4 ++-- .../org/thingsboard/rule/engine/api/NotificationCenter.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java index e055c6d6ae..72c339c635 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java @@ -477,7 +477,7 @@ public class NotificationController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/notification/deliveryMethods") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - public Set getAvailableDeliveryMethods(@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + public List getAvailableDeliveryMethods(@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { return notificationCenter.getAvailableDeliveryMethods(user.getTenantId()); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index 311fe6cb2c..af63256f0f 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -417,7 +417,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple } @Override - public Set getAvailableDeliveryMethods(TenantId tenantId) { + public List getAvailableDeliveryMethods(TenantId tenantId) { return channels.values().stream() .filter(channel -> { try { @@ -428,7 +428,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple } }) .map(NotificationChannel::getDeliveryMethod) - .collect(Collectors.toSet()); + .sorted().toList(); } @Override diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NotificationCenter.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NotificationCenter.java index 02ee53f3ad..b8fb9b61ff 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NotificationCenter.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NotificationCenter.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; -import java.util.Set; +import java.util.List; public interface NotificationCenter { @@ -48,6 +48,6 @@ public interface NotificationCenter { void deleteNotification(TenantId tenantId, UserId recipientId, NotificationId notificationId); - Set getAvailableDeliveryMethods(TenantId tenantId); + List getAvailableDeliveryMethods(TenantId tenantId); } From a2ae5b06c01ad9638c01690c3d3e0fc1c38db48d Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 5 Dec 2024 12:44:50 +0200 Subject: [PATCH 10/11] Non-null check for updateResourcesUsage --- .../server/common/data/widget/WidgetType.java | 3 ++- .../server/dao/resource/BaseResourceService.java | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) 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 d025aab3d5..fed271cbbe 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 @@ -50,7 +50,8 @@ public class WidgetType extends BaseWidgetType { @JsonIgnore public JsonNode getDefaultConfig() { - return Optional.ofNullable(descriptor.get("defaultConfig")) + return Optional.ofNullable(descriptor) + .map(descriptor -> descriptor.get("defaultConfig")) .filter(JsonNode::isTextual).map(JsonNode::asText) .map(json -> { try { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 361d2b3894..9395aae6c7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -403,6 +403,9 @@ public class BaseResourceService extends AbstractCachedEntityService links = getResourcesLinks(dashboard.getResources()); return updateResourcesUsage(tenantId, List.of(dashboard.getConfiguration()), List.of(DASHBOARD_RESOURCES_MAPPING), links); } @@ -413,8 +416,10 @@ public class BaseResourceService extends AbstractCachedEntityService jsonNodes = new ArrayList<>(2); List> mappings = new ArrayList<>(2); - jsonNodes.add(widgetTypeDetails.getDescriptor()); - mappings.add(WIDGET_RESOURCES_MAPPING); + if (widgetTypeDetails.getDescriptor() != null) { + jsonNodes.add(widgetTypeDetails.getDescriptor()); + mappings.add(WIDGET_RESOURCES_MAPPING); + } JsonNode defaultConfig = widgetTypeDetails.getDefaultConfig(); if (defaultConfig != null) { From 617381ffc76b12304eb7a4e818f3abedf08c16d0 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 6 Dec 2024 13:05:53 +0200 Subject: [PATCH 11/11] UI: Fix Json Form conditions. --- .../components/json-form/react/json-form-schema-form.tsx | 6 +++--- .../shared/components/json-form/react/json-form.models.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx b/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx index 5ce35ae96f..bbdd90cbe7 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form-schema-form.tsx @@ -131,10 +131,10 @@ class ThingsboardSchemaForm extends React.Component { } if (form.condition) { this.hasConditions = true; - if (!this.conditionFunction) { - this.conditionFunction = new Function('form', 'model', 'index', `return ${form.condition};`); + if (!form.conditionFunction) { + form.conditionFunction = new Function('form', 'model', 'index', `return ${form.condition};`); } - if (this.conditionFunction(form, model, index) === false) { + if (form.conditionFunction(form, model, index) === false) { return null; } } diff --git a/ui-ngx/src/app/shared/components/json-form/react/json-form.models.ts b/ui-ngx/src/app/shared/components/json-form/react/json-form.models.ts index edba015521..ffcf201136 100644 --- a/ui-ngx/src/app/shared/components/json-form/react/json-form.models.ts +++ b/ui-ngx/src/app/shared/components/json-form/react/json-form.models.ts @@ -87,6 +87,7 @@ export interface JsonFormData { required: boolean; default?: any; condition?: string; + conditionFunction?: Function; style?: any; rows?: number; rowsMax?: number;